Search code examples
python-3.xaws-lambdaboto3

Retrieve custom tag values for later use in Lambda / Python 3.12 function


I am an intern and new to Python and lambda and was given an exercise task to create a Lambda / Python 3.12 function that would search a specific account for EC2 instances that are running Windows 2022 Datacenter and then report on those along with the custom tag values for "itowner", "os", and the standard tag values for "Name" and "instanceid". I have some of this working but I am retrieving the tag values by position, but I just want to fetch the values another way as the tag position could be different on different instances. My code is below.

import boto3

ec2 = boto3.client('ec2')


def lambda_handler(event, context):
    response = ec2.describe_instances(
        Filters=[
            {
                'Name': 'tag:os',
                'Values': [
                    'win2022dc',
                ],
            },
        ],
    )
    for reservation in response["Reservations"]:
        for instance in reservation["Instances"]:
            instance_id = instance["InstanceId"]
            instance_type = instance["InstanceType"]
            for tags in instance["Tags"]:
                os = instance["Tags"][0]["Value"]
                instance_name = instance["Tags"][6]["Value"]
                itowner = instance["Tags"][11]["Value"]
             
print("Instance Name: " + instance_name,"Instance ID: " + instance_id, "Operating System: " + os, "ITOwner: " + itowner,)

Solution

  • You can use iterator and next. Additionally, you don't need a loop for tags. What you did with the loop here is repeat everything multiple times (depending on the number of tags). You will change this:

    for tags in instance["Tags"]:
        os = instance["Tags"][0]["Value"]
        instance_name = instance["Tags"][6]["Value"]
        itowner = instance["Tags"][11]["Value"]
    

    To this:

    os = next(e["Value"] for e in instance["Tags"] if e["Key"]=="os")
    instance_name = next(e["Value"] for e in instance["Tags"] if e["Key"]=="Name")
    itowner = next(e["Value"] for e in instance["Tags"] if e["Key"]=="itowner")
    

    This will iterate over the instance["Tags"] list, check the Key of the tag (since all items in this list are dictionaries that have Key and Value. If Key is what you need, take it's value. If you're sure that all instances have these keys, you can use this approach. If you think some might not exist, you should use the safety option to return empty string in case of non-existing tag, since next supports returning a default value, so that it doesn't throw an exception:

    os = next((e["Value"] for e in instance["Tags"] if e["Key"]=="os"), "")
    instance_name = next((e["Value"] for e in instance["Tags"] if e["Key"]=="Name"), "")
    itowner = next((e["Value"] for e in instance["Tags"] if e["Key"]=="itowner"), "")