I am trying to write a lambda function that will tag ec2 instances that will go from pending to running state. However, I have a problem reading the csv file that holds my ec2 instance tags. Currently, I have gone to where the lambda returns me the following result.
START RequestId: 6290699e-4018-4801-b7a8-6b5b46f26c2a Version: $LATEST {'Key': 'Name1', 'Value': 'Machine-1'} {'Key': 'Name2', 'Value': 'Machine-2'} {'Key': 'Name3', 'Value': 'Machine-3'} END RequestId: 6290699e-4018-4801-b7a8-6b5b46f26c2a REPORT RequestId: 6290699e-4018-4801-b7a8-6b5b46f26c2a Duration: 3306.40 ms Billed Duration: 3307 ms Memory Size: 128 MB Max Memory Used: 88 MB Init Duration: 335.79 ms
However, I need a list of dictionaries.
myList = [{'Key': 'Name1', 'Value': 'Instance-1'}, {'Key': 'Name2', 'Value': 'Instance-2'}, {'Key': 'Name3', 'Value': 'Instance-3'}]
Because the rest of the code looks like the following
instance_id = event['detail']['instance-id'] response = ec2_client.create_tags( Resources=[ instance_id, ], Tags=[ { 'Key': 'Name', 'Value': 'event_bridge_lambda_tag' }, ] )
At the moment, my lambda code looks like the following
import csv import boto3 from collections import OrderedDict def lambda_handler(event, context): s3_client = boto3.client("s3") ec2_client = boto3.client("ec2") S3_BUCKET_NAME = "tag-holds-bucket" FILE_NAME = "tags.csv" s3_file = s3_client.get_object(Bucket=S3_BUCKET_NAME, Key=FILE_NAME) file_content = s3_file['Body'].read().decode('utf-8').splitlines() myList = list() records = csv.DictReader(file_content) for row in records: #print(dict(row)) myList.append(row)
myList.append(row) -> gives me something like this as output
START RequestId: 618217d1-d1da-473f-b55e-77f1f7fe52dc Version: $LATEST [OrderedDict([('Key', 'Name1'), ('Value', 'Instance-1')]), OrderedDict([('Key', 'Name2'), ('Value', 'Instance-2')]), OrderedDict([('Key', 'Name3'), ('Value', 'Instance-3')])] END RequestId: 618217d1-d1da-473f-b55e-77f1f7fe52dc REPORT RequestId: 618217d1-d1da-473f-b55e-77f1f7fe52dc Duration: 3128.39 ms Billed Duration: 3129 ms Memory Size: 128 MB Max Memory Used: 88 MB Init Duration: 330.02 ms
I don’t know how to reach such a state
myList = [{'Key': 'Name1', 'Value': 'Instance-1'}, {'Key': 'Name2', 'Value': 'Instance-2'}, {'Key': 'Name3', 'Value': 'Instance-3'}]
My cvs file looks like this
And rest of the lambda code
instance_id = event['detail']['instance-id'] response = ec2_client.create_tags( Resources=[ instance_id, ], Tags=[ { 'Key': 'Name', 'Value': 'event_bridge_lambda_tag' }, ] )
Advertisement
Answer
csv.DictReader
returns a dict
or an OrderedDict
depending on the Python version you are running.
As seen in the documentation:
Changed in version 3.6: Returned rows are now of type OrderedDict.
Changed in version 3.8: Returned rows are now of type dict.
So it seems you are running Python < 3.8 in the lambda function. So you have 2 possibilities to have the output as a dict:
- Change your lambda function runtime to a higher one
- Convert the
OrderedDict
to adict
in your code simply using dict method:my_dict = dict(myList)