如何使用 IAM 策略标签来限定 EC2 实例或 EBS 卷的创建方式?

上次更新时间:2020 年 11 月 11 日

我想允许启动新 Amazon Elastic Compute Cloud (Amazon EC2) 实例的 AWS Identity and Access Management (IAM) 用户或组访问权限。我还想允许创建新 Amazon Elastic Block Store (Amazon EBS) 卷的 IAM 用户访问权限,但仅在这些用户应用特定的标签时才允许。如何使用 IAM 策略条件来限定创建新资源的访问权限?

简短描述

您可以指定 EC2 实例和 EBS 卷的标签,作为用于创建资源的 API 调用的一部分。根据此原则,您可以要求 IAM 用户通过向其 IAM 策略应用条件来标记特定资源。以下示例策略不允许用户创建安全组或密钥对,因此,用户必须选择预先存在的安全组和密钥对。

以下示例 IAM 策略允许用户:

  • 启动标签键和值均匹配的 EC2 实例
  • 启动至少有一个标签和值匹配的 EC2 实例
  • 启动至少有一个标签键匹配的 EC2 实例
  • 启动只具有指定列表标签的 EC2 实例

解决方法

启动标签键和值均匹配的 EC2 实例

以下示例策略要求用户在使用限定词 ForAllValues 应用策略中定义的所有标签后,才能启动 EC2 实例和创建 EBS 卷。如果用户应用了策略中未包含的任何标签,则操作会被拒绝。要强制区分大小写,请使用条件 aws:TagKeys

注意:请修改示例策略中的 key1 value1 来包含适用于您的资源的标签和值。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "AllowToDescribeAll",
      "Effect": "Allow",
      "Action": [
        "ec2:Describe*"
      ],
      "Resource": "*"
    },
    {
      "Sid": "AllowRunInstances",
      "Effect": "Allow",
      "Action": "ec2:RunInstances",
      "Resource": [
        "arn:aws:ec2:*::image/*",
        "arn:aws:ec2:*::snapshot/*",
        "arn:aws:ec2:*:*:subnet/*",
        "arn:aws:ec2:*:*:network-interface/*",
        "arn:aws:ec2:*:*:security-group/*",
        "arn:aws:ec2:*:*:key-pair/*"
      ]
    },
    {
      "Sid": "AllowRunInstancesWithRestrictions",
      "Effect": "Allow",
      "Action": [
        "ec2:CreateVolume",
        "ec2:RunInstances"
      ],
      "Resource": [
        "arn:aws:ec2:*:*:volume/*",
        "arn:aws:ec2:*:*:instance/*"
      ],
      "Condition": {
        "StringEquals": {
          "aws:RequestTag/key1": "value1",
          "aws:RequestTag/key2": "value2"
        },
        "ForAllValues:StringEquals": {
          "aws:TagKeys": [
            "key1",
            "key2"
          ]
        }
      }
    },
    {
      "Sid": "AllowCreateTagsOnlyLaunching",
      "Effect": "Allow",
      "Action": [
        "ec2:CreateTags"
      ],
      "Resource": [
        "arn:aws:ec2:*:*:volume/*",
        "arn:aws:ec2:*:*:instance/*"
      ],
      "Condition": {
        "StringEquals": {
          "ec2:CreateAction": [
            "RunInstances",
            "CreateVolume"
          ]
        }
      }
    }
  ]
}

重要提示:要成功启动 EC2 实例,此策略必须包含匹配的标签键和值。如果键值对不匹配,您可能会收到“启动失败”错误或类似类型的 API 失败消息。

示例结果

键/值 结果
key1/value1 和 key2/value2 允许
key1/value1 拒绝
key1/value2 拒绝
无键和值 拒绝

启动至少有一个标签和值匹配的 EC2 实例

在下例中,请替换 AllowRunInstancesWithRestrictions 条件块,以在至少有一个标签键的名称为 key1 且其值为 value1 时允许用户启动一个 EC2 实例并创建 EBS 卷。您可以在 RunInstances 请求中添加任意数量的其他标签。

"Condition": {
  "StringEquals": {
    "aws:RequestTag/key1": "value1"
  },
  "ForAnyValue:StringEquals": {
    "aws:TagKeys": [
      "key1"
    ]
  }
}

示例结果

键/值 结果
key1/value1 和 key2/value2 允许
key1/value1 允许

key1/value2

拒绝
无键和值

拒绝

启动至少有一个标签键匹配的 EC2 实例

在以下示例策略中,请替换 AllowRunInstancesWithRestrictions 条件块,以在至少有一个标签键的名称为 key1 时允许用户启动一个 EC2 实例并创建 EBS 卷。key1 标签无需具有特定的值,并且可以在 RunInstances 请求中添加任意数量的其他标签。

"Condition": {
  "ForAnyValue:StringEquals": {
    "aws:TagKeys": [
      "key1"
    ]
  }
}

示例结果

键/值 结果
key1/value1 和 key2/value2 允许
key1/value1 允许
key1/value2 允许
无键和值 拒绝

启动只具有指定列表标签的 EC2 实例

在以下示例策略中,请替换 AllowRunInstancesWithRestrictions 条件块,以仅在请求中同时提供了标签键 key1key2 时允许用户启动一个 EC2 实例并创建 EBS 卷。任何一个标签键都无需具有特定的值,但不能在 RunInstances 请求中添加其他标签。

"Condition": {
  "StringLike": {
      "aws:RequestTag/key1": "*",
      "aws:RequestTag/key2": "*"
  },
  "ForAllValues:StringEquals": {
    "aws:TagKeys": [
        "key1",
        "key2"
    ]
  }
}

注意:必须提供 StringLike 条件,以确保所有标签都存在。

示例结果

键/值 结果
key1/AnyValue 和 key2/AnyValue 允许
key1/AnyValue

拒绝

key2/AnyValue 拒绝
没有键或值 拒绝
key1/AnyValue、key2/AnyValue、key3/AnyValue 拒绝