Using Python and Boto3 to get Instance Tag information

Here are 2 sample functions to illustrate how you can get information about Tags on instances using Boto3 in AWS.

import boto3

def get_instance_name(fid):
    # When given an instance ID as str e.g. 'i-1234567', return the instance 'Name' from the name tag.
    ec2 = boto3.resource('ec2')
    ec2instance = ec2.Instance(fid)
    instancename = ''
    for tags in ec2instance.tags:
        if tags["Key"] == 'Name':
            instancename = tags["Value"]
    return instancename

In this function, I create the ec2 resource object using the instance ID passed to the function. I iterate through the Tags of the instance until I find the ‘Name’ Tag and return its value. This is a very simple function that can pull any tag value, really.

Next up, this function will list all instances with a certain Tag name and certain Value on that tag.

import boto3

def list_instances_by_tag_value(tagkey, tagvalue):
    # When passed a tag key, tag value this will return a list of InstanceIds that were found.

    ec2client = boto3.client('ec2')

    response = ec2client.describe_instances(
        Filters=[
            {
                'Name': 'tag:'+tagkey,
                'Values': [tagvalue]
            }
        ]
    )
    instancelist = []
    for reservation in (response["Reservations"]):
        for instance in reservation["Instances"]:
            instancelist.append(instance["InstanceId"])
    return instancelist

Here I use ‘response’ to collect the instances which fall into the Filter used. Take note that I used the tag: + tagkey. tag-value would return any instance that this value on any tag. Tag-key returns any instance with the tag name field that matches here, regardless of the value. I want a specific tag and specific value.

Tagged , , , . Bookmark the permalink.

13 Responses to Using Python and Boto3 to get Instance Tag information

  1. Ryan says:

    I have tried the first solution above while passing the instance id from a cloudevent . It does not return anything. Any ideas, have things changed since you posted this?

    • mike says:

      By “not return anything” are you getting a timeout, python/boto error, does it just sit there and you have to ctrl+c it to break the process? Are you handling the ‘cloudevent’ through lambda?

      If you want some direction, I’d need more specifics on the error and how you are running the function.

      • ryan says:

        I get a successful response but no information.
        Running it like this
        def get_instance_name(thisInstanceID):
        ec2 = boto3.resource(‘ec2’)
        ec2instance = ec2.Instance(thisInstanceID)
        instancename = ”
        for tags in ec2instance.tags:
        if tags[“Key”] == ‘Name’:
        instancename = tags[“Value”]
        print(instancename)

  2. Deon Fleek says:

    Yeah, it’s broken.

    In [47]: get_instance_name(‘i-12345678’)
    Out[47]: ”

    • mike says:

      I just ran it to check, and the code works. Now, the instance has to have a Name, by default, they do not. If you query an instance ID that does not have a ‘Name’ tag set, it will return ”.

  3. Chris Gerber says:

    You should be using paginators. Your solution works until you have more resources than are returned in a single response.

    def list_instances_by_tag_value(tagkey, tagvalue):
    # When passed a tag key, tag value this will return a list of InstanceIds that were found.

    ec2client = boto3.client(‘ec2’)

    instances = ec2client.get_paginator(‘describe_instances’)

    response = instances.paginate(
    Filters=[
    {
    ‘Name’: ‘tag:’+tagkey,
    ‘Values’: [tagvalue]
    }
    ]
    )
    instancelist = []
    for reservation in response.get(“Reservations”):
    for instance in reservation.get(“Instances”):
    instancelist.append(instance.get(“InstanceId”))
    return instancelist

    • mike says:

      Yes, this would be correct if there are more then 1000 possible items returned, IIRC. I frequently use paginators for s3 stuff where thousands of objects can be returned as a response. And paginators should be used if you expect more then 1000 instances to be returned in your response.

  4. Noa says:

    I tried to write this solution of getting the instance name, and it writes to me “you must specify a region”.
    what should I do?

    • mike says:

      When you define the boto3 resource, include region_name=’us-east-1′ (or whichever region).
      ec2 = boto3.resource(‘ec2′,region_name=’us-east-1’)

  5. Noa says:

    thanks!
    now it writes me different error when i go to the ec2instance.tags:
    botocore.exceptions.NoCredentialsError: Unable to locate credentials

    • mike says:

      Right, you need to do one of these. Run the script on a host inside AWS with a host role with perms, you need to run the AWS cli config for user on the host and give it the key/secret key, or you can provide the id and key in the script.

      Like this:
      boto3.setup_default_session(aws_access_key_id=’xxxxxxxxxxxxx’,
      aws_secret_access_key=’xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx’,
      region_name=’us-east-1′

Leave a Reply

Your email address will not be published. Required fields are marked *

Solve : *
29 − 17 =