Enforce Resource Tagging in AWS Using IAM Policy Conditions

Tags are very important in a shared cloud environment. They serve many purposes. They let us attribute costs to the right departments. They let us hunt down owners of long-abandoned resources. And so on… In this article, we’ll see how to prevent users from creating resources in AWS unless they’re tagged with a tag key that you want.

Here we take the launching of an EC2 instance as an example but this idea can be applied to any resource. Start by attaching this IAM policy to the IAM user (or their group) who will be launching the instance:

{
    "Version": "2012-10-17",
    "Statement": {
        "Effect": "Deny",
        "Action": "ec2:RunInstances",
        "Resource": "*",
        "Condition": {
            "Null": {
                "aws:RequestTag/Owner": "true"
            }
        }
    }
}

This policy specifically targets the ec2:RunInstances action & whenever it happens, it checks whether the instance being launched is lacking the Owner tag. If it is, the action is denied! Now if the user tries to launch an instance without the Owner tag, they’ll get an error:

Unfortunately, there doesn’t seem to be a way to show a cleaner error to the user. AWS CLI must be used to decode that error:

aws sts decode-authorization-message \
  --encoded-message <encoded-message> \
  --query DecodedMessage --output text | jq '.'

This returns a huge response, part of it is shown here:

{
  "allowed": false,
  "explicitDeny": true,
  "matchedStatements": {
    "items": [
      {
        "statementId": "",
        "effect": "DENY",
        "principals": {
          "items": [
            {
              "value": "AIDATDOMLI3YFAYEBFGSO"
            }
          ]
        },
        "principalGroups": {
          "items": []
        },
        "actions": {
          "items": [
            {
              "value": "ec2:RunInstances"
            }
          ]
        },
        "resources": {
          "items": [
            {
              "value": "*"
            }
          ]
        },
        "conditions": {
          "items": [
            {
              "key": "aws:RequestTag/Owner",
              "values": {
                "items": [
                  {
                    "value": "true"
                  }
                ]
              }
            }
          ]
        }
      }
    ]
  }
}

It basically says that the instance launch failed because the Owner tag is missing! Depending on your use case, you can apply this IAM policy to other actions in your account. You can even apply it at an organization level to enforce tagging in all your accounts.

About the Author

Harish KM is an AWS Developer at QloudX. He is passionate about creating zero-maintenance fully-serverless cloud-native solutions in AWS. With 20+ cloud & IT certifications, he is an expert in a multitude of technologies, especially serverless.

Leave a Reply

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