Find All Running EC2 Instances

There are now multiple EC2 regions spread across the world. In addition, you may have multiple accounts that you manage (for dev, test, production, etc.). Given that, it is easy to lose track of instances. And even though you may have forgotten about them, AWS has not, and you will continue to incur charges for these forgotten resources.

Use the EC2 API to find all running instances, for one or more accounts across all regions.

Fortunately, the EC2 API makes it relatively easy to find all running instances, for all accounts, across all regions. Example 2-12 gathers all of that information together and prints a report, and also returns a data structure that can be used to terminate unused instances.

Example 2-12. Find All Running Instances

import boto
import boto.ec2

def print_running_instances(running_instances):
    print 'The following running instances were found'
    for account_name in running_instances:
        print '\tAccount: %s' % account_name
        d = running_instances[account_name]
        for region_name in d:
            print '\t\tRegion: %s' % region_name
            for instance in d[region_name]:
                print '\t\t\tAn %s instance: %s' % (instance.instance_type,
                                                    instance.id)
                print '\t\t\t\tTags=%s' % instance.tags
    
def find_all_running_instances(accounts=None, quiet=False):
    """
    Will find all running instances across all EC2 regions for all of the
    accounts supplied.

    :type accounts: dict
    :param accounts: A dictionary contain account information.  The key is
                     a string identifying the account (e.g. "dev") and the
                     value is a tuple or list containing the access key
                     and secret key, in that order.
                     If this value is None, the credentials in the boto
                     config will be used.
    """
    if not accounts:
        creds = (boto.config.get('Credentials', 'aws_access_key_id'),
                 boto.config.get('Credentials', 'aws_secret_access_key'))
        accounts = {'main' : creds}
    running_instances = {}
    for account_name in accounts:
        running_instances[account_name] = {}
        ak, sk = accounts[account_name]
        for region in boto.ec2.regions():
            conn = region.connect(aws_access_key_id=ak,
                                  aws_secret_access_key=sk)
            filters={'instance-state-name' : 'running'}
            instances = []
            reservations = conn.get_all_instances(filters=filters)
            for r in reservations:
                instances += r.instances
            if instances:
                running_instances[account_name][region.name] = instances
    if not quiet:
        print_running_instances(running_instances)
    return running_instances
    
if __name__ == '__main__':
    find_all_running_instances()

Here’s an example of the script in use and the output produced:

>>> from ec2_find_all_running_instances import *
>>> find_all_running_instances()
The following running instances were found
	Account: main
		Region: us-east-1
			An t1.micro instance: i-9221f9fd
				Tags={u'midoc': ''}
			An t1.micro instance: i-b62057d6
				Tags={u'paws': ''}
{'main': {u'us-east-1': [Instance:i-9221f9fd, Instance:i-b62057d6]}}