Search code examples
amazon-web-servicesamazon-ec2amazon-iamterraform-provider-awskey-pair

Using IAM role permissions to prevent user from launching EC2 instance in CLI without a key pair


I am creating a policy for an IAM role in Terraform and that role needs to be able to launch EC2 instances from a launch template, but with some flexibility and some restrictions. One of these restrictions is that any instance launched in the console or AWS CLI should have a key pair associated with it, however it does not have to be a specific key pair.

I have tried using several variations on the condition in the code below (e.g. explicitly specifying a name, changing the test conditions etc) and also tried a Null test with value false, to try to specify that the ec2:KeyPairName just needs to exist. None of these conditions are allowing me to launch an instance.

 {
      "Sid": "AllowEC2Launch",
      "Effect": "Allow",
      "Action": "ec2:RunInstances",
      "Resource": [
        "arn:aws:iam::xxx:instance-profile/xxx",
        "arn:aws:ec2:xxx::image/xxx",
        "arn:aws:ec2:xxx:xxx:volume/*",
        "arn:aws:ec2:xxx:xxx:subnet/subnet-xxx",
        "arn:aws:ec2:xxx:xxx:security-group/sg-xxx",
        "arn:aws:ec2:xxx:xxx:network-interface/*",
        "arn:aws:ec2:xxx:xxx:launch-template/lt-xxx",
        "arn:aws:ec2:xxx:xxx:key-pair/*",
        "arn:aws:ec2:xxx:xxx:instance/*",
        "arn:aws:ec2:xxx:xxx:elastic-gpu/*"
      ],
      "Condition": {
        "ForAnyValue:StringLike": {
          "ec2:KeyPairName": [
            "*"
          ]
        }
      }
    },

(I am defining this in Terraform, but as the question is about how to write the policy, not the TF, I've posted the policy.)

To confirm, without the condition I can launch an instance with and without a specified key. With any of the conditions I have tried, I cannot launch an instance with or without a specified key. This is all through AWS CLI.

I have also considered that key_name can be specified in the Terraform launch template definition, however I want the condition to be not null rather than restricted to one specific key.


Solution

  • I think its not possible. ec2:KeyPairName condition is only valid for arn:aws:ec2:*:*:key-pair/* resources. If you launch an instance without a key, the resources arn:aws:ec2:*:*:key-pair/* are simply not used, so ec2:KeyPairName is never evaluated.

    The workaround would be to setup AWS Config rule to check for new instances if they have the key or not, or simply setup a lambda function that is triggered whenever an instance is launched which will check for the key as well.