3

I m trying to list out EC2 instance id using python boto3. I m new to python.

Below Code is working fine

import boto3
region = 'ap-south-1'
ec2 = boto3.client('ec2', region_name=region)

def lambda_handler(event, context):
    print('Into DescribeEc2Instance')
    instances = ec2.describe_instances(Filters=[{'Name': 'instance-type', 'Values': ["t2.micro", "t3.micro"]}])
    print(instances)

Output is

START RequestId: bb4e9b27-db8e-49fe-85ef-e26ae53f1308 Version: $LATEST
Into DescribeEc2Instance
{'Reservations': [{'Groups': [], 'Instances': [{'AmiLaunchIndex': 0, 'ImageId': 'ami-052c08d70def62', 'InstanceId': 'i-0a22a6209740df', 'InstanceType': 't2.micro', 'KeyName': 'testserver', 'LaunchTime': datetime.datetime(2020, 11, 12, 8, 11, 43, tzinfo=tzlocal()), 'Monitoring': {'State': 'disabled'}

Now to strip instance id from above output, I have added below code(last 2 lines) and for some reason its not working.

import boto3
region = 'ap-south-1'
instance = []
ec2 = boto3.client('ec2', region_name=region)

    def lambda_handler(event, context):
        print('Into DescribeEc2Instance')
        instances = ec2.describe_instances(Filters=[{'Name': 'instance-type', 'Values': ["t2.micro", "t3.micro"]}])
        print(instances)
        for ins_id in instances['Instances']:
                print(ins_id['InstanceId'])

Error is

{
  "errorMessage": "'Instances'",
  "errorType": "KeyError",
  "stackTrace": [
    "  File \"/var/task/lambda_function.py\", line 10, in lambda_handler\n    for ins_id in instances['Instances']:\n"
  ]
}
2
  • should be instances['Reservations']['Instances'] Commented Nov 12, 2020 at 9:50
  • @taras added as per your comment its giving error message as "errorMessage": "list indices must be integers or slices, not str" Commented Nov 12, 2020 at 9:55

4 Answers 4

6

Actually the accepted answer instances['Reservations'][0]['Instances'] may not have all instances. Instances are grouped together by security groups.Different security groups means many list elements will be there. To get every instance in that region, you need to use the code below.

Note: ['Reservations'][0]['Instances'] doesn't list all the instances, It only gives you the instances which are grouped by the first security group. If there are many groups you won't get all instances.

import boto3
region = 'ap-south-1'

ec2 = boto3.client('ec2', region_name=region)

def lambda_handler(event, context):
    instance_ids = []
    response = ec2.describe_instances(Filters=[{'Name': 'instance-type', 'Values': ["t2.micro", "t3.micro"]}])
    instances_full_details = response['Reservations']
    for instance_detail in instances_full_details:
        group_instances = instance_detail['Instances']

        for instance in group_instances:
            instance_id = instance['InstanceId']
            instance_ids.append(instance_id)
    return instance_ids
Sign up to request clarification or add additional context in comments.

3 Comments

Got that.. I have mentioned in earlier comment.. with luk2302 explanation it was clear to me.. up voting your answer now.. it will be useful for other folks..
I hope you read the answer and came to know that response groups the set of instances based on security groups
Implemented for more than one instance and its working as expected. thanks
4

The loop iteration should be

for ins_id in instances['Reservations'][0]['Instances']:

since you have a Reservation key at the top level, then an array and objects in the array with the Instances key which itself is yet another array that you then actually iterate.

1 Comment

Got it now with your explanation.. I need to start for loop with Reservations.. then 2nd loop for Instances if I have more than one instance.. not sure about why someone down voted question without comment.
1

This is the simplest solution I have found to date:

ec2 = boto3.resource('ec2')
ids= [instance.id for instance in ec2.instances.all()]

1 Comment

Does this include ALL instances, not just a single page of instances?
0

I like this approach in case there are multiple reservations:

response = ec2.describe_instances()
for reservation in response['Reservations']:
    for instance in reservation['Instances']:
        print(instance['InstanceId'])

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.