#!/usr/bin/env python
'''\
Generate a JSON object containing the names of all the AWS Autoscaling
-Groups in an account and the IPs of the Instances within them, suitable
-for use as an Ansible inventory.
+Groups in an account, the IDs of the Instances within them, as well
+as all the Tags on those Instances, each containing a list of the IPs
+of the Instances, suitable for use as an Ansible inventory.
+
+This output is similar to the default ec2.py inventory script, but is
+far more limited in the scope of information is has to retreive, parse,
+and render.
+
+It does not currently deal with hostvars at all.
'''
import argparse
import boto3
import json
import sys
+import os
from multiprocessing.dummy import Pool as ThreadPool
from functools import partial
-DEFAULT_REGIONS = ['us-east-1', 'us-west-2']
+#DEFAULT_REGIONS = ['us-east-1', 'us-west-2']
+DEFAULT_REGIONS = ['us-east-2']
HOSTVARS = {}
+try:
+ PUBLIC = len(os.environ['INVENTORY_PUBLIC']) > 0
+except:
+ PUBLIC = False
def allASGInstances(asgc):
'Return a tuple of a dict of each ASG name listing the instance IDs within it, and a list of all instance IDs.'
return instances
+def tagsOfInstances(ec2c, InstanceIds=None):
+ tags = {}
+ args = {'Filters': [{'Name': 'resource-type', 'Values': ["instance"]}]}
+ if InstanceIds:
+ args['Filters'] += [{'Name': 'resource-id', 'Values': InstanceIds}]
+ while True:
+ response = ec2c.describe_tags(**args)
+ for tag in response['Tags']:
+ tagname = "tag_{}_{}".format(tag['Key'], tag['Value'])
+ tagvalue = tag['ResourceId']
+ tags.setdefault(tagname, []).append(tagvalue)
+ if 'NextToken' not in response:
+ break
+ args['NextToken'] = response['NextToken']
+ return tags
+
+
def regionInventory(sessionArgs, publicIPs=False):
'Return dict results for one region.'
session = boto3.session.Session(**sessionArgs)
# add ASG dict, replacing ASG Instance Id with instance IP
inventory.update({asg:[AllInstanceIPs[iid] for iid in ASGs[asg] if iid in AllInstanceIPs] for asg in ASGs})
+ # group up instance tags as well
+ tags = tagsOfInstances(ec2c, AllInstanceIds)
+ inventory.update({tag:[AllInstanceIPs[iid] for iid in tags[tag] if iid in AllInstanceIPs] for tag in tags})
+
return inventory
parser = argparse.ArgumentParser(description='dynamic Ansible inventory from AWS Autoscaling Groups')
-parser.add_argument('--public', action='store_true', help='inventory public IPs (default: private IPs)')
+parser.add_argument('--public', action='store_true' if not PUBLIC else 'store_false', help='inventory public IPs (default: private IPs)')
parser.add_argument('--profile', metavar='PROFILE', dest='profile_name', help='AWS Profile (default: current IAM Role)')
parser.add_argument('--regions', metavar='REGION', nargs='+', default=DEFAULT_REGIONS, help='AWS Regions (default: %(default)s)')
parser.add_argument('--list', action='store_true')