IAM用户无法创建/管理同名EC2实例的策略问题排查
问题分析与修复方案
原策略的核心问题
- 创建实例的条件逻辑错误:执行
RunInstances时实例还未生成,aws:ResourceTag/Name是针对已存在资源的标签校验,此时根本无法匹配。必须用aws:RequestTag/Name检查用户发起请求时指定的标签值,同时要强制用户必须在创建时带这个标签。 - 资源范围与条件不兼容:原
RunInstances语句里包含了AMI、子网、密钥对等资源,这些资源本身不会有Name标签等于IAM用户名的情况,直接导致整个Allow语句无法匹配,授权失败。 - 标签权限未做限制:原策略允许无限制的
CreateTags,用户可能创建实例后修改标签,脱离用户名关联的控制,必须限制只能操作符合要求的Name标签。
修复后的完整策略
data "aws_iam_policy_document" "ec2_access" { statement { sid = "DescribeAndListInConsole" effect = "Allow" actions = [ "ec2:Describe*", "ec2:GetConsole*", "ec2:*KeyPair*", "ec2:CreateSecurityGroup", "ec2:DeleteSecurityGroup", "ec2:AuthorizeSecurityGroupEgress", "ec2:AuthorizeSecurityGroupIngress", "cloudwatch:*", ] resources = ["*"] } # 允许创建实例,但强制携带正确的Name标签 statement { sid = "RunEC2InstancesWithRequiredTag" effect = "Allow" actions = ["ec2:RunInstances"] # 仅包含实例相关的核心资源,其他依赖资源单独放开 resources = [ "arn:aws:ec2:*:*:instance/*", "arn:aws:ec2:*:*:volume/*", "arn:aws:ec2:*:*:network-interface/*" ] condition { test = "StringEquals" variable = "aws:RequestTag/Name" values = ["${aws:username}"] } } # 放开创建实例所需的其他依赖资源(无需标签限制) statement { sid = "AllowRunInstancesDependencies" effect = "Allow" actions = ["ec2:RunInstances"] resources = [ "arn:aws:ec2:*:*:subnet/*", "arn:aws:ec2:*::image/ami-*", "arn:aws:ec2:*:*:key-pair/*", "arn:aws:ec2:*:*:security-group/*" ] } # 限制只能给实例添加/修改符合要求的Name标签 statement { sid = "RestrictInstanceTagging" effect = "Allow" actions = ["ec2:CreateTags"] resources = ["arn:aws:ec2:*:*:instance/*"] condition { test = "StringEquals" variable = "ec2:CreateAction" values = ["RunInstances"] } condition { test = "StringEquals" variable = "aws:TagKeys" values = ["Name"] } condition { test = "StringEquals" variable = "aws:RequestTag/Name" values = ["${aws:username}"] } } statement { sid = "ManageEC2Instance" effect = "Allow" actions = [ "ec2:StartInstances", "ec2:StopInstances", "ec2:RebootInstances", "ec2:TerminateInstances" ] resources = ["arn:aws:ec2:*:*:instance/*"] condition { test = "StringEquals" variable = "aws:ResourceTag/Name" values = ["${aws:username}"] } } statement { sid = "LimitInstanceTypesInUse" effect = "Deny" actions = ["ec2:RunInstances"] resources = ["arn:aws:ec2:*:*:instance/*"] condition { test = "ForAnyValue:StringNotLike" variable = "ec2:InstanceType" values = [ "*.nano", "*.micro", "*.small" ] } } }
关键修复点说明
- 拆分RunInstances资源:把实例相关资源和依赖资源(AMI、子网等)分开,依赖资源不需要标签条件,确保创建请求能匹配到允许的语句。
- 替换创建实例的条件:用
aws:RequestTag/Name检查创建请求中携带的标签,确保用户必须指定正确的Name标签才能创建实例。 - 限制标签操作权限:仅允许在创建实例时添加Name标签,且值必须等于用户名,防止用户后续修改标签脱离控制。
- 保留管理实例的条件:
aws:ResourceTag/Name用于管理已存在的实例是正确的,因为此时实例已经有标签了。
内容的提问来源于stack exchange,提问作者dernat71
相关产品推荐
相关产品推荐

