You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

编写限制EC2实例使用指定安全组的AWS IAM政策遇问题

解决IAM政策限制EC2实例启动仅允许特定安全组的问题

看起来你的问题出在两个关键地方:条件逻辑的组合方式和安全组标签对应的条件键使用错误,咱们一步步拆解。

问题根源分析

首先看你当前的政策,Condition部分是两个条件并列:

"Condition": {
  "StringNotLike": {
    "ec2:ResourceTag/aws:cloudformation:stack-id": "NetworkResourcesStack"
  },
  "StringNotEquals": {
    "ec2:ResourceTag/Name": "UCSFInbound"
  }
}

AWS IAM的条件默认是AND关系,意思是只有当两个条件同时满足时,才会执行Deny操作。也就是说:

  • 当安全组既没有aws:cloudformation:stack-id=NetworkResourcesStack标签,并且没有Name=UCSFInbound标签时,才会被拒绝。

但这里还有个更关键的错误:你用了ec2:ResourceTag这个条件键,它对应的是要创建的EC2实例的标签,而不是你指定的安全组的标签!这就导致当你使用UCSFInbound安全组时,政策其实在检查实例是否有Name=UCSFInbound标签,而不是安全组的标签,这完全不符合你的需求。

修正后的IAM政策

要实现“仅允许使用带有两类标签之一的安全组启动实例”,我们需要做两个调整:

  1. 使用ec2:SecurityGroup.ResourceTag/[tag-key]条件键来引用安全组的标签;
  2. 用OR逻辑组合两个否定条件,确保只要安全组不满足其中任何一个合规标签,就触发Deny。

修正后的政策如下:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "DenyNonCompliantSecurityGroups",
      "Effect": "Deny",
      "Action": [
        "ec2:StartInstances",
        "ec2:RunInstances"
      ],
      "Resource": [
        "arn:aws:ec2:*:*:subnet/*",
        "arn:aws:ec2:*:*:key-pair/*",
        "arn:aws:ec2:*:*:instance/*",
        "arn:aws:ec2:*::snapshot/*",
        "arn:aws:ec2:*:*:launch-template/*",
        "arn:aws:ec2:*:*:volume/*",
        "arn:aws:ec2:*:*:security-group/*",
        "arn:aws:ec2:*:*:placement-group/*",
        "arn:aws:ec2:*:*:network-interface/*",
        "arn:aws:ec2:*::image/*"
      ],
      "Condition": {
        "ForAllValues:Bool": {
          "aws:OR": [
            {
              "StringNotLike": {
                "ec2:SecurityGroup.ResourceTag/aws:cloudformation:stack-id": "NetworkResourcesStack"
              }
            },
            {
              "StringNotEquals": {
                "ec2:SecurityGroup.ResourceTag/Name": "UCSFInbound"
              }
            }
          ]
        }
      }
    }
  ]
}

政策逻辑解释

  • 条件键修正:ec2:SecurityGroup.ResourceTag/[tag-key]专门用于检查启动实例时指定的安全组的标签,这才符合你的需求;
  • OR逻辑实现:通过aws:OR把两个否定条件组合起来,再用ForAllValues:Bool确保所有指定的安全组都不满足合规条件时,才触发Deny。换句话说:
    • 如果用户指定的安全组中,有任意一个符合aws:cloudformation:stack-id=NetworkResourcesStack 或者 Name=UCSFInbound,则不会触发Deny,允许操作;
    • 只有当所有指定的安全组都不符合这两个标签时,才会被拒绝。

为什么之前第一个安全组能工作?

你提到符合aws:cloudformation:stack-id标签的安全组可以正常启动,大概率是因为这个安全组所在的CloudFormation栈在创建实例时,自动给实例加上了相同的aws:cloudformation:stack-id标签,导致ec2:ResourceTag/aws:cloudformation:stack-id条件匹配,从而没有触发Deny。但这是巧合,不是正确的逻辑。

最后补充一下:记得确认你的合规安全组确实已经正确打上了对应的标签,避免因为标签拼写错误导致的问题。

内容的提问来源于stack exchange,提问作者claudiadast

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 09:07:46