6

I want to create an IAM policy that allows a user deploy instances as follows:

  1. They can only use 1 AMI
  2. They can only deploy to 1 specific VPC subnet
  3. They can only use 1 specific VPC security group

This scenario is addressed in the VPC documentation here (Example 4):

http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/VPC_IAM.html#subnet-sg-example-iam

I have tried my own version of the policy as such:

{
"Version": "2012-10-17",
"Statement":[{
    "Effect":"Allow",
    "Action": "ec2:RunInstances",
    "Resource": [
        "arn:aws:ec2:eu-west-1:937821706121:image/ami-141ac363",
        "arn:aws:ec2:eu-west-1:937821706121:subnet/subnet-733de516",
        "arn:aws:ec2:eu-west-1:937821706121:network-interface/*",
        "arn:aws:ec2:eu-west-1:937821706121:volume/*",
        "arn:aws:ec2:eu-west-1:937821706121:key-pair/*",
        "arn:aws:ec2:eu-west-1:937821706121:security-group/sg-4aa80f2f"
    ]
}]
}

It doesn't work. I get permission denied when I attempt to deploy instances as a user who is a member of a group where this policy applies. Is there some other policy I need to include with this to allow instance deployment in this way?

2 Answers 2

7

Basically, the IAM documentation is totally unreliable when it comes to doing anything other than set global admin or read-only policies.

This is the policy I eventually got to work (for the subnet bit at least):

{
   "Version": "2012-10-17",
   "Statement": [{
      "Effect": "Deny",
      "Action": "ec2:RunInstances",
      "Resource": [
         "arn:aws:ec2:eu-west-1:937821706121:network-interface/*"
      ],
     "Condition": {
         "ArnNotEquals": {
            "ec2:Subnet": "arn:aws:ec2:eu-west-1:937821706121:subnet/subnet-733de516"
            }
      }
   },
   {
      "Effect": "Allow",
      "Action": "ec2:RunInstances",
      "Resource": [
         "arn:aws:ec2:eu-west-1::image/ami-*",
         "arn:aws:ec2:eu-west-1:937821706121:network-interface/*",
         "arn:aws:ec2:eu-west-1:937821706121:instance/*",
         "arn:aws:ec2:eu-west-1:937821706121:subnet/*",
         "arn:aws:ec2:eu-west-1:937821706121:volume/*",
         "arn:aws:ec2:eu-west-1:937821706121:key-pair/*",
         "arn:aws:ec2:eu-west-1:937821706121:security-group/*"
         ]
      }
   ]
}

This took a lot of trial and error.

Basically, when you want to limit the user based on specific resources, you need to create a Statement that first denies the ability to run instances unless conditions are met on specific arn resources, and then at the end, permit them to do anything.

Update:

Amazon have admitted that their docs were inaccurate:

https://forums.aws.amazon.com/thread.jspa?threadID=160287&tstart=0

-1

You cannot actually do that based on a VPC. AWS does not support EC2-Describe* API actions on resource level permissions. Instead you can apply something similar based on a single VPC on a security group as shown below:

{  
   "Version":"2012-10-17",
   "Statement":[  
      {  
         "Effect":"Allow",
         "Action":[  
            "ec2:AcceptVpcPeeringConnection",
            "ec2:AllocateAddress",
            "ec2:AssignPrivateIpAddresses",
            "ec2:AssociateAddress",
            "ec2:AssociateDhcpOptions",
            "ec2:AssociateRouteTable",
            "ec2:AttachClassicLinkVpc",
            "ec2:AttachInternetGateway",
            "ec2:AttachNetworkInterface",
            "ec2:AttachVolume",
            "ec2:AttachVpnGateway",
            "ec2:BundleInstance",
            "ec2:ConfirmProductInstance",
            "ec2:CopyImage",
            "ec2:CopySnapshot",
            "ec2:CreateCustomerGateway",
            "ec2:CreateDhcpOptions",
            "ec2:CreateFlowLogs",
            "ec2:CreateImage",
            "ec2:CreateInstanceExportTask",
            "ec2:CreateInternetGateway",
            "ec2:CreateKeyPair",
            "ec2:CreateNatGateway",
            "ec2:CreateNetworkAcl",
            "ec2:CreateNetworkAclEntry",
            "ec2:CreateNetworkInterface",
            "ec2:CreatePlacementGroup",
            "ec2:CreateReservedInstancesListing",
            "ec2:CreateRoute",
            "ec2:CreateRouteTable",
            "ec2:CreateSnapshot",
            "ec2:CreateSpotDatafeedSubscription",
            "ec2:CreateSubnet",
            "ec2:CreateTags",
            "ec2:CreateVolume",
            "ec2:CreateVpc",
            "ec2:CreateVpcEndpoint",
            "ec2:CreateVpcPeeringConnection",
            "ec2:CreateVpnConnection",
            "ec2:CreateVpnConnectionRoute",
            "ec2:CreateVpnGateway",
            "ec2:DeleteCustomerGateway",
            "ec2:DeleteDhcpOptions",
            "ec2:DeleteFlowLogs",
            "ec2:DeleteInternetGateway",
            "ec2:DeleteKeyPair",
            "ec2:DeleteNatGateway",
            "ec2:DeleteNetworkAcl",
            "ec2:DeleteNetworkAclEntry",
            "ec2:DeleteNetworkInterface",
            "ec2:DeletePlacementGroup",
            "ec2:DeleteRoute",
            "ec2:DeleteRouteTable",
            "ec2:DeleteSnapshot",
            "ec2:DeleteSpotDatafeedSubscription",
            "ec2:DeleteSubnet",
            "ec2:DeleteTags",
            "ec2:DeleteVolume",
            "ec2:DeleteVpc",
            "ec2:DeleteVpcEndpoints",
            "ec2:DeleteVpcPeeringConnection",
            "ec2:DeleteVpnConnection",
            "ec2:DeleteVpnConnectionRoute",
            "ec2:DeleteVpnGateway",
            "ec2:DeregisterImage",
            "ec2:DescribeAccountAttributes",
            "ec2:DescribeAddresses",
            "ec2:DescribeAvailabilityZones",
            "ec2:DescribeBundleTasks",
            "ec2:DescribeClassicLinkInstances",
            "ec2:DescribeConversionTasks",
            "ec2:DescribeCustomerGateways",
            "ec2:DescribeDhcpOptions",
            "ec2:DescribeExportTasks",
            "ec2:DescribeFlowLogs",
            "ec2:DescribeHosts",
            "ec2:DescribeImageAttribute",
            "ec2:DescribeImages",
            "ec2:DescribeImportImageTasks",
            "ec2:DescribeImportSnapshotTasks",
            "ec2:DescribeInstanceAttribute",
            "ec2:DescribeInstances",
            "ec2:DescribeInstanceStatus",
            "ec2:DescribeInternetGateways",
            "ec2:DescribeKeyPairs",
            "ec2:DescribeMovingAddresses",
            "ec2:DescribeNatGateways",
            "ec2:DescribeNetworkAcls",
            "ec2:DescribeNetworkInterfaceAttribute",
            "ec2:DescribeNetworkInterfaces",
            "ec2:DescribePlacementGroups",
            "ec2:DescribePrefixLists",
            "ec2:DescribeRegions",
            "ec2:DescribeReservedInstances",
            "ec2:DescribeReservedInstancesListings",
            "ec2:DescribeReservedInstancesModifications",
            "ec2:DescribeReservedInstancesOfferings",
            "ec2:DescribeRouteTables",
            "ec2:DescribeSnapshotAttribute",
            "ec2:DescribeSnapshots",
            "ec2:DescribeSpotDatafeedSubscription",
            "ec2:DescribeSpotFleetInstances",
            "ec2:DescribeSpotFleetInstances",
            "ec2:DescribeSpotFleetRequestHistory",
            "ec2:DescribeSpotFleetRequestHistory",
            "ec2:DescribeSpotFleetRequests",
            "ec2:DescribeSpotFleetRequests",
            "ec2:DescribeSpotInstanceRequests",
            "ec2:DescribeSpotPriceHistory",
            "ec2:DescribeSubnets",
            "ec2:DescribeTags",
            "ec2:DescribeVolumeAttribute",
            "ec2:DescribeVolumes",
            "ec2:DescribeVolumeStatus",
            "ec2:DescribeVpcAttribute",
            "ec2:DescribeVpcClassicLink",
            "ec2:DescribeVpcEndpoints",
            "ec2:DescribeVpcEndpointServices",
            "ec2:DescribeVpcPeeringConnections",
            "ec2:DescribeVpcs",
            "ec2:DescribeVpnConnections",
            "ec2:DescribeVpnGateways",
            "ec2:DetachClassicLinkVpc",
            "ec2:DetachInternetGateway",
            "ec2:DetachNetworkInterface",
            "ec2:DetachVolume",
            "ec2:DetachVpnGateway",
            "ec2:DisableVgwRoutePropagation",
            "ec2:DisableVpcClassicLink",
            "ec2:DisassociateAddress",
            "ec2:DisassociateRouteTable",
            "ec2:EnableVgwRoutePropagation",
            "ec2:EnableVolumeIO",
            "ec2:EnableVpcClassicLink",
            "ec2:GetConsoleOutput",
            "ec2:GetPasswordData",
            "ec2:ImportImage",
            "ec2:ImportInstance",
            "ec2:ImportKeyPair",
            "ec2:ImportSnapshot",
            "ec2:ImportVolume",
            "ec2:ModifyHosts",
            "ec2:ModifyIdFormat",
            "ec2:ModifyImageAttribute",
            "ec2:ModifyInstanceAttribute",
            "ec2:ModifyInstancePlacement",
            "ec2:ModifyNetworkInterfaceAttribute",
            "ec2:ModifyReservedInstances",
            "ec2:ModifySnapshotAttribute",
            "ec2:ModifySpotFleetRequest",
            "ec2:ModifySubnetAttribute",
            "ec2:ModifyVolumeAttribute",
            "ec2:ModifyVpcAttribute",
            "ec2:ModifyVpcEndpoint",
            "ec2:ModifyVpcPeeringConnectionOptions",
            "ec2:MonitorInstances",
            "ec2:MoveAddressToVpc",
            "ec2:PurchaseReservedInstancesOffering",
            "ec2:RebootInstances",
            "ec2:RegisterImage",
            "ec2:RejectVpcPeeringConnection",
            "ec2:ReleaseAddress",
            "ec2:ReportInstanceStatus",
            "ec2:RestoreAddressToClassic",
            "ec2:RunInstances",
            "ec2:StartInstances",
            "ec2:StopInstances",
            "ec2:TerminateInstances",
            "ec2:UnassignPrivateIpAddresses",
            "ec2:UnmonitorInstances",
            "s3:",
            "elasticloadbalancing:",
            "autoscaling:"
         ],
         "Resource":""
      },
      {  
         "Effect":"Allow",
         "Action":[  
            "ec2:DescribeSecurityGroups",
            "ec2:DescribeTags"
         ],
         "Resource":""
      },
      {  
         "Effect":"Allow",
         "Action":[  
            "ec2:AuthorizeSecurityGroupIngress",
            "ec2:RevokeSecurityGroupIngress",
            "ec2:AuthorizeSecurityGroupEgress",
            "ec2:RevokeSecurityGroupEgress"
         ],
         "Resource":"arn:aws:ec2:REGION:ACCOUNTNUMBER:security-group/",
         "Condition":{  
            "ArnEquals":{  
               "ec2:Vpc":"arn:aws:ec2:REGION:ACCOUNTNUMBER:vpc/VPCID"
            }
         }
      }
   ]
}

You can change the EC2 actions depending on your needs.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .