Reputation: 1
I'm trying to automate tagging for the following resources on AWS:
Currently I have a Lambda function that is almost identical to this article: How to Automatically Tag Amazon EC2 Resources in Response to API Events | AWS Security Blog
How can I modify this Lambda function so it tags the above resources as well?
I've tried finding documentation on how to tag these specific resources and I can't seem to find anything that's relevant to tagging using a Lambda function.
elif eventname == 'CreateImage':
ids.append(detail['responseElements']['imageId'])
logger.info(ids)
elif eventname == 'CreateSnapshot':
ids.append(detail['responseElements']['snapshotId'])
logger.info(ids)
elif eventname == 'CreateSecurityGroup':
ids.append(detail['responseElements']['groupId'])
else:
logger.warning('Not supported action')
The above code is adding tags for EC2, but we need it to add tags to the resources I listed above.
Upvotes: 0
Views: 11498
Reputation: 111
To tag resources upon creation you need to use Lambda, Cloudwatch events and some automation.
You can tag resources with the IAM ARN of the resource creator and resource created-date with the documentation available here, this is an open-source tagging solution for AWS. This will help you tag your resources with the IAM ARN of the creator and the resource created-date.
There are two ways you can implement the solution available on the above link, 1. Shell Script and 2. CloudFormation template.
Upvotes: 0
Reputation: 412
This should help on a few of them.
Here are the cloudwatch event patterns:
{
"detail-type": [
"AWS API Call via CloudTrail"
],
"detail": {
"eventSource": [
"ec2.amazonaws.com",
"rds.amazonaws.com",
"lambda.amazonaws.com",
"s3.amazonaws.com",
"dynamodb.amazonaws.com",
"elasticfilesystem.amazonaws.com"
],
"eventName": [
"CreateVolume",
"RunInstances",
"CreateImage",
"CreateSnapshot",
"CreateDBInstance",
"CreateFunction20150331",
"UpdateFunctionConfiguration20150331v2",
"UpdateFunctionCode20150331v2",
"CreateBucket",
"CreateTable",
"CreateMountTarget"
]
}
}
and then here is the corresponding lambda code which will need a few modifications for your environment.
from __future__ import print_function
import json
import boto3
import logging
import time
import datetime
logger = logging.getLogger()
logger.setLevel(logging.INFO)
def lambda_handler(event, context):
logger.info('################ Event: ############## ' + str(event))
#print('Received event: ' + json.dumps(event, indent=2))
ids = []
try:
region = event['region']
detail = event['detail']
eventname = detail['eventName']
arn = detail['userIdentity']['arn']
principal = detail['userIdentity']['principalId']
userType = detail['userIdentity']['type']
if userType == 'IAMUser':
user = detail['userIdentity']['userName']
else:
user = principal.split(':')[1]
logger.info('principalId: ' + str(principal))
logger.info('region: ' + str(region))
logger.info('eventName: ' + str(eventname))
logger.info('detail: ' + str(detail))
ec2_client = boto3.resource('ec2')
lambda_client = boto3.client('lambda')
rds_client = boto3.client('rds')
s3_client = boto3.resource('s3')
ddb_client = boto3.client('dynamodb')
efs_client = boto3.client('efs')
if eventname == 'CreateVolume':
ids.append(detail['responseElements']['volumeId'])
logger.info(ids)
elif eventname == 'RunInstances':
items = detail['responseElements']['instancesSet']['items']
for item in items:
ids.append(item['instanceId'])
logger.info(ids)
logger.info('number of instances: ' + str(len(ids)))
base = ec2_client.instances.filter(InstanceIds=ids)
#loop through the instances
for instance in base:
for vol in instance.volumes.all():
ids.append(vol.id)
for eni in instance.network_interfaces:
ids.append(eni.id)
elif eventname == 'CreateImage':
ids.append(detail['responseElements']['imageId'])
logger.info(ids)
elif eventname == 'CreateSnapshot':
ids.append(detail['responseElements']['snapshotId'])
logger.info(ids)
elif eventname == 'CreateFunction20150331':
try:
functionArn = detail['responseElements']['functionArn']
lambda_client.tag_resource(Resource=functionArn,Tags={'CreatedBy': user})
lambda_client.tag_resource(Resource=functionArn,Tags={'DateCreated': time.strftime("%B %d %Y")})
except Exception as e:
logger.error('Exception thrown at CreateFunction20150331' + str(e))
pass
elif eventname == 'UpdateFunctionConfiguration20150331v2':
try:
functionArn = detail['responseElements']['functionArn']
lambda_client.tag_resource(Resource=functionArn,Tags={'LastConfigModifiedByNetID': user})
except Exception as e:
logger.error('Exception thrown at UpdateFunctionConfiguration20150331v2' + str(e))
pass
elif eventname == 'UpdateFunctionCode20150331v2':
try:
functionArn = detail['responseElements']['functionArn']
lambda_client.tag_resource(Resource=functionArn,Tags={'LastCodeModifiedByNetID': user})
except Exception as e:
logger.error('Exception thrown at UpdateFunctionCode20150331v2' + str(e))
pass
elif eventname == 'CreateDBInstance':
try:
dbResourceArn = detail['responseElements']['dBInstanceArn']
rds_client.add_tags_to_resource(ResourceName=dbResourceArn,Tags=[{'Key':'CreatedBy','Value': user}])
except Exception as e:
logger.error('Exception thrown at CreateDBInstance' + str(e))
pass
elif eventname == 'CreateBucket':
try:
bucket_name = detail['requestParameters']['bucketName']
s3_client.BucketTagging(bucket_name).put(Tagging={'TagSet': [{'Key':'CreatedBy','Value': user}]})
except Exception as e:
logger.error('Exception thrown at CreateBucket' + str(e))
pass
elif eventname == 'CreateTable':
try:
tableArn = detail['responseElements']['tableDescription']['tableArn']
ddb_client.tag_resource(ResourceArn=tableArn,Tags=[{'Key':'CreatedBy','Value': user}])
except Exception as e:
logger.error('Exception thrown at CreateTable' + str(e))
pass
elif eventname == 'CreateMountTarget':
try:
system_id = detail['requestParameters']['fileSystemId']
efs_client.create_tags(FileSystemId=system_id, Tags=[{'Key':'CreatedBy','Value': user}])
except Exception as e:
logger.error('Exception thrown at CreateMountTarget' + str(e))
pass
# todo: EMR and Glacier also possible candidates
else:
logger.warning('No matching eventname found in the Auto Tag lambda function (Ln 118)')
if ids:
for resourceid in ids:
print('Tagging resource ' + resourceid)
ec2_client.create_tags(Resources=ids, Tags=[{'Key': 'CreatedBy', 'Value': user}])
logger.info(' Remaining time (ms): ' + str(context.get_remaining_time_in_millis()) + '\n')
return True
except Exception as e:
logger.error('Something went wrong: ' + str(e))
return False
You are kind of limited by what is supported by Cloudwatch events, but this will hopefully help you knock out a few of the ones on your list.
Upvotes: 3
Reputation: 1631
Maybe something from python boto lib would help (on example of RDS) :
response = client.add_tags_to_resource(
ResourceName='arn:aws:rXXXXX,
Tags=[
{
'Key': 'Staging',
'Value': '2019',
},
], )
Upvotes: 0