How can I use IAM policy tags to restrict how an EC2 instance or EBS volume can be created?

Last updated: 2020-11-11

I want to allow AWS Identity and Access Management (IAM) users or groups access to launch new Amazon Elastic Compute Cloud (Amazon EC2) instances. I also want to allow IAM users access to create new Amazon Elastic Block Store (Amazon EBS) volumes, but only when they apply specific tags. How can I use IAM policy conditions to restrict access to create new resources?

Short description

You can specify tags for EC2 instances and EBS volumes as part of the API call that creates the resources. Using this principle, you can require IAM users to tag specific resources by applying conditions to their IAM policy. The following example policies don't allow users to create security groups or key pairs, so users must select pre-existing security groups and key pairs.

The following example IAM policies allow users to:

  • Launch EC2 instances that have matching tag keys and values
  • Launch EC2 instances that have at least one matching tag and value
  • Launch EC2 instances that have at least one matching tag key
  • Launch EC2 instances that have only the specified list of tags

Resolution

Launch EC2 instances that have matching tag keys and values

The following example policy allows a user to launch an EC2 instance and create an EBS volume only if the user applies all the tags that are defined in the policy using the qualifier ForAllValues. If the user applies a tag that's not included in the policy, then the action is denied. To enforce case sensitivity, use the condition aws:TagKeys.

Note: Modify key1 and value1 in the example policies to include the tags and values that apply to your resources.

{
  "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/*",
        "arn:aws:ec2:*:*:network-interface/*"
      ],
      "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/*",
        "arn:aws:ec2:*:*:network-interface/*"
      ],
      "Condition": {
        "StringEquals": {
          "ec2:CreateAction": [
            "RunInstances",
            "CreateVolume"
          ]
        }
      }
    }
  ]
}

Important: To launch EC2 instances successfully, this policy must include matching tag keys and values. If the key and value pairs don't match, you receive the error "Launch Failed" or similar type of API failure message.

Example results

Key/Value Result
key1/value1 and key2/value2 allow
key1/value1 deny
key1/value2 deny
no keys and values deny

Launch EC2 instances that have at least one matching tag and value

In the following example, replace the AllowRunInstancesWithRestrictions condition block to allow a user to launch an EC2 instance and create EBS volumes when at least one tag key is named key1 and its value is value1. Any number of additional tags can be added in the RunInstances request.

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

Example results

Key/Value Result
key1/value1 and key2/value2 allow
key1/value1 allow

key1/value2

deny
no keys and values

deny

Launch EC2 instances that have at least one matching tag key

In the following policy example, replace the AllowRunInstancesWithRestrictions condition block to allow a user to launch an EC2 instance and create EBS volumes when at least one tag key is named key1. No specific value is required for the key1 tag and any number of additional tags can be added in the RunInstances request.

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

Example results

Key/Value Result
key1/value1 and key2/value2 allow
key1/value1 allow
key1/value2 allow
no keys and values deny

Launch EC2 instances that have only the specified list of tags

In the following example policy, replace the AllowRunInstancesWithRestrictions condition block to allow a user to launch an EC2 instance and create EBS volumes only when tag keys key1 and key2 are provided in the request. No specific value is required for either tag keys, and no additional tags can be added in the RunInstances request.

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

Note: the StringLike condition is required to ensure that all tags are present.

Example results

Key/Value Results
key1/AnyValue and key2/AnyValue Allow
key1/AnyValue

Deny

key2/AnyValue Deny
No keys or values Deny
key1/AnyValue, key2/AnyValue, key3/AnyValue Deny