Question: "How can I create an IAM policy to explicitly grant permissions for an IAM user, group, or role to create and manage EC2 instances in a specified VPC using tags?"

How can I create an AWS Identity and Access Management (IAM) policy that explicitly grants an IAM user, group, or role permissions to create and manage Amazon Elastic Compute Cloud (Amazon EC2) instances in a specified VPC? The policy must limit permissions so that the IAM entity can create EC2 instances with specific tags and manage those EC2 instances in a VPC by using those tags.

Short descriptionAmazon EC2 provides limited supported resource-level permissions, but there are several actions, resources, and conditions to consider. Certain Amazon EC2 API actions, such as launching an EC2 instance, can be controlled through the VPC ARN using tags to control the instances.

ResolutionApply a custom IAM policy to restrict the permissions of an IAM user, group, or role for creating EC2 instances in a specified VPC with tags. Use policy condition "ec2:ResourceTags" to limit control to instances. This policy grants permissions to launch EC2 instances in a designated VPC with a unique tag. You can then manage those EC2 instances using restrictive tags.Create a managed policy to apply to the IAM entities that launch your instances1.    Open the IAM console, choose Policies, and then choose Create Policy.2.    Choose the JSON tab, and then enter this custom policy:{  "Version": "2012-10-17",  "Statement": [    {      "Sid": "GrantIAMPassRoleOnlyForEC2",      "Action": [        "iam:PassRole"      ],      "Effect": "Allow",      "Resource": [        "arn:aws:iam::ACCOUNTNUMBER:role/ROLENAME",        "arn:aws:iam::ACCOUNTNUMBER:role/ROLENAME"      ],      "Condition": {        "StringEquals": {          "iam:PassedToService": "ec2.amazonaws.com"        }      }    },    {      "Sid": "ReadOnlyEC2WithNonResource",      "Action": [        "ec2:Describe*",        "iam:ListInstanceProfiles"      ],      "Effect": "Allow",      "Resource": "*"    },    {      "Sid": "ModifyingEC2WithNonResource",      "Action": [        "ec2:CreateKeyPair",        "ec2:CreateSecurityGroup"      ],      "Effect": "Allow",      "Resource": "*"    },    {      "Sid": "RunInstancesWithTagRestrictions",      "Effect": "Allow",      "Action": "ec2:RunInstances",      "Resource": [        "arn:aws:ec2:REGION:ACCOUNTNUMBER:instance/*",        "arn:aws:ec2:REGION:ACCOUNTNUMBER:volume/*"      ],      "Condition": {        "StringEquals": {          "aws:RequestTag/TAG-KEY": "TAG-VALUE"        }      }    },    {      "Sid": "RemainingRunInstancePermissionsNonResource",      "Effect": "Allow",      "Action": "ec2:RunInstances",      "Resource": [        "arn:aws:ec2:REGION::image/*",        "arn:aws:ec2:REGION::snapshot/*",        "arn:aws:ec2:REGION:ACCOUNTNUMBER*:network-interface/*",        "arn:aws:ec2:REGION:ACCOUNTNUMBER*:key-pair/*",        "arn:aws:ec2:REGION:ACCOUNTNUMBER*:security-group/*"      ]    },    {      "Sid": "EC2RunInstancesVpcSubnet",      "Effect": "Allow",      "Action": "ec2:RunInstances",      "Resource": "arn:aws:ec2:REGION:ACCOUNTNUMBER:subnet/*",      "Condition": {        "StringEquals": {          "ec2:Vpc": "arn:aws:ec2:REGION:ACCOUNTNUMBER:vpc/VPC-ID"        }      }    },    {      "Sid": "EC2VpcNonResourceSpecificActions",      "Effect": "Allow",      "Action": [        "ec2:DeleteNetworkAcl",        "ec2:DeleteNetworkAclEntry",        "ec2:DeleteRoute",        "ec2:DeleteRouteTable",        "ec2:AuthorizeSecurityGroupEgress",        "ec2:AuthorizeSecurityGroupIngress",        "ec2:RevokeSecurityGroupEgress",        "ec2:RevokeSecurityGroupIngress",        "ec2:DeleteSecurityGroup",        "ec2:CreateNetworkInterfacePermission",        "ec2:CreateRoute",        "ec2:UpdateSecurityGroupRuleDescriptionsEgress",        "ec2:UpdateSecurityGroupRuleDescriptionsIngress"      ],      "Resource": "*",      "Condition": {        "StringEquals": {          "ec2:Vpc": "arn:aws:ec2:REGION:ACCOUNTNUMBER:vpc/VPC-ID"        }      }    },    {      "Sid": "AllowInstanceActionsTagBased",      "Effect": "Allow",      "Action": [        "ec2:RebootInstances",        "ec2:StopInstances",        "ec2:TerminateInstances",        "ec2:StartInstances",        "ec2:AttachVolume",        "ec2:DetachVolume",        "ec2:AssociateIamInstanceProfile",        "ec2:DisassociateIamInstanceProfile",        "ec2:GetConsoleScreenshot",        "ec2:ReplaceIamInstanceProfileAssociation"      ],      "Resource": [        "arn:aws:ec2:REGION:ACCOUNTNUMBER:instance/*",        "arn:aws:ec2:REGION:ACCOUNTNUMBER:volume/*"      ],      "Condition": {        "StringEquals": {          "ec2:ResourceTag/TAG-KEY": "TAG-VALUE"        }      }    },    {      "Sid": "AllowCreateTagsOnlyLaunching",      "Effect": "Allow",      "Action": [        "ec2:CreateTags"      ],      "Resource": [        "arn:aws:ec2:REGION:ACCOUNTNUMBER:instance/*",        "arn:aws:ec2:REGION:ACCOUNTNUMBER:volume/*"      ],      "Condition": {        "StringEquals": {          "ec2:CreateAction": "RunInstances"        }      }    }  ]}3.    Replace the ACCOUNTNUMBER,  REGION, TAG-KEY, TAG-VALUE, VPC-ID, and ROLENAME parameters with values from your environment.4.    (Optional) If you're assigning this policy to only IAM users or groups, then you can replace the TAG-KEY or TAG-VALUE parameters with the IAM policy variable ${aws:username}. This policy variable allows the IAM service to prepopulate these parameters with the friendly name of the calling IAM user. This step allows IAM users to launch an instance in only the specified VPC, and allows the IAM users to control their own instances.5.    Choose Review policy, and then for Name, enter a name. For example, enter "VPC_Lockdown_VPC-ID", where "VPC-ID" is the ID of the VPC that you are applying this policy to.6.    Choose Create policy.Note: Some items must be replaced with specific resources from your environment. For more information, see Amazon Resource Names (ARNs).Attach the policy to a user, group, or role1.    In the IAM console navigation pane, choose Users, Groups, or Roles.2.    Choose the user, group, or role that you are attaching the policy to.3.    Choose Attach policies.4.    Enter the name of the policy that you created in the search box, and then choose your policy. For example, enter "VPC_Lockdown_VPC-ID".5.    Choose Attach Policy.An IAM entity with this custom policy attached can sign in to the AWS Management Console, open the Amazon EC2 dashboard, and then launch an EC2 instance after specifying the subnet, VPC, and tag.This policy restricts the following actions using the policy condition "ec2:ResourceTags":Starting the instanceStopping the instanceRebooting the instanceTerminating the instanceAttaching a volume to the instanceDetaching a volume from the instanceDisassociating the IAM instance profile from the instanceReplacing the IAM instance profile association for the instanceGetting a console screenshot of the instanceThis policy restricts the following actions against the specified VPC:Deleting security groupsCreating and delete routesDeleting route tablesDeleting network ACLsDeleting ACL entriesAuthorizing or revoke security group ingress and egress rulesCreating network interface permissionsUpdating security group description for ingress and egress rules