Daniel
Daniel

Reputation: 673

Boto3 KeyError when printing all managed instances

I'm trying to print all of the managed instances in my SSM environment. For some reason, it starts printing dozens of instance names, but at some point, it just errors out.

My script:

import boto3
import re

# Boto3
ssm_client = boto3.client('ssm')
ec2_client = boto3.client('ec2')

paginator = ssm_client.get_paginator('describe_instance_information')
response_iterator = paginator.paginate(
    Filters=[
        {
            'Key': 'ResourceType',
            'Values': [
                'ManagedInstance'],

            # 'Key': 'ResourceType',
            # 'Values': [
            #     'EC2Instance']
        },
    ],
    PaginationConfig={
        # 'MaxItems': 10,
    }
)

for item in response_iterator:
        for instance in item['InstanceInformationList']:
            print(instance['ComputerName'])

I just get the following output:

us-gw111
us-gw222
us-gw333
Traceback (most recent call last):
  File "/home/Python/SSM/app.py", line 42, in <module>
    print(instance['ComputerName'])
KeyError: 'ComputerName'
Exit 1

I'm not sure why it starts by printing a huge chunk of the overall list of instances, but then just reaches a certain point and errors out.

I'm sure that ComputerName is the correct key to call. If I use the following loop:

for item in response_iterator:
        for instance in item:
            print(instance)

my output is:

InstanceInformationList
NextToken
ResponseMetadata

So naturally I will dive in InstanceInformationList:

for item in response_iterator:
        for instance in item['InstanceInformationList']:
            print(instance.keys())

And here are the keys:

dict_keys(['InstanceId', 'PingStatus', 'LastPingDateTime', 'AgentVersion', 'IsLatestVersion', 'PlatformType', 'PlatformName', 'PlatformVersion', 'ActivationId', 'IamRole', 'RegistrationDate', 'ResourceType', 'IPAddress', 'ComputerName', 'AssociationStatus', 'LastAssociationExecutionDate', 'LastSuccessfulAssociationExecutionDate', 'AssociationOverview'])

As you can see, ComputerName is indeed one of them.

Upvotes: 0

Views: 637

Answers (1)

Daniel
Daniel

Reputation: 673

Seems like boto3 acts weird when it reaches an instance where the PingStatus is set to ConnectionLost.

This works:

for item in response_iterator:
        for instance in item['InstanceInformationList']:
            if instance.get('PingStatus') == 'Online':
                instanceName = instance.get('ComputerName').replace(".domain.net", "")
                print(instanceName)

Also, using instance.get('ComputerName') instead of instance['ComputerName'] seems to partially fix this, if you're not printing the ComputerName and just interested in the list as a whole.

Upvotes: 1

Related Questions