Restrict IAM User

In this blog post I will go through how you can allow IAM users to launch EC2 instances, but only when they apply certain tags. You will also get to know how you can restrict the same user to start, stop, restart and terminate only the instances that they have launched based on tags.

Introduction

Sometimes as an AWS administrator you want the users to be able to launch EC2 instances only if they have assigned the required tags while launching the instances. This maybe required because not everyone tags their resources properly until you don’t enforce them. And at the same time you don’t want the users to accidentally terminate EC2 instances that they shouldn’t have.

Prerequisites

Below are the pre-requisites in order for you to setup this in your environment:

  • An AWS Account with Administrator privileges
  • Basics of AWS and IAM in particular
  • AWS CLI configured with proper credentials

Setup

In this blog I will take example of a scenario where users should always have tag key of Owner and tag value as their IAM username while spinning up their EC2 instances. And they will only be able to start, stop, restart and terminate the EC2 instances which will have the Owner tag as their IAM username, in this way they will not be able to do anything on other users EC2 instances accidentally. And they will not be able to spin up EC2 instances if the Owner tag key and values are missing.

I will login to AWS from as an admin user and create another IAM user and attach the below IAM policy to this new user. Click here to know more on how to create an IAM user and assign policy to the user.

I have already gone ahead and created an IAM user of name Sam and assigned the below policy to the user.

  {
    "Version": "2012-10-17",
    "Statement": [
        {
        "Sid": "AllowToDescribeAll",
        "Effect": "Allow",
        "Action": [
          "ec2:Describe*"
        ],
        "Resource": "*"
      },
      {
        "Sid": "AllowRunInstancesWithRestrictions",
        "Effect": "Allow",
        "Action": "ec2:RunInstances",
        "Resource": [
            "arn:aws:ec2:*:*:volume/*",
            "arn:aws:ec2:*:*:instance/*"
        ],
        "Condition": {
            "StringEquals": {
                "aws:RequestTag/Owner": "${aws:username}"
            },
            "ForAnyValue:StringEquals": {
                "aws:TagKeys": [
                  "Owner"
                ]
              }
        }
    },
      {
        "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": "AllowOtherActionsonInstanceswithRestriction",
        "Effect": "Allow",
        "Action": [
            "ec2:StartInstances",
            "ec2:StopInstances",
            "ec2:RebootInstances",
            "ec2:TerminateInstances",
            "ec2:AttachVolume",
            "ec2:DetachVolume",
            "ec2:DeleteVolume",
            "ec2:DeleteSnapshot"
        ],
        "Resource": "*",
        "Condition": {
            "StringEquals": {
                "ec2:ResourceTag/Owner": "${aws:username}"
            }
        }
    },
      {
        "Sid": "AllowCreateTagsOnlyLaunching",
        "Effect": "Allow",
        "Action": [
          "ec2:CreateTags"
        ],
        "Resource": [
          "arn:aws:ec2:*:*:volume/*",
          "arn:aws:ec2:*:*:instance/*"
        ],
        "Condition": {
          "StringEquals": {
            "ec2:CreateAction": "RunInstances"
          }
        }
      }
    ]
  }

Let’s dive deeper into this policy.

There are 5 separate blocks in the above policy. Let’s go through each one by one:

  • AllowToDescribeAll basically gives describe access to this user so that they can see are able to see all the EC2 resources like instances, VPC’s, Subnets, Security Groups etc.
  • AllowRunInstancesWithRestrictions and AllowRunInstances is part where we are restricting the user to launch only when the user specifies tag key of Owner and tag value of their IAM username. You will notice I have used IAM Policy variable which will automatically check for the IAM username. Click here to learn more about IAM Policy variables.
  • AllowOtherActionsonInstanceswithRestriction allows users to start, stop, restart and terminate instances if and only if tag key of Owner and tag value of their IAM username (In this case Sam).
  • AllowCreateTagsOnlyLaunching will ensure that the user can only tags while spinning up the instances and not after they have spin it up.

Time for some action

Now lets’ go ahead and launch some EC2 instances to see the above policy in action. As you can see in the below image, I haven’t specified the tag key of Owner and tag value of Sam.

Let’s try to launch it and see what happens.

Let’s try to understand what the error is. We will use AWS CLI to decode the above message. You can use decode-authorization-message command to see the actual message. This assumes that you have the AWS CLI configured with proper credentials. Click here to dive deeper into how to configure AWS CLI.

aws sts decode-authorization-message --encoded-message <encoded authorization failure message>

Now, let’s add the Owner tag and try again. And you can see in the below image, that the instance launches successfully

If you will try to stop the instance, you should be able to stop it.

Now, let’s spin up instance using the Admin user and let’s not put a tag key of Owner and tag value of Sam (in your case please put tag value as your respective username) on it. We are doing this from Admin user because you will not be able to spin up any instance by using the IAM user without having the required tag key and tag value.

No, let’s try to stop it by logging in as Sam user, and you will see that you are not able to stop the instance.

And you will notice that you cannot stop this instance because it’s not tagged with tag key of Owner and tag value of Sam.

Again you will note that we get the encoded authorization failure message. You can again use the decode-authorization-message to see the actual message.

Conclusion

In this post we covered how to allow users to launch EC2 instances only when they specify certain tags. We also looked at how to restrict users to not stop, restart, terminate other users EC2 instances which are tagged with different tag key and tag value. I just demonstrated by using Owner tag but you can further modify the above policy based on your needs and play with it in order to suit your requirements.

Feel free to leave your feedback or any queries that you may have while setting this up in your own environment in the comments section below.

Leave a comment

Your email address will not be published. Required fields are marked *