1

I am trying to find out all EC2 instances in 10 different accounts which are running non-amazon AMI images. Following CLI command gives me the list of all AMI's:

aws ec2 describe-instances --output text --query 'Reservations[*].Instances[*].[ImageId]' | sort | uniq -c

I think I can modify this further to get all non-amazon AMI's but is there a way to run this across 10 different accounts in one call?

NoviceMe
  • 3,126
  • 11
  • 57
  • 117

3 Answers3

2

is there a way to run this across 10 different accounts in one call?

No, that's not possible. You need to write a loop that iterates over each account, calling ec2 describe-instances once for each account.

Mark B
  • 183,023
  • 24
  • 297
  • 295
  • Is the cli command I wrote good? Or can this be written better to find non-amazon ami's? – NoviceMe Aug 05 '19 at 14:38
  • I'm not sure how you could filter by AMI owner in an `ec2 describe-instances` call, since that information is not included in the response. – Mark B Aug 05 '19 at 14:56
  • I dont need to filter by owner. I just need to know if AMI is amazon image or custom. Is there a better way to do this? – NoviceMe Aug 05 '19 at 19:12
  • The owner is how you check that. You would check if Amazon is the owner. – Mark B Aug 05 '19 at 19:22
  • This does not have owner: aws ec2 describe-instances. I only get owner if i search by linux or windows. Am i missing something? – NoviceMe Aug 05 '19 at 19:27
  • As I said, you need to look at the AMI Owner to determine if it is an AWS image or a customer created AMIs, but you don't get that information in a describe-instances call, so you are going to have to make multiple calls to determine this, and then multiply that by the number of accounts you have. – Mark B Aug 05 '19 at 20:40
0

Here's a script that can find instances using AMIs where the Owner is not amazon:

import boto3

ec2_client = boto3.client('ec2', region_name='ap-southeast-2')

instances = ec2_client.describe_instances()

# Get a set of AMIs used on all the instances
images = set(i['ImageId'] for r in instances['Reservations'] for i in r['Instances'])

# Find which of these are owned by Amazon
amis = ec2_client.describe_images(ImageIds=list(images), Owners=['amazon'])
amazon_amis = [i['ImageId'] for i in amis['Images']]

# Which instances are not using Amazon images?
non_amazon_instances = [(i['InstanceId'], i['ImageId']) for r in instances['Reservations'] for i in r['Instances'] if i['ImageId'] not in amazon_amis]

for i in non_amazon_instances:
    print(f"{i[0]} uses {i[1]}")

A few things to note:

  • Deprecated AMIs might not have accessible information, so might be marked a non-Amazon.
  • This script, as written, only works on one region. You could change it to loop through regions.
  • This script, as written, only works on one account. You would need a way to loop through credentials for other accounts.
John Rotenstein
  • 241,921
  • 22
  • 380
  • 470
0

Use AWS config

  1. Create an agregator in root or delegated account(wait for the agregator to load)
  2. Create query
SELECT
  accountId,
  resourceId,
  configuration.keyName,
  availabilityZone
WHERE
  resourceType = 'AWS::EC2::Instance'
  AND configuration.state.name = 'running'

more details https://aws.amazon.com/blogs/mt/org-aggregator-delegated-admin/