AWS Auto tag - Multi resource and account

265 Views Asked by At

All,

I have multiple AWS Accounts (300+ and growing) with 4 regions for each accounts. Each account has different set of resource being created. It means services that are running on each account is not consistent across all the account.

Now, I wish to automate resource tagging using cloudtrail events such as "created by" to existing resources and for new resources.

Please advice me what would be best method to apply tag automatically for multi accounts/regions/resources.

1

There are 1 best solutions below

0
On

This is one of the most hectic scenarios most organizations face. But there is a simple and easy solution that can be implemented for resources that are being newly created. For existing resources it is a bit complex as we have to rely on Cloudtrail event history that only lasts for 90 days.

The solution is simple whenever a resource is created in the account a backend lambda automatically tags the resource with the Key as you mentioned "Created_by" and value is username (who created) fetched from Cloudtrail.

For example, if you want to automatically tag ec2 instances and lambdas create a eventbridge rule with the following pattern and add a lambda function as target

{
"detail": {
"configurationItem": {
  "configurationItemStatus": ["ResourceDiscovered"],
  "resourceType": ["AWS::Lambda::function","AWS::EC2::Instance"]
},
"messageType": ["ConfigurationItemChangeNotification"]
},
"detail-type": ["Config Configuration Item Change"],
"source": ["aws.config"]
}

The source of the Eventbridge is taken as aws.config.

The lambda has the following python code that does the auto-tagging function

import json
import boto3
def lambda_handler(event, context): 
  client = boto3.client('cloudtrail')

  resource_type = event["detail"]["configurationItem"]["resourceType"]
 resource_arn = event["resources"][0]

if resource_type == "AWS::Lambda::Function":
    resource_name = event["detail"]["configurationItem"]["configuration"]["functionName"]
    
    response = client.lookup_events(
    LookupAttributes=[
        {
            'AttributeKey': 'ResourceName',
            'AttributeValue': resource_name
        },
    ],
    )
    user_name=response["Events"][0]["Username"]
    
    client = boto3.client('lambda')
    
    client.tag_resource(
        Resource=resource_arn,
        Tags={'Created_by': user_name}
        )
    print("Lambda function "+resource_name+" tagged with username = " + user_name)

elif resource_type == "AWS::EC2::Instance":
    resource_name = event["detail"]["configurationItem"]["configuration"]["instanceId"]
    print(resource_name)
   
    
    response = client.lookup_events(
    LookupAttributes=[
        {
            'AttributeKey': 'ResourceName',
            'AttributeValue': resource_name
        },
    ],
    )
    user_name=response["Events"][0]["Username"]
    
    client = boto3.client('ec2')
    client.create_tags(
        Resources=[ resource_name ],
        Tags=[
            {
                'Key': 'Created_by',
                'Value': user_name
            },
        ])
    print("EC2 Instance "+resource_name+" tagged with username = " + user_name)

And make sure you add necessary permissions to the lambda function.

For detailed information - check the following links

https://medium.com/@TechStoryLines/automatically-tagging-aws-resources-with-usernames-a-brief-automation-guide-57d70455e66a

https://techstorylines.hashnode.dev/automatically-tagging-aws-resources-with-usernames-a-brief-automation-guide