Is it possible to have Automatically Tagging AWS Resources with Usernames?

AWS tags


Problem Statement:


Many organizations encounter a common challenge over time: the accumulation of resources. Determining which resources are still necessary becomes increasingly difficult. When the realization hits that we need to evaluate their relevance, it involves bringing in the account owner for a manual review and potential deletion of unnecessary items. Manually tracking down resources and their creators in AWS can be a time-consuming and challenging task, especially when relying on limited CloudTrail logs that expire after 90 days.

Design

  • Set up an EventBridge rule that listens for events from AWS Config as its source. When AWS Config detects a new resource creation, it triggers a Lambda or a Step function.

  • The Lambda/Step function then accesses CloudTrail to retrieve the IAM info associated with the action. With the IAM info in hand, the Lambda/Step function proceeds to tag the resource itself. The tags added to the resource will include a “key” with the label “Created_by” and a corresponding “value” that contains the IAM info fetched from CloudTrail.

Sample EventBridge rule

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

In AWS Config, the configurationItemStatus field indicates the status of a configuration item (CI) for a resource. Here are the valid values for configurationItemStatus:

  • OK: The resource configuration has been updated.

  • ResourceDiscovered: The resource was newly discovered.

  • ResourceNotRecorded: The resource was discovered, but its configuration was not recorded since the recorder doesn’t record resources of this type.

  • ResourceDeleted: The resource was deleted.

  • ResourceDeletedNotRecorded: The resource was deleted, but its configuration was not recorded since the recorder doesn’t record resources of this type1.

Create a Lambda

Sample Lambda function. Make sure to grant the necessary permissions to the Lambda function to read CloudTrail logs and also permission to tag Lambda resources.

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::S3::Bucket":
        resource_name = event["detail"]["configurationItem"]["resourceId"]
        print(resource_name)
        print("S3 Tagging "+resource_name+"starting" )

        
        response = client.lookup_events(
        LookupAttributes=[
            {
                'AttributeKey': 'ResourceName',
                'AttributeValue': resource_name
            },
        ],
        )
        user_name=response["Events"][0]["Username"]
        
        print("S3 bucket "+resource_name+" is trying to tag with username = " + user_name)
        
        client = boto3.client('s3')
        client.put_bucket_tagging(
            Bucket=resource_name,
            Tagging={'TagSet': [{'Key': 'created_by', 'Value': user_name}]})
        
        print("S3 bucket "+resource_name+" tags with username = " + user_name)
        print("S3 Instance "+resource_name+" tagged with username = " + user_name)

A sample screenshot





Comments