1. ARN 是什么ARN 是 AWS 给每个资源起的完整名字。资源自己的名字可能和别人的重复ARN 不会重复。原因是 ARN 除了资源名还写明了这个资源属于哪个服务、哪个 Region、哪个账户。2. ARN 由六段组成各段之间用冒号隔开。例如arn:aws:lambda:ap-northeast-1:123456789012:function:order-api从左到右arn开头固定写 arn。aws分区。标准 AWS 写aws中国区写aws-cn。不同分区完全分开账户和权限都不互通。lambda哪个服务。ap-northeast-1哪个 Region这里是东京。123456789012哪个账户固定 12 位数字。function:order-api资源本身这里是名叫 order-api 的函数。3. 有些段是空的不是每个 ARN 都六段写满。IAM 角色不属于任何 Region所以 Region 那一段空着arn:aws:iam::123456789012:role/app-roleS3 bucket 的名字在全 AWS 都不能重复只靠名字就能确定是哪个 bucket所以 Region 和账户两段都空着arn:aws:s3:::my-bucket段是空的冒号也照样保留所以会出现两个或三个冒号连在一起。4. 最后一段每个服务写法不同AWS 没有统一规定最后一段怎么写Lambda 用冒号function:order-apiEC2 用斜杠instance/i-0abc123SNS 只写名字不写类型order-events这会带来一个具体问题。最后一段里也可能出现冒号比如带版本号的 Lambdafunction:order-api:7。程序拆 ARN 时只能按前五个冒号拆剩下的部分整个算作最后一段。按所有冒号拆最后一段就会被拆碎。5. ARN 最常用在权限里IAM 权限规则写的是谁可以对哪个资源做什么操作。“哪个资源”就用 ARN 来写。例如“允许读取 my-bucket 里的所有文件”操作s3:GetObject 资源arn:aws:s3:::my-bucket/**表示任意内容my-bucket/*就是 my-bucket 里的所有文件。6. 容易出错的五个地方第一写死了aws。模板里直接写arn:aws:...到中国区就不能用因为中国区要求写arn:aws-cn:...。第二S3 的 bucket 和文件是两种 ARN。列出 bucket 里有哪些文件资源要写 bucket 本身arn:aws:s3:::my-bucket读写某个文件资源要写到文件arn:aws:s3:::my-bucket/*只写其中一种另一类操作就会被拒绝。第三Lambda 带版本和不带版本是两个 ARN。function:order-api和function:order-api:prod在权限里是两个不同的字符串。只给了前一个的权限用后一个调用会被拒绝所以两个都要写。第四角色被使用时显示的 ARN 会变。角色本身的 ARN 是arn:aws:iam::123456789012:role/service-role/app-role程序用这个角色干活时日志里记录的身份是arn:aws:sts::123456789012:assumed-role/app-role/会话名服务从 iam 变成了 sts中间的service-role/也没有了。拿这两个字符串直接比较会判断成不相等。第五删掉再建同名资源ARN 不变。大多数资源的 ARN 由名字组成所以删掉后再用同名建一个ARN 一模一样原来写给旧资源的权限会自动用到新资源上。S3 风险最大因为 bucket 的 ARN 里没有账户你删掉一个 bucket 后别的账户可以建同名 bucket你的程序可能就把数据写进了别人的 bucket。IAM 角色是例外。删掉再同名重建后原来信任它的规则不会自动信任新角色需要重新保存这些规则。7. 实际该怎么做不要在模板和代码里写死分区、Region 和账户用工具提供的变量自动填入。需要某个资源的 ARN 时优先用 AWS 创建资源后返回的那个不要自己拼。程序里要拆 ARN用 AWS SDK 自带的方法。不确定某个服务的 ARN 怎么写查 AWS 官方的 Service Authorization Reference每个服务的格式都列在那里。