AWS Organizations: enforce tags on all resources that can have tags

919 Views Asked by At

TL;DR: What's THE BEST method of ensuring all resources have a set of tags?


I have a set of three tags, Component, Stack and Project, that I want present in any resource that can have tags.

I'm using Pulumi as my IaaS tool. I'm already using a Pulumi policy to ensure that resources have the required tags when I create them via Pulumi.

Since I'm using AWS Organizations, I can use a Tag Policy to ensure some resources have the required tags. However, this policy does not encompass all existing resources that can have tags.

I could use a SCP, but that seems cumbersome to maintain and difficult to reason about properly.

I tried something like:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "EnforceComponentTag",
            "Effect": "Deny",
            "Action": [
                "*"
            ],
            "Resource": [
                "*"
            ],
            "Condition": {
                "Null": {
                    "aws:RequestTag/Component": "true"
                }
            }
        }
    ]
}

But of course this is not working because it blocks get/describe requests, for example.

One could also try something like:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "EnforceComponentTag",
            "Effect": "Deny",
            "Action": [
                "aps:Create*",
                "aps:Delete*",
                "aps:Put*"
            ],
            "Resource": [
                "*"
            ],
            "Condition": {
                "Null": {
                    "aws:RequestTag/Component": "true"
                }
            }
        }
    ]
}

But I feel this is cumbersome to write and maintain and may lead to hard to debug bugs, as well as missing some resources.

Finally, there is also the AWS Config service to keep track of untagged resources.

What other alternatives exist to ensure all resources have a certain set of tags?

1

There are 1 best solutions below

0
sahith palika On

As of now AWS does not have any straight forward simple solution of implementing mandatory tags. You need to work around and implement the best solution that is efficient for you.

While you've already examined approaches such as Pulumi policies, AWS Organizations Tag Policies, and SCPs, there are additional strategies you can look into -

1. AWS Resource Groups

  • While this doesn't automatically enforce tagging, it offers a visual representation of tagged and untagged resources.
  • AWS Resource Groups enable you to establish and manage resource groups based on tags.
  • By creating a Resource Group that encompasses resources with designated tags, you can regularly review and ensure proper tagging.

2. Tag Editor

  • AWS Resource Groups Tagging provides a Tag Editor that allows you to view, edit, and manage tags for your resources.
  • You can filter resources based on tags, perform bulk tag operations, and search for resources using specific tag criteria.

3. Automation Script -

  • One can write an automation script to automatically tag new resources with the username of who created it.
  • This enables us to keep track of who created the resource and go back to him asking him to add the necessary tags
  • Make use of Eventbridge, lambda, and cloudtrail to this.
  • We will first create a eventbridge rule with a custom pattern that detects resource creation. So when a new lambda is created the rule detects it and triggers the target. In the target section of the eventbridge rule, we will have a lambda. This lambda gets the username from cloudtrail and adds a tag key:value to the newly created lambda.
  • you can refer to this article for more details - https://medium.com/@TechStoryLines/automatically-tagging-aws-resources-with-usernames-a-brief-automation-guide-57d70455e66a

4. Resource create alert

  • You can implement a resource-created email alert whenever a resource is created without necessary tags.
  • The architecture is same as described above but here the target lambda checks if the resource has all tags.
  • If not send a ses/sns alert

Fyr, You can refer to the SCP policy that is currently implemented in my account

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "DenyEC2CreationSCP1",
      "Effect": "Deny",
      "Action": [
        "ec2:RunInstances"
      ],
      "Resource": [
        "arn:aws:ec2:*:*:instance/*",
        "arn:aws:ec2:*:*:volume/*"
      ],
      "Condition": {
        "Null": {
          "aws:RequestTag/owner": "true"
        }
      }
    },
{
  "Sid": "DenySCP4",
  "Effect": "Deny",
  "Action": [
    "lambda:CreateFunction",
    "elasticloadbalancing:CreateLoadBalancer",
    "sns:CreateTopic",
    "sqs:CreateQueue",
    "glue:CreateJob",
    "glue:CreateWorkflow",
    "glue:CreateCrawler",
    "lightsail:CreateInstances",
    "lightsail:CreateRelationalDatabase",
    "elasticbeanstalk:CreateEnvironment",
    "elasticbeanstalk:CreateApplication",
    "ec2:AllocateAddress",
    "ec2:CreateVpc",
    "ec2:CreateNatGateway",
    "ec2:CreateVpnGateway",
    "ec2:CreateCustomerGateway",
    "ec2:CreateVpnConnection",
    "route53:CreateHostedZone",
    "s3:PutStorageLensConfiguration",
    "s3:CreateJob",
    "backup:CreateBackupVault",
    "backup:CreateBackupPlan",
    "backup:CreateProtectedResource",
    "firehose:CreateDeliveryStream",
    "kinesisanalytics:CreateApplication",
    "elasticache:CreateGlobalReplicationGroup",
    "ecs:CreateCluster",
    "ecs:RegisterTaskDefinition",
    "eks:CreateCluster"
  ],
  "Resource": "*",
  "Condition": {
    "Null": {
      "aws:RequestTag/team": "true"
    }
  }
}