diff --git a/baas-1601-dc1/ec2.ini b/baas-1601-dc1/ec2.ini
deleted file mode 100644
index 36b3921..0000000
--- a/baas-1601-dc1/ec2.ini
+++ /dev/null
@@ -1,200 +0,0 @@
-# Ansible EC2 external inventory script settings
-#
-
-[ec2]
-
-# to talk to a private eucalyptus instance uncomment these lines
-# and edit edit eucalyptus_host to be the host name of your cloud controller
-#eucalyptus = True
-#eucalyptus_host = clc.cloud.domain.org
-
-# AWS regions to make calls to. Set this to 'all' to make request to all regions
-# in AWS and merge the results together. Alternatively, set this to a comma
-# separated list of regions. E.g. 'us-east-1,us-west-1,us-west-2'
-regions = all
-regions_exclude = us-gov-west-1,cn-north-1
-
-# When generating inventory, Ansible needs to know how to address a server.
-# Each EC2 instance has a lot of variables associated with it. Here is the list:
-#   http://docs.pythonboto.org/en/latest/ref/ec2.html#module-boto.ec2.instance
-# Below are 2 variables that are used as the address of a server:
-#   - destination_variable
-#   - vpc_destination_variable
-
-# This is the normal destination variable to use. If you are running Ansible
-# from outside EC2, then 'public_dns_name' makes the most sense. If you are
-# running Ansible from within EC2, then perhaps you want to use the internal
-# address, and should set this to 'private_dns_name'. The key of an EC2 tag
-# may optionally be used; however the boto instance variables hold precedence
-# in the event of a collision.
-destination_variable = public_dns_name
-
-# This allows you to override the inventory_name with an ec2 variable, instead
-# of using the destination_variable above. Addressing (aka ansible_ssh_host)
-# will still use destination_variable. Tags should be written as 'tag_TAGNAME'.
-#hostname_variable = tag_Name
-
-# For server inside a VPC, using DNS names may not make sense. When an instance
-# has 'subnet_id' set, this variable is used. If the subnet is public, setting
-# this to 'ip_address' will return the public IP address. For instances in a
-# private subnet, this should be set to 'private_ip_address', and Ansible must
-# be run from within EC2. The key of an EC2 tag may optionally be used; however
-# the boto instance variables hold precedence in the event of a collision.
-# WARNING: - instances that are in the private vpc, _without_ public ip address
-# will not be listed in the inventory until You set:
-# vpc_destination_variable = private_ip_address
-vpc_destination_variable = ip_address
-
-# The following two settings allow flexible ansible host naming based on a
-# python format string and a comma-separated list of ec2 tags.  Note that:
-#
-# 1) If the tags referenced are not present for some instances, empty strings
-#    will be substituted in the format string.
-# 2) This overrides both destination_variable and vpc_destination_variable.
-#
-#destination_format = {0}.{1}.example.com
-#destination_format_tags = Name,environment
-
-# To tag instances on EC2 with the resource records that point to them from
-# Route53, uncomment and set 'route53' to True.
-route53 = False
-
-# To exclude RDS instances from the inventory, uncomment and set to False.
-rds = False
-
-# To exclude ElastiCache instances from the inventory, uncomment and set to False.
-elasticache = False
-
-# Additionally, you can specify the list of zones to exclude looking up in
-# 'route53_excluded_zones' as a comma-separated list.
-# route53_excluded_zones = samplezone1.com, samplezone2.com
-
-# By default, only EC2 instances in the 'running' state are returned. Set
-# 'all_instances' to True to return all instances regardless of state.
-all_instances = True
-
-# By default, only EC2 instances in the 'running' state are returned. Specify
-# EC2 instance states to return as a comma-separated list. This
-# option is overriden when 'all_instances' is True.
-# instance_states = pending, running, shutting-down, terminated, stopping, stopped
-
-# By default, only RDS instances in the 'available' state are returned.  Set
-# 'all_rds_instances' to True return all RDS instances regardless of state.
-all_rds_instances = False
-
-# By default, only ElastiCache clusters and nodes in the 'available' state
-# are returned. Set 'all_elasticache_clusters' and/or 'all_elastic_nodes'
-# to True return all ElastiCache clusters and nodes, regardless of state.
-#
-# Note that all_elasticache_nodes only applies to listed clusters. That means
-# if you set all_elastic_clusters to false, no node will be return from
-# unavailable clusters, regardless of the state and to what you set for
-# all_elasticache_nodes.
-all_elasticache_replication_groups = False
-all_elasticache_clusters = False
-all_elasticache_nodes = False
-
-# API calls to EC2 are slow. For this reason, we cache the results of an API
-# call. Set this to the path you want cache files to be written to. Two files
-# will be written to this directory:
-#   - ansible-ec2.cache
-#   - ansible-ec2.index
-cache_path = ~/.ansible/tmp
-
-# The number of seconds a cache file is considered valid. After this many
-# seconds, a new API call will be made, and the cache file will be updated.
-# To disable the cache, set this value to 0
-cache_max_age = 300
-
-# Organize groups into a nested/hierarchy instead of a flat namespace.
-nested_groups = False
-
-# Replace - tags when creating groups to avoid issues with ansible
-replace_dash_in_groups = True
-
-# If set to true, any tag of the form "a,b,c" is expanded into a list
-# and the results are used to create additional tag_* inventory groups.
-expand_csv_tags = False
-
-# The EC2 inventory output can become very large. To manage its size,
-# configure which groups should be created.
-group_by_instance_id = True
-group_by_region = True
-group_by_availability_zone = True
-group_by_ami_id = True
-group_by_instance_type = True
-group_by_key_pair = True
-group_by_vpc_id = True
-group_by_security_group = True
-group_by_tag_keys = True
-group_by_tag_none = True
-group_by_route53_names = True
-group_by_rds_engine = False
-group_by_rds_parameter_group = False
-group_by_elasticache_engine = True
-group_by_elasticache_cluster = True
-group_by_elasticache_parameter_group = True
-group_by_elasticache_replication_group = True
-
-# If you only want to include hosts that match a certain regular expression
-# pattern_include = staging-*
-
-# If you want to exclude any hosts that match a certain regular expression
-# pattern_exclude = staging-*
-# Ansible EC2 external inventory script settings
-#
-
-##[ec2]
-##
-### to talk to a private eucalyptus instance uncomment these lines
-### and edit edit eucalyptus_host to be the host name of your cloud controller
-###eucalyptus = True
-###eucalyptus_host = clc.cloud.domain.org
-##
-### AWS regions to make calls to. Set this to 'all' to make request to all regions
-##
-### in AWS and merge the results together. Alternatively, set this to a comma
-### separated list of regions. E.g. 'us-east-1,us-west-1,us-west-2'
-##regions = all
-##regions_exclude = us-gov-west-1,cn-north-1
-##
-### When generating inventory, Ansible needs to know how to address a server.
-### Each EC2 instance has a lot of variables associated with it. Here is the list:
-###   http://docs.pythonboto.org/en/latest/ref/ec2.html#module-boto.ec2.instance
-### Below are 2 variables that are used as the address of a server:
-###   - destination_variable
-###   - vpc_destination_variable
-##
-### This is the normal destination variable to use. If you are running Ansible
-### from outside EC2, then 'public_dns_name' makes the most sense. If you are
-### running Ansible from within EC2, then perhaps you want to use the internal
-### address, and should set this to 'private_dns_name'. The key of an EC2 tag
-##...skipping...
-### pattern_include = staging-*
-##
-### If you want to exclude any hosts that match a certain regular expression
-### pattern_exclude = staging-*
-
-# Instance filters can be used to control which instances are retrieved for
-# inventory. For the full list of possible filters, please read the EC2 API
-# docs: http://docs.aws.amazon.com/AWSEC2/latest/APIReference/ApiReference-query-DescribeInstances.html#query-DescribeInstances-filters
-# Filters are key/value pairs separated by '=', to list multiple filters use
-# a list separated by commas. See examples below.
-
-# Retrieve only instances with (key=value) env=staging tag
-# instance_filters = tag:env=staging
-
-# Retrieve only instances with role=webservers OR role=dbservers tag
-# instance_filters = tag:role=webservers,tag:role=dbservers
-
-# Retrieve only t1.micro instances OR instances with tag env=staging
-# instance_filters = instance-type=t1.micro,tag:env=staging
-
-# You can use wildcards in filter values also. Below will list instances which
-# tag Name value matches webservers1*
-# (ex. webservers15, webservers1a, webservers123 etc)
-# instance_filters = tag:Name=webservers1*
-
-# A boto configuration profile may be used to separate out credentials
-# see http://boto.readthedocs.org/en/latest/boto_config_tut.html
-# boto_profile = some-boto-profile-name
diff --git a/baas-1601-dc1/ec2.py b/baas-1601-dc1/ec2.py
deleted file mode 100755
index f30958a..0000000
--- a/baas-1601-dc1/ec2.py
+++ /dev/null
@@ -1,1385 +0,0 @@
-#!/usr/bin/env python
-
-'''
-EC2 external inventory script
-=================================
-
-Generates inventory that Ansible can understand by making API request to
-AWS EC2 using the Boto library.
-
-NOTE: This script assumes Ansible is being executed where the environment
-variables needed for Boto have already been set:
-    export AWS_ACCESS_KEY_ID='AK123'
-    export AWS_SECRET_ACCESS_KEY='abc123'
-
-This script also assumes there is an ec2.ini file alongside it.  To specify a
-different path to ec2.ini, define the EC2_INI_PATH environment variable:
-
-    export EC2_INI_PATH=/path/to/my_ec2.ini
-
-If you're using eucalyptus you need to set the above variables and
-you need to define:
-
-    export EC2_URL=http://hostname_of_your_cc:port/services/Eucalyptus
-
-If you're using boto profiles (requires boto>=2.24.0) you can choose a profile
-using the --boto-profile command line argument (e.g. ec2.py --boto-profile prod) or using
-the AWS_PROFILE variable:
-
-    AWS_PROFILE=prod ansible-playbook -i ec2.py myplaybook.yml
-
-For more details, see: http://docs.pythonboto.org/en/latest/boto_config_tut.html
-
-When run against a specific host, this script returns the following variables:
- - ec2_ami_launch_index
- - ec2_architecture
- - ec2_association
- - ec2_attachTime
- - ec2_attachment
- - ec2_attachmentId
- - ec2_client_token
- - ec2_deleteOnTermination
- - ec2_description
- - ec2_deviceIndex
- - ec2_dns_name
- - ec2_eventsSet
- - ec2_group_name
- - ec2_hypervisor
- - ec2_id
- - ec2_image_id
- - ec2_instanceState
- - ec2_instance_type
- - ec2_ipOwnerId
- - ec2_ip_address
- - ec2_item
- - ec2_kernel
- - ec2_key_name
- - ec2_launch_time
- - ec2_monitored
- - ec2_monitoring
- - ec2_networkInterfaceId
- - ec2_ownerId
- - ec2_persistent
- - ec2_placement
- - ec2_platform
- - ec2_previous_state
- - ec2_private_dns_name
- - ec2_private_ip_address
- - ec2_publicIp
- - ec2_public_dns_name
- - ec2_ramdisk
- - ec2_reason
- - ec2_region
- - ec2_requester_id
- - ec2_root_device_name
- - ec2_root_device_type
- - ec2_security_group_ids
- - ec2_security_group_names
- - ec2_shutdown_state
- - ec2_sourceDestCheck
- - ec2_spot_instance_request_id
- - ec2_state
- - ec2_state_code
- - ec2_state_reason
- - ec2_status
- - ec2_subnet_id
- - ec2_tenancy
- - ec2_virtualization_type
- - ec2_vpc_id
-
-These variables are pulled out of a boto.ec2.instance object. There is a lack of
-consistency with variable spellings (camelCase and underscores) since this
-just loops through all variables the object exposes. It is preferred to use the
-ones with underscores when multiple exist.
-
-In addition, if an instance has AWS Tags associated with it, each tag is a new
-variable named:
- - ec2_tag_[Key] = [Value]
-
-Security groups are comma-separated in 'ec2_security_group_ids' and
-'ec2_security_group_names'.
-'''
-
-# (c) 2012, Peter Sankauskas
-#
-# This file is part of Ansible,
-#
-# Ansible is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# Ansible is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with Ansible.  If not, see <http://www.gnu.org/licenses/>.
-
-######################################################################
-
-import sys
-import os
-import argparse
-import re
-from time import time
-import boto
-from boto import ec2
-from boto import rds
-from boto import elasticache
-from boto import route53
-import six
-
-from six.moves import configparser
-from collections import defaultdict
-
-try:
-    import json
-except ImportError:
-    import simplejson as json
-
-
-class Ec2Inventory(object):
-
-    def _empty_inventory(self):
-        return {"_meta" : {"hostvars" : {}}}
-
-    def __init__(self):
-        ''' Main execution path '''
-
-        # Inventory grouped by instance IDs, tags, security groups, regions,
-        # and availability zones
-        self.inventory = self._empty_inventory()
-
-        # Index of hostname (address) to instance ID
-        self.index = {}
-
-        # Boto profile to use (if any)
-        self.boto_profile = None
-
-        # Read settings and parse CLI arguments
-        self.parse_cli_args()
-        self.read_settings()
-
-        # Make sure that profile_name is not passed at all if not set
-        # as pre 2.24 boto will fall over otherwise
-        if self.boto_profile:
-            if not hasattr(boto.ec2.EC2Connection, 'profile_name'):
-                self.fail_with_error("boto version must be >= 2.24 to use profile")
-
-        # Cache
-        if self.args.refresh_cache:
-            self.do_api_calls_update_cache()
-        elif not self.is_cache_valid():
-            self.do_api_calls_update_cache()
-
-        # Data to print
-        if self.args.host:
-            data_to_print = self.get_host_info()
-
-        elif self.args.list:
-            # Display list of instances for inventory
-            if self.inventory == self._empty_inventory():
-                data_to_print = self.get_inventory_from_cache()
-            else:
-                data_to_print = self.json_format_dict(self.inventory, True)
-
-        print(data_to_print)
-
-
-    def is_cache_valid(self):
-        ''' Determines if the cache files have expired, or if it is still valid '''
-
-        if os.path.isfile(self.cache_path_cache):
-            mod_time = os.path.getmtime(self.cache_path_cache)
-            current_time = time()
-            if (mod_time + self.cache_max_age) > current_time:
-                if os.path.isfile(self.cache_path_index):
-                    return True
-
-        return False
-
-
-    def read_settings(self):
-        ''' Reads the settings from the ec2.ini file '''
-        if six.PY3:
-            config = configparser.ConfigParser()
-        else:
-            config = configparser.SafeConfigParser()
-        ec2_default_ini_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'ec2.ini')
-        ec2_ini_path = os.path.expanduser(os.path.expandvars(os.environ.get('EC2_INI_PATH', ec2_default_ini_path)))
-        config.read(ec2_ini_path)
-
-        # is eucalyptus?
-        self.eucalyptus_host = None
-        self.eucalyptus = False
-        if config.has_option('ec2', 'eucalyptus'):
-            self.eucalyptus = config.getboolean('ec2', 'eucalyptus')
-        if self.eucalyptus and config.has_option('ec2', 'eucalyptus_host'):
-            self.eucalyptus_host = config.get('ec2', 'eucalyptus_host')
-
-        # Regions
-        self.regions = []
-        configRegions = config.get('ec2', 'regions')
-        configRegions_exclude = config.get('ec2', 'regions_exclude')
-        if (configRegions == 'all'):
-            if self.eucalyptus_host:
-                self.regions.append(boto.connect_euca(host=self.eucalyptus_host).region.name)
-            else:
-                for regionInfo in ec2.regions():
-                    if regionInfo.name not in configRegions_exclude:
-                        self.regions.append(regionInfo.name)
-        else:
-            self.regions = configRegions.split(",")
-
-        # Destination addresses
-        self.destination_variable = config.get('ec2', 'destination_variable')
-        self.vpc_destination_variable = config.get('ec2', 'vpc_destination_variable')
-
-        if config.has_option('ec2', 'hostname_variable'):
-            self.hostname_variable = config.get('ec2', 'hostname_variable')
-        else:
-            self.hostname_variable = None
-
-        if config.has_option('ec2', 'destination_format') and \
-                config.has_option('ec2', 'destination_format_tags'):
-            self.destination_format = config.get('ec2', 'destination_format')
-            self.destination_format_tags = config.get('ec2', 'destination_format_tags').split(',')
-        else:
-            self.destination_format = None
-            self.destination_format_tags = None
-
-        # Route53
-        self.route53_enabled = config.getboolean('ec2', 'route53')
-        self.route53_excluded_zones = []
-        if config.has_option('ec2', 'route53_excluded_zones'):
-            self.route53_excluded_zones.extend(
-                    config.get('ec2', 'route53_excluded_zones', '').split(','))
-
-        # Include RDS instances?
-        self.rds_enabled = True
-        if config.has_option('ec2', 'rds'):
-            self.rds_enabled = config.getboolean('ec2', 'rds')
-
-        # Include ElastiCache instances?
-        self.elasticache_enabled = True
-        if config.has_option('ec2', 'elasticache'):
-            self.elasticache_enabled = config.getboolean('ec2', 'elasticache')
-
-        # Return all EC2 instances?
-        if config.has_option('ec2', 'all_instances'):
-            self.all_instances = config.getboolean('ec2', 'all_instances')
-        else:
-            self.all_instances = False
-
-        # Instance states to be gathered in inventory. Default is 'running'.
-        # Setting 'all_instances' to 'yes' overrides this option.
-        ec2_valid_instance_states = [
-            'pending',
-            'running',
-            'shutting-down',
-            'terminated',
-            'stopping',
-            'stopped'
-        ]
-        self.ec2_instance_states = []
-        if self.all_instances:
-            self.ec2_instance_states = ec2_valid_instance_states
-        elif config.has_option('ec2', 'instance_states'):
-            for instance_state in config.get('ec2', 'instance_states').split(','):
-                instance_state = instance_state.strip()
-                if instance_state not in ec2_valid_instance_states:
-                    continue
-                self.ec2_instance_states.append(instance_state)
-        else:
-            self.ec2_instance_states = ['running']
-
-        # Return all RDS instances? (if RDS is enabled)
-        if config.has_option('ec2', 'all_rds_instances') and self.rds_enabled:
-            self.all_rds_instances = config.getboolean('ec2', 'all_rds_instances')
-        else:
-            self.all_rds_instances = False
-
-        # Return all ElastiCache replication groups? (if ElastiCache is enabled)
-        if config.has_option('ec2', 'all_elasticache_replication_groups') and self.elasticache_enabled:
-            self.all_elasticache_replication_groups = config.getboolean('ec2', 'all_elasticache_replication_groups')
-        else:
-            self.all_elasticache_replication_groups = False
-
-        # Return all ElastiCache clusters? (if ElastiCache is enabled)
-        if config.has_option('ec2', 'all_elasticache_clusters') and self.elasticache_enabled:
-            self.all_elasticache_clusters = config.getboolean('ec2', 'all_elasticache_clusters')
-        else:
-            self.all_elasticache_clusters = False
-
-        # Return all ElastiCache nodes? (if ElastiCache is enabled)
-        if config.has_option('ec2', 'all_elasticache_nodes') and self.elasticache_enabled:
-            self.all_elasticache_nodes = config.getboolean('ec2', 'all_elasticache_nodes')
-        else:
-            self.all_elasticache_nodes = False
-
-        # boto configuration profile (prefer CLI argument)
-        self.boto_profile = self.args.boto_profile
-        if config.has_option('ec2', 'boto_profile') and not self.boto_profile:
-            self.boto_profile = config.get('ec2', 'boto_profile')
-
-        # Cache related
-        cache_dir = os.path.expanduser(config.get('ec2', 'cache_path'))
-        if self.boto_profile:
-            cache_dir = os.path.join(cache_dir, 'profile_' + self.boto_profile)
-        if not os.path.exists(cache_dir):
-            os.makedirs(cache_dir)
-
-        cache_name = 'ansible-ec2'
-        aws_profile = lambda: (self.boto_profile or
-                               os.environ.get('AWS_PROFILE') or
-                               os.environ.get('AWS_ACCESS_KEY_ID'))
-        if aws_profile():
-            cache_name = '%s-%s' % (cache_name, aws_profile())
-        self.cache_path_cache = cache_dir + "/%s.cache" % cache_name
-        self.cache_path_index = cache_dir + "/%s.index" % cache_name
-        self.cache_max_age = config.getint('ec2', 'cache_max_age')
-
-        if config.has_option('ec2', 'expand_csv_tags'):
-            self.expand_csv_tags = config.getboolean('ec2', 'expand_csv_tags')
-        else:
-            self.expand_csv_tags = False
-
-        # Configure nested groups instead of flat namespace.
-        if config.has_option('ec2', 'nested_groups'):
-            self.nested_groups = config.getboolean('ec2', 'nested_groups')
-        else:
-            self.nested_groups = False
-
-        # Replace dash or not in group names
-        if config.has_option('ec2', 'replace_dash_in_groups'):
-            self.replace_dash_in_groups = config.getboolean('ec2', 'replace_dash_in_groups')
-        else:
-            self.replace_dash_in_groups = True
-
-        # Configure which groups should be created.
-        group_by_options = [
-            'group_by_instance_id',
-            'group_by_region',
-            'group_by_availability_zone',
-            'group_by_ami_id',
-            'group_by_instance_type',
-            'group_by_key_pair',
-            'group_by_vpc_id',
-            'group_by_security_group',
-            'group_by_tag_keys',
-            'group_by_tag_none',
-            'group_by_route53_names',
-            'group_by_rds_engine',
-            'group_by_rds_parameter_group',
-            'group_by_elasticache_engine',
-            'group_by_elasticache_cluster',
-            'group_by_elasticache_parameter_group',
-            'group_by_elasticache_replication_group',
-        ]
-        for option in group_by_options:
-            if config.has_option('ec2', option):
-                setattr(self, option, config.getboolean('ec2', option))
-            else:
-                setattr(self, option, True)
-
-        # Do we need to just include hosts that match a pattern?
-        try:
-            pattern_include = config.get('ec2', 'pattern_include')
-            if pattern_include and len(pattern_include) > 0:
-                self.pattern_include = re.compile(pattern_include)
-            else:
-                self.pattern_include = None
-        except configparser.NoOptionError:
-            self.pattern_include = None
-
-        # Do we need to exclude hosts that match a pattern?
-        try:
-            pattern_exclude = config.get('ec2', 'pattern_exclude');
-            if pattern_exclude and len(pattern_exclude) > 0:
-                self.pattern_exclude = re.compile(pattern_exclude)
-            else:
-                self.pattern_exclude = None
-        except configparser.NoOptionError:
-            self.pattern_exclude = None
-
-        # Instance filters (see boto and EC2 API docs). Ignore invalid filters.
-        self.ec2_instance_filters = defaultdict(list)
-        if config.has_option('ec2', 'instance_filters'):
-
-            filters = [f for f in config.get('ec2', 'instance_filters').split(',') if f]
-
-            for instance_filter in filters:
-                instance_filter = instance_filter.strip()
-                if not instance_filter or '=' not in instance_filter:
-                    continue
-                filter_key, filter_value = [x.strip() for x in instance_filter.split('=', 1)]
-                if not filter_key:
-                    continue
-                self.ec2_instance_filters[filter_key].append(filter_value)
-
-    def parse_cli_args(self):
-        ''' Command line argument processing '''
-
-        parser = argparse.ArgumentParser(description='Produce an Ansible Inventory file based on EC2')
-        parser.add_argument('--list', action='store_true', default=True,
-                            help='List instances (default: True)')
-        parser.add_argument('--host', action='store',
-                            help='Get all the variables about a specific instance')
-        parser.add_argument('--refresh-cache', action='store_true', default=False,
-                            help='Force refresh of cache by making API requests to EC2 (default: False - use cache files)')
-        parser.add_argument('--profile', '--boto-profile', action='store', dest='boto_profile',
-                            help='Use boto profile for connections to EC2')
-        self.args = parser.parse_args()
-
-
-    def do_api_calls_update_cache(self):
-        ''' Do API calls to each region, and save data in cache files '''
-
-        if self.route53_enabled:
-            self.get_route53_records()
-
-        for region in self.regions:
-            self.get_instances_by_region(region)
-            if self.rds_enabled:
-                self.get_rds_instances_by_region(region)
-            if self.elasticache_enabled:
-                self.get_elasticache_clusters_by_region(region)
-                self.get_elasticache_replication_groups_by_region(region)
-
-        self.write_to_cache(self.inventory, self.cache_path_cache)
-        self.write_to_cache(self.index, self.cache_path_index)
-
-    def connect(self, region):
-        ''' create connection to api server'''
-        if self.eucalyptus:
-            conn = boto.connect_euca(host=self.eucalyptus_host)
-            conn.APIVersion = '2010-08-31'
-        else:
-            conn = self.connect_to_aws(ec2, region)
-        return conn
-
-    def boto_fix_security_token_in_profile(self, connect_args):
-        ''' monkey patch for boto issue boto/boto#2100 '''
-        profile = 'profile ' + self.boto_profile
-        if boto.config.has_option(profile, 'aws_security_token'):
-            connect_args['security_token'] = boto.config.get(profile, 'aws_security_token')
-        return connect_args
-
-    def connect_to_aws(self, module, region):
-        connect_args = {}
-
-        # only pass the profile name if it's set (as it is not supported by older boto versions)
-        if self.boto_profile:
-            connect_args['profile_name'] = self.boto_profile
-            self.boto_fix_security_token_in_profile(connect_args)
-
-        conn = module.connect_to_region(region, **connect_args)
-        # connect_to_region will fail "silently" by returning None if the region name is wrong or not supported
-        if conn is None:
-            self.fail_with_error("region name: %s likely not supported, or AWS is down.  connection to region failed." % region)
-        return conn
-
-    def get_instances_by_region(self, region):
-        ''' Makes an AWS EC2 API call to the list of instances in a particular
-        region '''
-
-        try:
-            conn = self.connect(region)
-            reservations = []
-            if self.ec2_instance_filters:
-                for filter_key, filter_values in self.ec2_instance_filters.items():
-                    reservations.extend(conn.get_all_instances(filters = { filter_key : filter_values }))
-            else:
-                reservations = conn.get_all_instances()
-
-            for reservation in reservations:
-                for instance in reservation.instances:
-                    self.add_instance(instance, region)
-
-        except boto.exception.BotoServerError as e:
-            if e.error_code == 'AuthFailure':
-                error = self.get_auth_error_message()
-            else:
-                backend = 'Eucalyptus' if self.eucalyptus else 'AWS'
-                error = "Error connecting to %s backend.\n%s" % (backend, e.message)
-            self.fail_with_error(error, 'getting EC2 instances')
-
-    def get_rds_instances_by_region(self, region):
-        ''' Makes an AWS API call to the list of RDS instances in a particular
-        region '''
-
-        try:
-            conn = self.connect_to_aws(rds, region)
-            if conn:
-                marker = None
-                while True:
-                    instances = conn.get_all_dbinstances(marker=marker)
-                    marker = instances.marker
-                    for instance in instances:
-                        self.add_rds_instance(instance, region)
-                    if not marker:
-                        break
-        except boto.exception.BotoServerError as e:
-            error = e.reason
-
-            if e.error_code == 'AuthFailure':
-                error = self.get_auth_error_message()
-            if not e.reason == "Forbidden":
-                error = "Looks like AWS RDS is down:\n%s" % e.message
-            self.fail_with_error(error, 'getting RDS instances')
-
-    def get_elasticache_clusters_by_region(self, region):
-        ''' Makes an AWS API call to the list of ElastiCache clusters (with
-        nodes' info) in a particular region.'''
-
-        # ElastiCache boto module doesn't provide a get_all_intances method,
-        # that's why we need to call describe directly (it would be called by
-        # the shorthand method anyway...)
-        try:
-            conn = self.connect_to_aws(elasticache, region)
-            if conn:
-                # show_cache_node_info = True
-                # because we also want nodes' information
-                response = conn.describe_cache_clusters(None, None, None, True)
-
-        except boto.exception.BotoServerError as e:
-            error = e.reason
-
-            if e.error_code == 'AuthFailure':
-                error = self.get_auth_error_message()
-            if not e.reason == "Forbidden":
-                error = "Looks like AWS ElastiCache is down:\n%s" % e.message
-            self.fail_with_error(error, 'getting ElastiCache clusters')
-
-        try:
-            # Boto also doesn't provide wrapper classes to CacheClusters or
-            # CacheNodes. Because of that wo can't make use of the get_list
-            # method in the AWSQueryConnection. Let's do the work manually
-            clusters = response['DescribeCacheClustersResponse']['DescribeCacheClustersResult']['CacheClusters']
-
-        except KeyError as e:
-            error = "ElastiCache query to AWS failed (unexpected format)."
-            self.fail_with_error(error, 'getting ElastiCache clusters')
-
-        for cluster in clusters:
-            self.add_elasticache_cluster(cluster, region)
-
-    def get_elasticache_replication_groups_by_region(self, region):
-        ''' Makes an AWS API call to the list of ElastiCache replication groups
-        in a particular region.'''
-
-        # ElastiCache boto module doesn't provide a get_all_intances method,
-        # that's why we need to call describe directly (it would be called by
-        # the shorthand method anyway...)
-        try:
-            conn = self.connect_to_aws(elasticache, region)
-            if conn:
-                response = conn.describe_replication_groups()
-
-        except boto.exception.BotoServerError as e:
-            error = e.reason
-
-            if e.error_code == 'AuthFailure':
-                error = self.get_auth_error_message()
-            if not e.reason == "Forbidden":
-                error = "Looks like AWS ElastiCache [Replication Groups] is down:\n%s" % e.message
-            self.fail_with_error(error, 'getting ElastiCache clusters')
-
-        try:
-            # Boto also doesn't provide wrapper classes to ReplicationGroups
-            # Because of that wo can't make use of the get_list method in the
-            # AWSQueryConnection. Let's do the work manually
-            replication_groups = response['DescribeReplicationGroupsResponse']['DescribeReplicationGroupsResult']['ReplicationGroups']
-
-        except KeyError as e:
-            error = "ElastiCache [Replication Groups] query to AWS failed (unexpected format)."
-            self.fail_with_error(error, 'getting ElastiCache clusters')
-
-        for replication_group in replication_groups:
-            self.add_elasticache_replication_group(replication_group, region)
-
-    def get_auth_error_message(self):
-        ''' create an informative error message if there is an issue authenticating'''
-        errors = ["Authentication error retrieving ec2 inventory."]
-        if None in [os.environ.get('AWS_ACCESS_KEY_ID'), os.environ.get('AWS_SECRET_ACCESS_KEY')]:
-            errors.append(' - No AWS_ACCESS_KEY_ID or AWS_SECRET_ACCESS_KEY environment vars found')
-        else:
-            errors.append(' - AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY environment vars found but may not be correct')
-
-        boto_paths = ['/etc/boto.cfg', '~/.boto', '~/.aws/credentials']
-        boto_config_found = list(p for p in boto_paths if os.path.isfile(os.path.expanduser(p)))
-        if len(boto_config_found) > 0:
-            errors.append(" - Boto configs found at '%s', but the credentials contained may not be correct" % ', '.join(boto_config_found))
-        else:
-            errors.append(" - No Boto config found at any expected location '%s'" % ', '.join(boto_paths))
-
-        return '\n'.join(errors)
-
-    def fail_with_error(self, err_msg, err_operation=None):
-        '''log an error to std err for ansible-playbook to consume and exit'''
-        if err_operation:
-            err_msg = 'ERROR: "{err_msg}", while: {err_operation}'.format(
-                    err_msg=err_msg, err_operation=err_operation)
-        sys.stderr.write(err_msg)
-        sys.exit(1)
-
-    def get_instance(self, region, instance_id):
-        conn = self.connect(region)
-
-        reservations = conn.get_all_instances([instance_id])
-        for reservation in reservations:
-            for instance in reservation.instances:
-                return instance
-
-    def add_instance(self, instance, region):
-        ''' Adds an instance to the inventory and index, as long as it is
-        addressable '''
-
-        # Only return instances with desired instance states
-        if instance.state not in self.ec2_instance_states:
-            return
-
-        # Select the best destination address
-        if self.destination_format and self.destination_format_tags:
-            dest = self.destination_format.format(*[ getattr(instance, 'tags').get(tag, '') for tag in self.destination_format_tags ])
-        elif instance.subnet_id:
-            dest = getattr(instance, self.vpc_destination_variable, None)
-            if dest is None:
-                dest = getattr(instance, 'tags').get(self.vpc_destination_variable, None)
-        else:
-            dest = getattr(instance, self.destination_variable, None)
-            if dest is None:
-                dest = getattr(instance, 'tags').get(self.destination_variable, None)
-
-        if not dest:
-            # Skip instances we cannot address (e.g. private VPC subnet)
-            return
-
-        # Set the inventory name
-        hostname = None
-        if self.hostname_variable:
-            if self.hostname_variable.startswith('tag_'):
-                hostname = instance.tags.get(self.hostname_variable[4:], None)
-            else:
-                hostname = getattr(instance, self.hostname_variable)
-
-        # If we can't get a nice hostname, use the destination address
-        if not hostname:
-            hostname = dest
-        else:
-            hostname = self.to_safe(hostname).lower()
-
-        # if we only want to include hosts that match a pattern, skip those that don't
-        if self.pattern_include and not self.pattern_include.match(hostname):
-            return
-
-        # if we need to exclude hosts that match a pattern, skip those
-        if self.pattern_exclude and self.pattern_exclude.match(hostname):
-            return
-
-        # Add to index
-        self.index[hostname] = [region, instance.id]
-
-        # Inventory: Group by instance ID (always a group of 1)
-        if self.group_by_instance_id:
-            self.inventory[instance.id] = [hostname]
-            if self.nested_groups:
-                self.push_group(self.inventory, 'instances', instance.id)
-
-        # Inventory: Group by region
-        if self.group_by_region:
-            self.push(self.inventory, region, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'regions', region)
-
-        # Inventory: Group by availability zone
-        if self.group_by_availability_zone:
-            self.push(self.inventory, instance.placement, hostname)
-            if self.nested_groups:
-                if self.group_by_region:
-                    self.push_group(self.inventory, region, instance.placement)
-                self.push_group(self.inventory, 'zones', instance.placement)
-
-        # Inventory: Group by Amazon Machine Image (AMI) ID
-        if self.group_by_ami_id:
-            ami_id = self.to_safe(instance.image_id)
-            self.push(self.inventory, ami_id, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'images', ami_id)
-
-        # Inventory: Group by instance type
-        if self.group_by_instance_type:
-            type_name = self.to_safe('type_' + instance.instance_type)
-            self.push(self.inventory, type_name, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'types', type_name)
-
-        # Inventory: Group by key pair
-        if self.group_by_key_pair and instance.key_name:
-            key_name = self.to_safe('key_' + instance.key_name)
-            self.push(self.inventory, key_name, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'keys', key_name)
-
-        # Inventory: Group by VPC
-        if self.group_by_vpc_id and instance.vpc_id:
-            vpc_id_name = self.to_safe('vpc_id_' + instance.vpc_id)
-            self.push(self.inventory, vpc_id_name, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'vpcs', vpc_id_name)
-
-        # Inventory: Group by security group
-        if self.group_by_security_group:
-            try:
-                for group in instance.groups:
-                    key = self.to_safe("security_group_" + group.name)
-                    self.push(self.inventory, key, hostname)
-                    if self.nested_groups:
-                        self.push_group(self.inventory, 'security_groups', key)
-            except AttributeError:
-                self.fail_with_error('\n'.join(['Package boto seems a bit older.',
-                                                'Please upgrade boto >= 2.3.0.']))
-
-        # Inventory: Group by tag keys
-        if self.group_by_tag_keys:
-            for k, v in instance.tags.items():
-                if self.expand_csv_tags and v and ',' in v:
-                    values = map(lambda x: x.strip(), v.split(','))
-                else:
-                    values = [v]
-
-                for v in values:
-                    if v:
-                        key = self.to_safe("tag_" + k + "=" + v)
-                    else:
-                        key = self.to_safe("tag_" + k)
-                    self.push(self.inventory, key, hostname)
-                    if self.nested_groups:
-                        self.push_group(self.inventory, 'tags', self.to_safe("tag_" + k))
-                        if v:
-                            self.push_group(self.inventory, self.to_safe("tag_" + k), key)
-
-        # Inventory: Group by Route53 domain names if enabled
-        if self.route53_enabled and self.group_by_route53_names:
-            route53_names = self.get_instance_route53_names(instance)
-            for name in route53_names:
-                self.push(self.inventory, name, hostname)
-                if self.nested_groups:
-                    self.push_group(self.inventory, 'route53', name)
-
-        # Global Tag: instances without tags
-        if self.group_by_tag_none and len(instance.tags) == 0:
-            self.push(self.inventory, 'tag_none', hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'tags', 'tag_none')
-
-        # Global Tag: tag all EC2 instances
-        self.push(self.inventory, 'ec2', hostname)
-
-        self.inventory["_meta"]["hostvars"][hostname] = self.get_host_info_dict_from_instance(instance)
-        self.inventory["_meta"]["hostvars"][hostname]['ansible_ssh_host'] = dest
-
-
-    def add_rds_instance(self, instance, region):
-        ''' Adds an RDS instance to the inventory and index, as long as it is
-        addressable '''
-
-        # Only want available instances unless all_rds_instances is True
-        if not self.all_rds_instances and instance.status != 'available':
-            return
-
-        # Select the best destination address
-        dest = instance.endpoint[0]
-
-        if not dest:
-            # Skip instances we cannot address (e.g. private VPC subnet)
-            return
-
-        # Set the inventory name
-        hostname = None
-        if self.hostname_variable:
-            if self.hostname_variable.startswith('tag_'):
-                hostname = instance.tags.get(self.hostname_variable[4:], None)
-            else:
-                hostname = getattr(instance, self.hostname_variable)
-
-        # If we can't get a nice hostname, use the destination address
-        if not hostname:
-            hostname = dest
-
-        hostname = self.to_safe(hostname).lower()
-
-        # Add to index
-        self.index[hostname] = [region, instance.id]
-
-        # Inventory: Group by instance ID (always a group of 1)
-        if self.group_by_instance_id:
-            self.inventory[instance.id] = [hostname]
-            if self.nested_groups:
-                self.push_group(self.inventory, 'instances', instance.id)
-
-        # Inventory: Group by region
-        if self.group_by_region:
-            self.push(self.inventory, region, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'regions', region)
-
-        # Inventory: Group by availability zone
-        if self.group_by_availability_zone:
-            self.push(self.inventory, instance.availability_zone, hostname)
-            if self.nested_groups:
-                if self.group_by_region:
-                    self.push_group(self.inventory, region, instance.availability_zone)
-                self.push_group(self.inventory, 'zones', instance.availability_zone)
-
-        # Inventory: Group by instance type
-        if self.group_by_instance_type:
-            type_name = self.to_safe('type_' + instance.instance_class)
-            self.push(self.inventory, type_name, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'types', type_name)
-
-        # Inventory: Group by VPC
-        if self.group_by_vpc_id and instance.subnet_group and instance.subnet_group.vpc_id:
-            vpc_id_name = self.to_safe('vpc_id_' + instance.subnet_group.vpc_id)
-            self.push(self.inventory, vpc_id_name, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'vpcs', vpc_id_name)
-
-        # Inventory: Group by security group
-        if self.group_by_security_group:
-            try:
-                if instance.security_group:
-                    key = self.to_safe("security_group_" + instance.security_group.name)
-                    self.push(self.inventory, key, hostname)
-                    if self.nested_groups:
-                        self.push_group(self.inventory, 'security_groups', key)
-
-            except AttributeError:
-                self.fail_with_error('\n'.join(['Package boto seems a bit older.',
-                                                'Please upgrade boto >= 2.3.0.']))
-
-
-        # Inventory: Group by engine
-        if self.group_by_rds_engine:
-            self.push(self.inventory, self.to_safe("rds_" + instance.engine), hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'rds_engines', self.to_safe("rds_" + instance.engine))
-
-        # Inventory: Group by parameter group
-        if self.group_by_rds_parameter_group:
-            self.push(self.inventory, self.to_safe("rds_parameter_group_" + instance.parameter_group.name), hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'rds_parameter_groups', self.to_safe("rds_parameter_group_" + instance.parameter_group.name))
-
-        # Global Tag: all RDS instances
-        self.push(self.inventory, 'rds', hostname)
-
-        self.inventory["_meta"]["hostvars"][hostname] = self.get_host_info_dict_from_instance(instance)
-        self.inventory["_meta"]["hostvars"][hostname]['ansible_ssh_host'] = dest
-
-    def add_elasticache_cluster(self, cluster, region):
-        ''' Adds an ElastiCache cluster to the inventory and index, as long as
-        it's nodes are addressable '''
-
-        # Only want available clusters unless all_elasticache_clusters is True
-        if not self.all_elasticache_clusters and cluster['CacheClusterStatus'] != 'available':
-            return
-
-        # Select the best destination address
-        if 'ConfigurationEndpoint' in cluster and cluster['ConfigurationEndpoint']:
-            # Memcached cluster
-            dest = cluster['ConfigurationEndpoint']['Address']
-            is_redis = False
-        else:
-            # Redis sigle node cluster
-            # Because all Redis clusters are single nodes, we'll merge the
-            # info from the cluster with info about the node
-            dest = cluster['CacheNodes'][0]['Endpoint']['Address']
-            is_redis = True
-
-        if not dest:
-            # Skip clusters we cannot address (e.g. private VPC subnet)
-            return
-
-        # Add to index
-        self.index[dest] = [region, cluster['CacheClusterId']]
-
-        # Inventory: Group by instance ID (always a group of 1)
-        if self.group_by_instance_id:
-            self.inventory[cluster['CacheClusterId']] = [dest]
-            if self.nested_groups:
-                self.push_group(self.inventory, 'instances', cluster['CacheClusterId'])
-
-        # Inventory: Group by region
-        if self.group_by_region and not is_redis:
-            self.push(self.inventory, region, dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'regions', region)
-
-        # Inventory: Group by availability zone
-        if self.group_by_availability_zone and not is_redis:
-            self.push(self.inventory, cluster['PreferredAvailabilityZone'], dest)
-            if self.nested_groups:
-                if self.group_by_region:
-                    self.push_group(self.inventory, region, cluster['PreferredAvailabilityZone'])
-                self.push_group(self.inventory, 'zones', cluster['PreferredAvailabilityZone'])
-
-        # Inventory: Group by node type
-        if self.group_by_instance_type and not is_redis:
-            type_name = self.to_safe('type_' + cluster['CacheNodeType'])
-            self.push(self.inventory, type_name, dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'types', type_name)
-
-        # Inventory: Group by VPC (information not available in the current
-        # AWS API version for ElastiCache)
-
-        # Inventory: Group by security group
-        if self.group_by_security_group and not is_redis:
-
-            # Check for the existence of the 'SecurityGroups' key and also if
-            # this key has some value. When the cluster is not placed in a SG
-            # the query can return None here and cause an error.
-            if 'SecurityGroups' in cluster and cluster['SecurityGroups'] is not None:
-                for security_group in cluster['SecurityGroups']:
-                    key = self.to_safe("security_group_" + security_group['SecurityGroupId'])
-                    self.push(self.inventory, key, dest)
-                    if self.nested_groups:
-                        self.push_group(self.inventory, 'security_groups', key)
-
-        # Inventory: Group by engine
-        if self.group_by_elasticache_engine and not is_redis:
-            self.push(self.inventory, self.to_safe("elasticache_" + cluster['Engine']), dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'elasticache_engines', self.to_safe(cluster['Engine']))
-
-        # Inventory: Group by parameter group
-        if self.group_by_elasticache_parameter_group:
-            self.push(self.inventory, self.to_safe("elasticache_parameter_group_" + cluster['CacheParameterGroup']['CacheParameterGroupName']), dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'elasticache_parameter_groups', self.to_safe(cluster['CacheParameterGroup']['CacheParameterGroupName']))
-
-        # Inventory: Group by replication group
-        if self.group_by_elasticache_replication_group and 'ReplicationGroupId' in cluster and cluster['ReplicationGroupId']:
-            self.push(self.inventory, self.to_safe("elasticache_replication_group_" + cluster['ReplicationGroupId']), dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'elasticache_replication_groups', self.to_safe(cluster['ReplicationGroupId']))
-
-        # Global Tag: all ElastiCache clusters
-        self.push(self.inventory, 'elasticache_clusters', cluster['CacheClusterId'])
-
-        host_info = self.get_host_info_dict_from_describe_dict(cluster)
-
-        self.inventory["_meta"]["hostvars"][dest] = host_info
-
-        # Add the nodes
-        for node in cluster['CacheNodes']:
-            self.add_elasticache_node(node, cluster, region)
-
-    def add_elasticache_node(self, node, cluster, region):
-        ''' Adds an ElastiCache node to the inventory and index, as long as
-        it is addressable '''
-
-        # Only want available nodes unless all_elasticache_nodes is True
-        if not self.all_elasticache_nodes and node['CacheNodeStatus'] != 'available':
-            return
-
-        # Select the best destination address
-        dest = node['Endpoint']['Address']
-
-        if not dest:
-            # Skip nodes we cannot address (e.g. private VPC subnet)
-            return
-
-        node_id = self.to_safe(cluster['CacheClusterId'] + '_' + node['CacheNodeId'])
-
-        # Add to index
-        self.index[dest] = [region, node_id]
-
-        # Inventory: Group by node ID (always a group of 1)
-        if self.group_by_instance_id:
-            self.inventory[node_id] = [dest]
-            if self.nested_groups:
-                self.push_group(self.inventory, 'instances', node_id)
-
-        # Inventory: Group by region
-        if self.group_by_region:
-            self.push(self.inventory, region, dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'regions', region)
-
-        # Inventory: Group by availability zone
-        if self.group_by_availability_zone:
-            self.push(self.inventory, cluster['PreferredAvailabilityZone'], dest)
-            if self.nested_groups:
-                if self.group_by_region:
-                    self.push_group(self.inventory, region, cluster['PreferredAvailabilityZone'])
-                self.push_group(self.inventory, 'zones', cluster['PreferredAvailabilityZone'])
-
-        # Inventory: Group by node type
-        if self.group_by_instance_type:
-            type_name = self.to_safe('type_' + cluster['CacheNodeType'])
-            self.push(self.inventory, type_name, dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'types', type_name)
-
-        # Inventory: Group by VPC (information not available in the current
-        # AWS API version for ElastiCache)
-
-        # Inventory: Group by security group
-        if self.group_by_security_group:
-
-            # Check for the existence of the 'SecurityGroups' key and also if
-            # this key has some value. When the cluster is not placed in a SG
-            # the query can return None here and cause an error.
-            if 'SecurityGroups' in cluster and cluster['SecurityGroups'] is not None:
-                for security_group in cluster['SecurityGroups']:
-                    key = self.to_safe("security_group_" + security_group['SecurityGroupId'])
-                    self.push(self.inventory, key, dest)
-                    if self.nested_groups:
-                        self.push_group(self.inventory, 'security_groups', key)
-
-        # Inventory: Group by engine
-        if self.group_by_elasticache_engine:
-            self.push(self.inventory, self.to_safe("elasticache_" + cluster['Engine']), dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'elasticache_engines', self.to_safe("elasticache_" + cluster['Engine']))
-
-        # Inventory: Group by parameter group (done at cluster level)
-
-        # Inventory: Group by replication group (done at cluster level)
-
-        # Inventory: Group by ElastiCache Cluster
-        if self.group_by_elasticache_cluster:
-            self.push(self.inventory, self.to_safe("elasticache_cluster_" + cluster['CacheClusterId']), dest)
-
-        # Global Tag: all ElastiCache nodes
-        self.push(self.inventory, 'elasticache_nodes', dest)
-
-        host_info = self.get_host_info_dict_from_describe_dict(node)
-
-        if dest in self.inventory["_meta"]["hostvars"]:
-            self.inventory["_meta"]["hostvars"][dest].update(host_info)
-        else:
-            self.inventory["_meta"]["hostvars"][dest] = host_info
-
-    def add_elasticache_replication_group(self, replication_group, region):
-        ''' Adds an ElastiCache replication group to the inventory and index '''
-
-        # Only want available clusters unless all_elasticache_replication_groups is True
-        if not self.all_elasticache_replication_groups and replication_group['Status'] != 'available':
-            return
-
-        # Select the best destination address (PrimaryEndpoint)
-        dest = replication_group['NodeGroups'][0]['PrimaryEndpoint']['Address']
-
-        if not dest:
-            # Skip clusters we cannot address (e.g. private VPC subnet)
-            return
-
-        # Add to index
-        self.index[dest] = [region, replication_group['ReplicationGroupId']]
-
-        # Inventory: Group by ID (always a group of 1)
-        if self.group_by_instance_id:
-            self.inventory[replication_group['ReplicationGroupId']] = [dest]
-            if self.nested_groups:
-                self.push_group(self.inventory, 'instances', replication_group['ReplicationGroupId'])
-
-        # Inventory: Group by region
-        if self.group_by_region:
-            self.push(self.inventory, region, dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'regions', region)
-
-        # Inventory: Group by availability zone (doesn't apply to replication groups)
-
-        # Inventory: Group by node type (doesn't apply to replication groups)
-
-        # Inventory: Group by VPC (information not available in the current
-        # AWS API version for replication groups
-
-        # Inventory: Group by security group (doesn't apply to replication groups)
-        # Check this value in cluster level
-
-        # Inventory: Group by engine (replication groups are always Redis)
-        if self.group_by_elasticache_engine:
-            self.push(self.inventory, 'elasticache_redis', dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'elasticache_engines', 'redis')
-
-        # Global Tag: all ElastiCache clusters
-        self.push(self.inventory, 'elasticache_replication_groups', replication_group['ReplicationGroupId'])
-
-        host_info = self.get_host_info_dict_from_describe_dict(replication_group)
-
-        self.inventory["_meta"]["hostvars"][dest] = host_info
-
-    def get_route53_records(self):
-        ''' Get and store the map of resource records to domain names that
-        point to them. '''
-
-        r53_conn = route53.Route53Connection()
-        all_zones = r53_conn.get_zones()
-
-        route53_zones = [ zone for zone in all_zones if zone.name[:-1]
-                          not in self.route53_excluded_zones ]
-
-        self.route53_records = {}
-
-        for zone in route53_zones:
-            rrsets = r53_conn.get_all_rrsets(zone.id)
-
-            for record_set in rrsets:
-                record_name = record_set.name
-
-                if record_name.endswith('.'):
-                    record_name = record_name[:-1]
-
-                for resource in record_set.resource_records:
-                    self.route53_records.setdefault(resource, set())
-                    self.route53_records[resource].add(record_name)
-
-
-    def get_instance_route53_names(self, instance):
-        ''' Check if an instance is referenced in the records we have from
-        Route53. If it is, return the list of domain names pointing to said
-        instance. If nothing points to it, return an empty list. '''
-
-        instance_attributes = [ 'public_dns_name', 'private_dns_name',
-                                'ip_address', 'private_ip_address' ]
-
-        name_list = set()
-
-        for attrib in instance_attributes:
-            try:
-                value = getattr(instance, attrib)
-            except AttributeError:
-                continue
-
-            if value in self.route53_records:
-                name_list.update(self.route53_records[value])
-
-        return list(name_list)
-
-    def get_host_info_dict_from_instance(self, instance):
-        instance_vars = {}
-        for key in vars(instance):
-            value = getattr(instance, key)
-            key = self.to_safe('ec2_' + key)
-
-            # Handle complex types
-            # state/previous_state changed to properties in boto in https://github.com/boto/boto/commit/a23c379837f698212252720d2af8dec0325c9518
-            if key == 'ec2__state':
-                instance_vars['ec2_state'] = instance.state or ''
-                instance_vars['ec2_state_code'] = instance.state_code
-            elif key == 'ec2__previous_state':
-                instance_vars['ec2_previous_state'] = instance.previous_state or ''
-                instance_vars['ec2_previous_state_code'] = instance.previous_state_code
-            elif type(value) in [int, bool]:
-                instance_vars[key] = value
-            elif isinstance(value, six.string_types):
-                instance_vars[key] = value.strip()
-            elif type(value) == type(None):
-                instance_vars[key] = ''
-            elif key == 'ec2_region':
-                instance_vars[key] = value.name
-            elif key == 'ec2__placement':
-                instance_vars['ec2_placement'] = value.zone
-            elif key == 'ec2_tags':
-                for k, v in value.items():
-                    if self.expand_csv_tags and ',' in v:
-                        v = map(lambda x: x.strip(), v.split(','))
-                    key = self.to_safe('ec2_tag_' + k)
-                    instance_vars[key] = v
-            elif key == 'ec2_groups':
-                group_ids = []
-                group_names = []
-                for group in value:
-                    group_ids.append(group.id)
-                    group_names.append(group.name)
-                instance_vars["ec2_security_group_ids"] = ','.join([str(i) for i in group_ids])
-                instance_vars["ec2_security_group_names"] = ','.join([str(i) for i in group_names])
-            else:
-                pass
-                # TODO Product codes if someone finds them useful
-                #print key
-                #print type(value)
-                #print value
-
-        return instance_vars
-
-    def get_host_info_dict_from_describe_dict(self, describe_dict):
-        ''' Parses the dictionary returned by the API call into a flat list
-            of parameters. This method should be used only when 'describe' is
-            used directly because Boto doesn't provide specific classes. '''
-
-        # I really don't agree with prefixing everything with 'ec2'
-        # because EC2, RDS and ElastiCache are different services.
-        # I'm just following the pattern used until now to not break any
-        # compatibility.
-
-        host_info = {}
-        for key in describe_dict:
-            value = describe_dict[key]
-            key = self.to_safe('ec2_' + self.uncammelize(key))
-
-            # Handle complex types
-
-            # Target: Memcached Cache Clusters
-            if key == 'ec2_configuration_endpoint' and value:
-                host_info['ec2_configuration_endpoint_address'] = value['Address']
-                host_info['ec2_configuration_endpoint_port'] = value['Port']
-
-            # Target: Cache Nodes and Redis Cache Clusters (single node)
-            if key == 'ec2_endpoint' and value:
-                host_info['ec2_endpoint_address'] = value['Address']
-                host_info['ec2_endpoint_port'] = value['Port']
-
-            # Target: Redis Replication Groups
-            if key == 'ec2_node_groups' and value:
-                host_info['ec2_endpoint_address'] = value[0]['PrimaryEndpoint']['Address']
-                host_info['ec2_endpoint_port'] = value[0]['PrimaryEndpoint']['Port']
-                replica_count = 0
-                for node in value[0]['NodeGroupMembers']:
-                    if node['CurrentRole'] == 'primary':
-                        host_info['ec2_primary_cluster_address'] = node['ReadEndpoint']['Address']
-                        host_info['ec2_primary_cluster_port'] = node['ReadEndpoint']['Port']
-                        host_info['ec2_primary_cluster_id'] = node['CacheClusterId']
-                    elif node['CurrentRole'] == 'replica':
-                        host_info['ec2_replica_cluster_address_'+ str(replica_count)] = node['ReadEndpoint']['Address']
-                        host_info['ec2_replica_cluster_port_'+ str(replica_count)] = node['ReadEndpoint']['Port']
-                        host_info['ec2_replica_cluster_id_'+ str(replica_count)] = node['CacheClusterId']
-                        replica_count += 1
-
-            # Target: Redis Replication Groups
-            if key == 'ec2_member_clusters' and value:
-                host_info['ec2_member_clusters'] = ','.join([str(i) for i in value])
-
-            # Target: All Cache Clusters
-            elif key == 'ec2_cache_parameter_group':
-                host_info["ec2_cache_node_ids_to_reboot"] = ','.join([str(i) for i in value['CacheNodeIdsToReboot']])
-                host_info['ec2_cache_parameter_group_name'] = value['CacheParameterGroupName']
-                host_info['ec2_cache_parameter_apply_status'] = value['ParameterApplyStatus']
-
-            # Target: Almost everything
-            elif key == 'ec2_security_groups':
-
-                # Skip if SecurityGroups is None
-                # (it is possible to have the key defined but no value in it).
-                if value is not None:
-                    sg_ids = []
-                    for sg in value:
-                        sg_ids.append(sg['SecurityGroupId'])
-                    host_info["ec2_security_group_ids"] = ','.join([str(i) for i in sg_ids])
-
-            # Target: Everything
-            # Preserve booleans and integers
-            elif type(value) in [int, bool]:
-                host_info[key] = value
-
-            # Target: Everything
-            # Sanitize string values
-            elif isinstance(value, six.string_types):
-                host_info[key] = value.strip()
-
-            # Target: Everything
-            # Replace None by an empty string
-            elif type(value) == type(None):
-                host_info[key] = ''
-
-            else:
-                # Remove non-processed complex types
-                pass
-
-        return host_info
-
-    def get_host_info(self):
-        ''' Get variables about a specific host '''
-
-        if len(self.index) == 0:
-            # Need to load index from cache
-            self.load_index_from_cache()
-
-        if not self.args.host in self.index:
-            # try updating the cache
-            self.do_api_calls_update_cache()
-            if not self.args.host in self.index:
-                # host might not exist anymore
-                return self.json_format_dict({}, True)
-
-        (region, instance_id) = self.index[self.args.host]
-
-        instance = self.get_instance(region, instance_id)
-        return self.json_format_dict(self.get_host_info_dict_from_instance(instance), True)
-
-    def push(self, my_dict, key, element):
-        ''' Push an element onto an array that may not have been defined in
-        the dict '''
-        group_info = my_dict.setdefault(key, [])
-        if isinstance(group_info, dict):
-            host_list = group_info.setdefault('hosts', [])
-            host_list.append(element)
-        else:
-            group_info.append(element)
-
-    def push_group(self, my_dict, key, element):
-        ''' Push a group as a child of another group. '''
-        parent_group = my_dict.setdefault(key, {})
-        if not isinstance(parent_group, dict):
-            parent_group = my_dict[key] = {'hosts': parent_group}
-        child_groups = parent_group.setdefault('children', [])
-        if element not in child_groups:
-            child_groups.append(element)
-
-    def get_inventory_from_cache(self):
-        ''' Reads the inventory from the cache file and returns it as a JSON
-        object '''
-
-        cache = open(self.cache_path_cache, 'r')
-        json_inventory = cache.read()
-        return json_inventory
-
-
-    def load_index_from_cache(self):
-        ''' Reads the index from the cache file sets self.index '''
-
-        cache = open(self.cache_path_index, 'r')
-        json_index = cache.read()
-        self.index = json.loads(json_index)
-
-
-    def write_to_cache(self, data, filename):
-        ''' Writes data in JSON format to a file '''
-
-        json_data = self.json_format_dict(data, True)
-        cache = open(filename, 'w')
-        cache.write(json_data)
-        cache.close()
-
-    def uncammelize(self, key):
-        temp = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', key)
-        return re.sub('([a-z0-9])([A-Z])', r'\1_\2', temp).lower()
-
-    def to_safe(self, word):
-        ''' Converts 'bad' characters in a string to underscores so they can be used as Ansible groups '''
-        regex = "[^A-Za-z0-9\_"
-        if not self.replace_dash_in_groups:
-            regex += "\-"
-        return re.sub(regex + "]", "_", word)
-
-    def json_format_dict(self, data, pretty=False):
-        ''' Converts a dict to a JSON object and dumps it as a formatted
-        string '''
-
-        if pretty:
-            return json.dumps(data, sort_keys=True, indent=2)
-        else:
-            return json.dumps(data)
-
-
-# Run the script
-Ec2Inventory()
diff --git a/baas-1601-dc1/inventory b/baas-1601-dc1/inventory
deleted file mode 100644
index 71009f3..0000000
--- a/baas-1601-dc1/inventory
+++ /dev/null
@@ -1,68 +0,0 @@
-[tag_Name_dc1_n0]
-[tag_Name_dc1_n1]
-[tag_Name_dc1_n2]
-[tag_Name_dc1_n3]
-[tag_Name_dc1_n4]
-[tag_Name_dc1_n5]
-[tag_Name_dc1_n6]
-[tag_Name_dc1_n7]
-[tag_Name_dc1_n8]
-[tag_Name_dc1_n9]
-[tag_Name_dc1_n10]
-
-[control:children]
-tag_Name_dc1_n0
-
-[planet:children]
-dc-1
-
-[dc-1:children]
-tag_Name_dc1_n1
-tag_Name_dc1_n2
-tag_Name_dc1_n3
-tag_Name_dc1_n4
-tag_Name_dc1_n5
-tag_Name_dc1_n6
-tag_Name_dc1_n7
-tag_Name_dc1_n8
-tag_Name_dc1_n9
-tag_Name_dc1_n10
-
-[elastic:children]
-dc-1-elastic
-
-[dc-1-elastic:children]
-tag_Name_dc1_n1
-tag_Name_dc1_n2
-tag_Name_dc1_n3
-
-[baas:children]
-dc-1-baas
-
-[dc-1-baas:children]
-tag_Name_dc1_n4
-tag_Name_dc1_n5
-tag_Name_dc1_n6
-
-[portal:children]
-dc-1-portal
-
-[dc-1-portal:children]
-tag_Name_dc1_n7
-
-[ds:children]
-dc-1-ds
-
-[dc-1-ds:children]
-dc-1-cassandra
-
-[cassandra:children]
-dc-1-cassandra
-
-[dc-1-cassandra:children]
-tag_Name_dc1_n8
-tag_Name_dc1_n9
-tag_Name_dc1_n10
-
-[dc-1-ms:children]
-tag_Name_dc1_n1
diff --git a/baas-1701-dc5-dc6/ec2.ini b/baas-1701-dc5-dc6/ec2.ini
deleted file mode 100644
index 36b3921..0000000
--- a/baas-1701-dc5-dc6/ec2.ini
+++ /dev/null
@@ -1,200 +0,0 @@
-# Ansible EC2 external inventory script settings
-#
-
-[ec2]
-
-# to talk to a private eucalyptus instance uncomment these lines
-# and edit edit eucalyptus_host to be the host name of your cloud controller
-#eucalyptus = True
-#eucalyptus_host = clc.cloud.domain.org
-
-# AWS regions to make calls to. Set this to 'all' to make request to all regions
-# in AWS and merge the results together. Alternatively, set this to a comma
-# separated list of regions. E.g. 'us-east-1,us-west-1,us-west-2'
-regions = all
-regions_exclude = us-gov-west-1,cn-north-1
-
-# When generating inventory, Ansible needs to know how to address a server.
-# Each EC2 instance has a lot of variables associated with it. Here is the list:
-#   http://docs.pythonboto.org/en/latest/ref/ec2.html#module-boto.ec2.instance
-# Below are 2 variables that are used as the address of a server:
-#   - destination_variable
-#   - vpc_destination_variable
-
-# This is the normal destination variable to use. If you are running Ansible
-# from outside EC2, then 'public_dns_name' makes the most sense. If you are
-# running Ansible from within EC2, then perhaps you want to use the internal
-# address, and should set this to 'private_dns_name'. The key of an EC2 tag
-# may optionally be used; however the boto instance variables hold precedence
-# in the event of a collision.
-destination_variable = public_dns_name
-
-# This allows you to override the inventory_name with an ec2 variable, instead
-# of using the destination_variable above. Addressing (aka ansible_ssh_host)
-# will still use destination_variable. Tags should be written as 'tag_TAGNAME'.
-#hostname_variable = tag_Name
-
-# For server inside a VPC, using DNS names may not make sense. When an instance
-# has 'subnet_id' set, this variable is used. If the subnet is public, setting
-# this to 'ip_address' will return the public IP address. For instances in a
-# private subnet, this should be set to 'private_ip_address', and Ansible must
-# be run from within EC2. The key of an EC2 tag may optionally be used; however
-# the boto instance variables hold precedence in the event of a collision.
-# WARNING: - instances that are in the private vpc, _without_ public ip address
-# will not be listed in the inventory until You set:
-# vpc_destination_variable = private_ip_address
-vpc_destination_variable = ip_address
-
-# The following two settings allow flexible ansible host naming based on a
-# python format string and a comma-separated list of ec2 tags.  Note that:
-#
-# 1) If the tags referenced are not present for some instances, empty strings
-#    will be substituted in the format string.
-# 2) This overrides both destination_variable and vpc_destination_variable.
-#
-#destination_format = {0}.{1}.example.com
-#destination_format_tags = Name,environment
-
-# To tag instances on EC2 with the resource records that point to them from
-# Route53, uncomment and set 'route53' to True.
-route53 = False
-
-# To exclude RDS instances from the inventory, uncomment and set to False.
-rds = False
-
-# To exclude ElastiCache instances from the inventory, uncomment and set to False.
-elasticache = False
-
-# Additionally, you can specify the list of zones to exclude looking up in
-# 'route53_excluded_zones' as a comma-separated list.
-# route53_excluded_zones = samplezone1.com, samplezone2.com
-
-# By default, only EC2 instances in the 'running' state are returned. Set
-# 'all_instances' to True to return all instances regardless of state.
-all_instances = True
-
-# By default, only EC2 instances in the 'running' state are returned. Specify
-# EC2 instance states to return as a comma-separated list. This
-# option is overriden when 'all_instances' is True.
-# instance_states = pending, running, shutting-down, terminated, stopping, stopped
-
-# By default, only RDS instances in the 'available' state are returned.  Set
-# 'all_rds_instances' to True return all RDS instances regardless of state.
-all_rds_instances = False
-
-# By default, only ElastiCache clusters and nodes in the 'available' state
-# are returned. Set 'all_elasticache_clusters' and/or 'all_elastic_nodes'
-# to True return all ElastiCache clusters and nodes, regardless of state.
-#
-# Note that all_elasticache_nodes only applies to listed clusters. That means
-# if you set all_elastic_clusters to false, no node will be return from
-# unavailable clusters, regardless of the state and to what you set for
-# all_elasticache_nodes.
-all_elasticache_replication_groups = False
-all_elasticache_clusters = False
-all_elasticache_nodes = False
-
-# API calls to EC2 are slow. For this reason, we cache the results of an API
-# call. Set this to the path you want cache files to be written to. Two files
-# will be written to this directory:
-#   - ansible-ec2.cache
-#   - ansible-ec2.index
-cache_path = ~/.ansible/tmp
-
-# The number of seconds a cache file is considered valid. After this many
-# seconds, a new API call will be made, and the cache file will be updated.
-# To disable the cache, set this value to 0
-cache_max_age = 300
-
-# Organize groups into a nested/hierarchy instead of a flat namespace.
-nested_groups = False
-
-# Replace - tags when creating groups to avoid issues with ansible
-replace_dash_in_groups = True
-
-# If set to true, any tag of the form "a,b,c" is expanded into a list
-# and the results are used to create additional tag_* inventory groups.
-expand_csv_tags = False
-
-# The EC2 inventory output can become very large. To manage its size,
-# configure which groups should be created.
-group_by_instance_id = True
-group_by_region = True
-group_by_availability_zone = True
-group_by_ami_id = True
-group_by_instance_type = True
-group_by_key_pair = True
-group_by_vpc_id = True
-group_by_security_group = True
-group_by_tag_keys = True
-group_by_tag_none = True
-group_by_route53_names = True
-group_by_rds_engine = False
-group_by_rds_parameter_group = False
-group_by_elasticache_engine = True
-group_by_elasticache_cluster = True
-group_by_elasticache_parameter_group = True
-group_by_elasticache_replication_group = True
-
-# If you only want to include hosts that match a certain regular expression
-# pattern_include = staging-*
-
-# If you want to exclude any hosts that match a certain regular expression
-# pattern_exclude = staging-*
-# Ansible EC2 external inventory script settings
-#
-
-##[ec2]
-##
-### to talk to a private eucalyptus instance uncomment these lines
-### and edit edit eucalyptus_host to be the host name of your cloud controller
-###eucalyptus = True
-###eucalyptus_host = clc.cloud.domain.org
-##
-### AWS regions to make calls to. Set this to 'all' to make request to all regions
-##
-### in AWS and merge the results together. Alternatively, set this to a comma
-### separated list of regions. E.g. 'us-east-1,us-west-1,us-west-2'
-##regions = all
-##regions_exclude = us-gov-west-1,cn-north-1
-##
-### When generating inventory, Ansible needs to know how to address a server.
-### Each EC2 instance has a lot of variables associated with it. Here is the list:
-###   http://docs.pythonboto.org/en/latest/ref/ec2.html#module-boto.ec2.instance
-### Below are 2 variables that are used as the address of a server:
-###   - destination_variable
-###   - vpc_destination_variable
-##
-### This is the normal destination variable to use. If you are running Ansible
-### from outside EC2, then 'public_dns_name' makes the most sense. If you are
-### running Ansible from within EC2, then perhaps you want to use the internal
-### address, and should set this to 'private_dns_name'. The key of an EC2 tag
-##...skipping...
-### pattern_include = staging-*
-##
-### If you want to exclude any hosts that match a certain regular expression
-### pattern_exclude = staging-*
-
-# Instance filters can be used to control which instances are retrieved for
-# inventory. For the full list of possible filters, please read the EC2 API
-# docs: http://docs.aws.amazon.com/AWSEC2/latest/APIReference/ApiReference-query-DescribeInstances.html#query-DescribeInstances-filters
-# Filters are key/value pairs separated by '=', to list multiple filters use
-# a list separated by commas. See examples below.
-
-# Retrieve only instances with (key=value) env=staging tag
-# instance_filters = tag:env=staging
-
-# Retrieve only instances with role=webservers OR role=dbservers tag
-# instance_filters = tag:role=webservers,tag:role=dbservers
-
-# Retrieve only t1.micro instances OR instances with tag env=staging
-# instance_filters = instance-type=t1.micro,tag:env=staging
-
-# You can use wildcards in filter values also. Below will list instances which
-# tag Name value matches webservers1*
-# (ex. webservers15, webservers1a, webservers123 etc)
-# instance_filters = tag:Name=webservers1*
-
-# A boto configuration profile may be used to separate out credentials
-# see http://boto.readthedocs.org/en/latest/boto_config_tut.html
-# boto_profile = some-boto-profile-name
diff --git a/baas-1701-dc5-dc6/ec2.py b/baas-1701-dc5-dc6/ec2.py
deleted file mode 100755
index f30958a..0000000
--- a/baas-1701-dc5-dc6/ec2.py
+++ /dev/null
@@ -1,1385 +0,0 @@
-#!/usr/bin/env python
-
-'''
-EC2 external inventory script
-=================================
-
-Generates inventory that Ansible can understand by making API request to
-AWS EC2 using the Boto library.
-
-NOTE: This script assumes Ansible is being executed where the environment
-variables needed for Boto have already been set:
-    export AWS_ACCESS_KEY_ID='AK123'
-    export AWS_SECRET_ACCESS_KEY='abc123'
-
-This script also assumes there is an ec2.ini file alongside it.  To specify a
-different path to ec2.ini, define the EC2_INI_PATH environment variable:
-
-    export EC2_INI_PATH=/path/to/my_ec2.ini
-
-If you're using eucalyptus you need to set the above variables and
-you need to define:
-
-    export EC2_URL=http://hostname_of_your_cc:port/services/Eucalyptus
-
-If you're using boto profiles (requires boto>=2.24.0) you can choose a profile
-using the --boto-profile command line argument (e.g. ec2.py --boto-profile prod) or using
-the AWS_PROFILE variable:
-
-    AWS_PROFILE=prod ansible-playbook -i ec2.py myplaybook.yml
-
-For more details, see: http://docs.pythonboto.org/en/latest/boto_config_tut.html
-
-When run against a specific host, this script returns the following variables:
- - ec2_ami_launch_index
- - ec2_architecture
- - ec2_association
- - ec2_attachTime
- - ec2_attachment
- - ec2_attachmentId
- - ec2_client_token
- - ec2_deleteOnTermination
- - ec2_description
- - ec2_deviceIndex
- - ec2_dns_name
- - ec2_eventsSet
- - ec2_group_name
- - ec2_hypervisor
- - ec2_id
- - ec2_image_id
- - ec2_instanceState
- - ec2_instance_type
- - ec2_ipOwnerId
- - ec2_ip_address
- - ec2_item
- - ec2_kernel
- - ec2_key_name
- - ec2_launch_time
- - ec2_monitored
- - ec2_monitoring
- - ec2_networkInterfaceId
- - ec2_ownerId
- - ec2_persistent
- - ec2_placement
- - ec2_platform
- - ec2_previous_state
- - ec2_private_dns_name
- - ec2_private_ip_address
- - ec2_publicIp
- - ec2_public_dns_name
- - ec2_ramdisk
- - ec2_reason
- - ec2_region
- - ec2_requester_id
- - ec2_root_device_name
- - ec2_root_device_type
- - ec2_security_group_ids
- - ec2_security_group_names
- - ec2_shutdown_state
- - ec2_sourceDestCheck
- - ec2_spot_instance_request_id
- - ec2_state
- - ec2_state_code
- - ec2_state_reason
- - ec2_status
- - ec2_subnet_id
- - ec2_tenancy
- - ec2_virtualization_type
- - ec2_vpc_id
-
-These variables are pulled out of a boto.ec2.instance object. There is a lack of
-consistency with variable spellings (camelCase and underscores) since this
-just loops through all variables the object exposes. It is preferred to use the
-ones with underscores when multiple exist.
-
-In addition, if an instance has AWS Tags associated with it, each tag is a new
-variable named:
- - ec2_tag_[Key] = [Value]
-
-Security groups are comma-separated in 'ec2_security_group_ids' and
-'ec2_security_group_names'.
-'''
-
-# (c) 2012, Peter Sankauskas
-#
-# This file is part of Ansible,
-#
-# Ansible is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# Ansible is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with Ansible.  If not, see <http://www.gnu.org/licenses/>.
-
-######################################################################
-
-import sys
-import os
-import argparse
-import re
-from time import time
-import boto
-from boto import ec2
-from boto import rds
-from boto import elasticache
-from boto import route53
-import six
-
-from six.moves import configparser
-from collections import defaultdict
-
-try:
-    import json
-except ImportError:
-    import simplejson as json
-
-
-class Ec2Inventory(object):
-
-    def _empty_inventory(self):
-        return {"_meta" : {"hostvars" : {}}}
-
-    def __init__(self):
-        ''' Main execution path '''
-
-        # Inventory grouped by instance IDs, tags, security groups, regions,
-        # and availability zones
-        self.inventory = self._empty_inventory()
-
-        # Index of hostname (address) to instance ID
-        self.index = {}
-
-        # Boto profile to use (if any)
-        self.boto_profile = None
-
-        # Read settings and parse CLI arguments
-        self.parse_cli_args()
-        self.read_settings()
-
-        # Make sure that profile_name is not passed at all if not set
-        # as pre 2.24 boto will fall over otherwise
-        if self.boto_profile:
-            if not hasattr(boto.ec2.EC2Connection, 'profile_name'):
-                self.fail_with_error("boto version must be >= 2.24 to use profile")
-
-        # Cache
-        if self.args.refresh_cache:
-            self.do_api_calls_update_cache()
-        elif not self.is_cache_valid():
-            self.do_api_calls_update_cache()
-
-        # Data to print
-        if self.args.host:
-            data_to_print = self.get_host_info()
-
-        elif self.args.list:
-            # Display list of instances for inventory
-            if self.inventory == self._empty_inventory():
-                data_to_print = self.get_inventory_from_cache()
-            else:
-                data_to_print = self.json_format_dict(self.inventory, True)
-
-        print(data_to_print)
-
-
-    def is_cache_valid(self):
-        ''' Determines if the cache files have expired, or if it is still valid '''
-
-        if os.path.isfile(self.cache_path_cache):
-            mod_time = os.path.getmtime(self.cache_path_cache)
-            current_time = time()
-            if (mod_time + self.cache_max_age) > current_time:
-                if os.path.isfile(self.cache_path_index):
-                    return True
-
-        return False
-
-
-    def read_settings(self):
-        ''' Reads the settings from the ec2.ini file '''
-        if six.PY3:
-            config = configparser.ConfigParser()
-        else:
-            config = configparser.SafeConfigParser()
-        ec2_default_ini_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'ec2.ini')
-        ec2_ini_path = os.path.expanduser(os.path.expandvars(os.environ.get('EC2_INI_PATH', ec2_default_ini_path)))
-        config.read(ec2_ini_path)
-
-        # is eucalyptus?
-        self.eucalyptus_host = None
-        self.eucalyptus = False
-        if config.has_option('ec2', 'eucalyptus'):
-            self.eucalyptus = config.getboolean('ec2', 'eucalyptus')
-        if self.eucalyptus and config.has_option('ec2', 'eucalyptus_host'):
-            self.eucalyptus_host = config.get('ec2', 'eucalyptus_host')
-
-        # Regions
-        self.regions = []
-        configRegions = config.get('ec2', 'regions')
-        configRegions_exclude = config.get('ec2', 'regions_exclude')
-        if (configRegions == 'all'):
-            if self.eucalyptus_host:
-                self.regions.append(boto.connect_euca(host=self.eucalyptus_host).region.name)
-            else:
-                for regionInfo in ec2.regions():
-                    if regionInfo.name not in configRegions_exclude:
-                        self.regions.append(regionInfo.name)
-        else:
-            self.regions = configRegions.split(",")
-
-        # Destination addresses
-        self.destination_variable = config.get('ec2', 'destination_variable')
-        self.vpc_destination_variable = config.get('ec2', 'vpc_destination_variable')
-
-        if config.has_option('ec2', 'hostname_variable'):
-            self.hostname_variable = config.get('ec2', 'hostname_variable')
-        else:
-            self.hostname_variable = None
-
-        if config.has_option('ec2', 'destination_format') and \
-                config.has_option('ec2', 'destination_format_tags'):
-            self.destination_format = config.get('ec2', 'destination_format')
-            self.destination_format_tags = config.get('ec2', 'destination_format_tags').split(',')
-        else:
-            self.destination_format = None
-            self.destination_format_tags = None
-
-        # Route53
-        self.route53_enabled = config.getboolean('ec2', 'route53')
-        self.route53_excluded_zones = []
-        if config.has_option('ec2', 'route53_excluded_zones'):
-            self.route53_excluded_zones.extend(
-                    config.get('ec2', 'route53_excluded_zones', '').split(','))
-
-        # Include RDS instances?
-        self.rds_enabled = True
-        if config.has_option('ec2', 'rds'):
-            self.rds_enabled = config.getboolean('ec2', 'rds')
-
-        # Include ElastiCache instances?
-        self.elasticache_enabled = True
-        if config.has_option('ec2', 'elasticache'):
-            self.elasticache_enabled = config.getboolean('ec2', 'elasticache')
-
-        # Return all EC2 instances?
-        if config.has_option('ec2', 'all_instances'):
-            self.all_instances = config.getboolean('ec2', 'all_instances')
-        else:
-            self.all_instances = False
-
-        # Instance states to be gathered in inventory. Default is 'running'.
-        # Setting 'all_instances' to 'yes' overrides this option.
-        ec2_valid_instance_states = [
-            'pending',
-            'running',
-            'shutting-down',
-            'terminated',
-            'stopping',
-            'stopped'
-        ]
-        self.ec2_instance_states = []
-        if self.all_instances:
-            self.ec2_instance_states = ec2_valid_instance_states
-        elif config.has_option('ec2', 'instance_states'):
-            for instance_state in config.get('ec2', 'instance_states').split(','):
-                instance_state = instance_state.strip()
-                if instance_state not in ec2_valid_instance_states:
-                    continue
-                self.ec2_instance_states.append(instance_state)
-        else:
-            self.ec2_instance_states = ['running']
-
-        # Return all RDS instances? (if RDS is enabled)
-        if config.has_option('ec2', 'all_rds_instances') and self.rds_enabled:
-            self.all_rds_instances = config.getboolean('ec2', 'all_rds_instances')
-        else:
-            self.all_rds_instances = False
-
-        # Return all ElastiCache replication groups? (if ElastiCache is enabled)
-        if config.has_option('ec2', 'all_elasticache_replication_groups') and self.elasticache_enabled:
-            self.all_elasticache_replication_groups = config.getboolean('ec2', 'all_elasticache_replication_groups')
-        else:
-            self.all_elasticache_replication_groups = False
-
-        # Return all ElastiCache clusters? (if ElastiCache is enabled)
-        if config.has_option('ec2', 'all_elasticache_clusters') and self.elasticache_enabled:
-            self.all_elasticache_clusters = config.getboolean('ec2', 'all_elasticache_clusters')
-        else:
-            self.all_elasticache_clusters = False
-
-        # Return all ElastiCache nodes? (if ElastiCache is enabled)
-        if config.has_option('ec2', 'all_elasticache_nodes') and self.elasticache_enabled:
-            self.all_elasticache_nodes = config.getboolean('ec2', 'all_elasticache_nodes')
-        else:
-            self.all_elasticache_nodes = False
-
-        # boto configuration profile (prefer CLI argument)
-        self.boto_profile = self.args.boto_profile
-        if config.has_option('ec2', 'boto_profile') and not self.boto_profile:
-            self.boto_profile = config.get('ec2', 'boto_profile')
-
-        # Cache related
-        cache_dir = os.path.expanduser(config.get('ec2', 'cache_path'))
-        if self.boto_profile:
-            cache_dir = os.path.join(cache_dir, 'profile_' + self.boto_profile)
-        if not os.path.exists(cache_dir):
-            os.makedirs(cache_dir)
-
-        cache_name = 'ansible-ec2'
-        aws_profile = lambda: (self.boto_profile or
-                               os.environ.get('AWS_PROFILE') or
-                               os.environ.get('AWS_ACCESS_KEY_ID'))
-        if aws_profile():
-            cache_name = '%s-%s' % (cache_name, aws_profile())
-        self.cache_path_cache = cache_dir + "/%s.cache" % cache_name
-        self.cache_path_index = cache_dir + "/%s.index" % cache_name
-        self.cache_max_age = config.getint('ec2', 'cache_max_age')
-
-        if config.has_option('ec2', 'expand_csv_tags'):
-            self.expand_csv_tags = config.getboolean('ec2', 'expand_csv_tags')
-        else:
-            self.expand_csv_tags = False
-
-        # Configure nested groups instead of flat namespace.
-        if config.has_option('ec2', 'nested_groups'):
-            self.nested_groups = config.getboolean('ec2', 'nested_groups')
-        else:
-            self.nested_groups = False
-
-        # Replace dash or not in group names
-        if config.has_option('ec2', 'replace_dash_in_groups'):
-            self.replace_dash_in_groups = config.getboolean('ec2', 'replace_dash_in_groups')
-        else:
-            self.replace_dash_in_groups = True
-
-        # Configure which groups should be created.
-        group_by_options = [
-            'group_by_instance_id',
-            'group_by_region',
-            'group_by_availability_zone',
-            'group_by_ami_id',
-            'group_by_instance_type',
-            'group_by_key_pair',
-            'group_by_vpc_id',
-            'group_by_security_group',
-            'group_by_tag_keys',
-            'group_by_tag_none',
-            'group_by_route53_names',
-            'group_by_rds_engine',
-            'group_by_rds_parameter_group',
-            'group_by_elasticache_engine',
-            'group_by_elasticache_cluster',
-            'group_by_elasticache_parameter_group',
-            'group_by_elasticache_replication_group',
-        ]
-        for option in group_by_options:
-            if config.has_option('ec2', option):
-                setattr(self, option, config.getboolean('ec2', option))
-            else:
-                setattr(self, option, True)
-
-        # Do we need to just include hosts that match a pattern?
-        try:
-            pattern_include = config.get('ec2', 'pattern_include')
-            if pattern_include and len(pattern_include) > 0:
-                self.pattern_include = re.compile(pattern_include)
-            else:
-                self.pattern_include = None
-        except configparser.NoOptionError:
-            self.pattern_include = None
-
-        # Do we need to exclude hosts that match a pattern?
-        try:
-            pattern_exclude = config.get('ec2', 'pattern_exclude');
-            if pattern_exclude and len(pattern_exclude) > 0:
-                self.pattern_exclude = re.compile(pattern_exclude)
-            else:
-                self.pattern_exclude = None
-        except configparser.NoOptionError:
-            self.pattern_exclude = None
-
-        # Instance filters (see boto and EC2 API docs). Ignore invalid filters.
-        self.ec2_instance_filters = defaultdict(list)
-        if config.has_option('ec2', 'instance_filters'):
-
-            filters = [f for f in config.get('ec2', 'instance_filters').split(',') if f]
-
-            for instance_filter in filters:
-                instance_filter = instance_filter.strip()
-                if not instance_filter or '=' not in instance_filter:
-                    continue
-                filter_key, filter_value = [x.strip() for x in instance_filter.split('=', 1)]
-                if not filter_key:
-                    continue
-                self.ec2_instance_filters[filter_key].append(filter_value)
-
-    def parse_cli_args(self):
-        ''' Command line argument processing '''
-
-        parser = argparse.ArgumentParser(description='Produce an Ansible Inventory file based on EC2')
-        parser.add_argument('--list', action='store_true', default=True,
-                            help='List instances (default: True)')
-        parser.add_argument('--host', action='store',
-                            help='Get all the variables about a specific instance')
-        parser.add_argument('--refresh-cache', action='store_true', default=False,
-                            help='Force refresh of cache by making API requests to EC2 (default: False - use cache files)')
-        parser.add_argument('--profile', '--boto-profile', action='store', dest='boto_profile',
-                            help='Use boto profile for connections to EC2')
-        self.args = parser.parse_args()
-
-
-    def do_api_calls_update_cache(self):
-        ''' Do API calls to each region, and save data in cache files '''
-
-        if self.route53_enabled:
-            self.get_route53_records()
-
-        for region in self.regions:
-            self.get_instances_by_region(region)
-            if self.rds_enabled:
-                self.get_rds_instances_by_region(region)
-            if self.elasticache_enabled:
-                self.get_elasticache_clusters_by_region(region)
-                self.get_elasticache_replication_groups_by_region(region)
-
-        self.write_to_cache(self.inventory, self.cache_path_cache)
-        self.write_to_cache(self.index, self.cache_path_index)
-
-    def connect(self, region):
-        ''' create connection to api server'''
-        if self.eucalyptus:
-            conn = boto.connect_euca(host=self.eucalyptus_host)
-            conn.APIVersion = '2010-08-31'
-        else:
-            conn = self.connect_to_aws(ec2, region)
-        return conn
-
-    def boto_fix_security_token_in_profile(self, connect_args):
-        ''' monkey patch for boto issue boto/boto#2100 '''
-        profile = 'profile ' + self.boto_profile
-        if boto.config.has_option(profile, 'aws_security_token'):
-            connect_args['security_token'] = boto.config.get(profile, 'aws_security_token')
-        return connect_args
-
-    def connect_to_aws(self, module, region):
-        connect_args = {}
-
-        # only pass the profile name if it's set (as it is not supported by older boto versions)
-        if self.boto_profile:
-            connect_args['profile_name'] = self.boto_profile
-            self.boto_fix_security_token_in_profile(connect_args)
-
-        conn = module.connect_to_region(region, **connect_args)
-        # connect_to_region will fail "silently" by returning None if the region name is wrong or not supported
-        if conn is None:
-            self.fail_with_error("region name: %s likely not supported, or AWS is down.  connection to region failed." % region)
-        return conn
-
-    def get_instances_by_region(self, region):
-        ''' Makes an AWS EC2 API call to the list of instances in a particular
-        region '''
-
-        try:
-            conn = self.connect(region)
-            reservations = []
-            if self.ec2_instance_filters:
-                for filter_key, filter_values in self.ec2_instance_filters.items():
-                    reservations.extend(conn.get_all_instances(filters = { filter_key : filter_values }))
-            else:
-                reservations = conn.get_all_instances()
-
-            for reservation in reservations:
-                for instance in reservation.instances:
-                    self.add_instance(instance, region)
-
-        except boto.exception.BotoServerError as e:
-            if e.error_code == 'AuthFailure':
-                error = self.get_auth_error_message()
-            else:
-                backend = 'Eucalyptus' if self.eucalyptus else 'AWS'
-                error = "Error connecting to %s backend.\n%s" % (backend, e.message)
-            self.fail_with_error(error, 'getting EC2 instances')
-
-    def get_rds_instances_by_region(self, region):
-        ''' Makes an AWS API call to the list of RDS instances in a particular
-        region '''
-
-        try:
-            conn = self.connect_to_aws(rds, region)
-            if conn:
-                marker = None
-                while True:
-                    instances = conn.get_all_dbinstances(marker=marker)
-                    marker = instances.marker
-                    for instance in instances:
-                        self.add_rds_instance(instance, region)
-                    if not marker:
-                        break
-        except boto.exception.BotoServerError as e:
-            error = e.reason
-
-            if e.error_code == 'AuthFailure':
-                error = self.get_auth_error_message()
-            if not e.reason == "Forbidden":
-                error = "Looks like AWS RDS is down:\n%s" % e.message
-            self.fail_with_error(error, 'getting RDS instances')
-
-    def get_elasticache_clusters_by_region(self, region):
-        ''' Makes an AWS API call to the list of ElastiCache clusters (with
-        nodes' info) in a particular region.'''
-
-        # ElastiCache boto module doesn't provide a get_all_intances method,
-        # that's why we need to call describe directly (it would be called by
-        # the shorthand method anyway...)
-        try:
-            conn = self.connect_to_aws(elasticache, region)
-            if conn:
-                # show_cache_node_info = True
-                # because we also want nodes' information
-                response = conn.describe_cache_clusters(None, None, None, True)
-
-        except boto.exception.BotoServerError as e:
-            error = e.reason
-
-            if e.error_code == 'AuthFailure':
-                error = self.get_auth_error_message()
-            if not e.reason == "Forbidden":
-                error = "Looks like AWS ElastiCache is down:\n%s" % e.message
-            self.fail_with_error(error, 'getting ElastiCache clusters')
-
-        try:
-            # Boto also doesn't provide wrapper classes to CacheClusters or
-            # CacheNodes. Because of that wo can't make use of the get_list
-            # method in the AWSQueryConnection. Let's do the work manually
-            clusters = response['DescribeCacheClustersResponse']['DescribeCacheClustersResult']['CacheClusters']
-
-        except KeyError as e:
-            error = "ElastiCache query to AWS failed (unexpected format)."
-            self.fail_with_error(error, 'getting ElastiCache clusters')
-
-        for cluster in clusters:
-            self.add_elasticache_cluster(cluster, region)
-
-    def get_elasticache_replication_groups_by_region(self, region):
-        ''' Makes an AWS API call to the list of ElastiCache replication groups
-        in a particular region.'''
-
-        # ElastiCache boto module doesn't provide a get_all_intances method,
-        # that's why we need to call describe directly (it would be called by
-        # the shorthand method anyway...)
-        try:
-            conn = self.connect_to_aws(elasticache, region)
-            if conn:
-                response = conn.describe_replication_groups()
-
-        except boto.exception.BotoServerError as e:
-            error = e.reason
-
-            if e.error_code == 'AuthFailure':
-                error = self.get_auth_error_message()
-            if not e.reason == "Forbidden":
-                error = "Looks like AWS ElastiCache [Replication Groups] is down:\n%s" % e.message
-            self.fail_with_error(error, 'getting ElastiCache clusters')
-
-        try:
-            # Boto also doesn't provide wrapper classes to ReplicationGroups
-            # Because of that wo can't make use of the get_list method in the
-            # AWSQueryConnection. Let's do the work manually
-            replication_groups = response['DescribeReplicationGroupsResponse']['DescribeReplicationGroupsResult']['ReplicationGroups']
-
-        except KeyError as e:
-            error = "ElastiCache [Replication Groups] query to AWS failed (unexpected format)."
-            self.fail_with_error(error, 'getting ElastiCache clusters')
-
-        for replication_group in replication_groups:
-            self.add_elasticache_replication_group(replication_group, region)
-
-    def get_auth_error_message(self):
-        ''' create an informative error message if there is an issue authenticating'''
-        errors = ["Authentication error retrieving ec2 inventory."]
-        if None in [os.environ.get('AWS_ACCESS_KEY_ID'), os.environ.get('AWS_SECRET_ACCESS_KEY')]:
-            errors.append(' - No AWS_ACCESS_KEY_ID or AWS_SECRET_ACCESS_KEY environment vars found')
-        else:
-            errors.append(' - AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY environment vars found but may not be correct')
-
-        boto_paths = ['/etc/boto.cfg', '~/.boto', '~/.aws/credentials']
-        boto_config_found = list(p for p in boto_paths if os.path.isfile(os.path.expanduser(p)))
-        if len(boto_config_found) > 0:
-            errors.append(" - Boto configs found at '%s', but the credentials contained may not be correct" % ', '.join(boto_config_found))
-        else:
-            errors.append(" - No Boto config found at any expected location '%s'" % ', '.join(boto_paths))
-
-        return '\n'.join(errors)
-
-    def fail_with_error(self, err_msg, err_operation=None):
-        '''log an error to std err for ansible-playbook to consume and exit'''
-        if err_operation:
-            err_msg = 'ERROR: "{err_msg}", while: {err_operation}'.format(
-                    err_msg=err_msg, err_operation=err_operation)
-        sys.stderr.write(err_msg)
-        sys.exit(1)
-
-    def get_instance(self, region, instance_id):
-        conn = self.connect(region)
-
-        reservations = conn.get_all_instances([instance_id])
-        for reservation in reservations:
-            for instance in reservation.instances:
-                return instance
-
-    def add_instance(self, instance, region):
-        ''' Adds an instance to the inventory and index, as long as it is
-        addressable '''
-
-        # Only return instances with desired instance states
-        if instance.state not in self.ec2_instance_states:
-            return
-
-        # Select the best destination address
-        if self.destination_format and self.destination_format_tags:
-            dest = self.destination_format.format(*[ getattr(instance, 'tags').get(tag, '') for tag in self.destination_format_tags ])
-        elif instance.subnet_id:
-            dest = getattr(instance, self.vpc_destination_variable, None)
-            if dest is None:
-                dest = getattr(instance, 'tags').get(self.vpc_destination_variable, None)
-        else:
-            dest = getattr(instance, self.destination_variable, None)
-            if dest is None:
-                dest = getattr(instance, 'tags').get(self.destination_variable, None)
-
-        if not dest:
-            # Skip instances we cannot address (e.g. private VPC subnet)
-            return
-
-        # Set the inventory name
-        hostname = None
-        if self.hostname_variable:
-            if self.hostname_variable.startswith('tag_'):
-                hostname = instance.tags.get(self.hostname_variable[4:], None)
-            else:
-                hostname = getattr(instance, self.hostname_variable)
-
-        # If we can't get a nice hostname, use the destination address
-        if not hostname:
-            hostname = dest
-        else:
-            hostname = self.to_safe(hostname).lower()
-
-        # if we only want to include hosts that match a pattern, skip those that don't
-        if self.pattern_include and not self.pattern_include.match(hostname):
-            return
-
-        # if we need to exclude hosts that match a pattern, skip those
-        if self.pattern_exclude and self.pattern_exclude.match(hostname):
-            return
-
-        # Add to index
-        self.index[hostname] = [region, instance.id]
-
-        # Inventory: Group by instance ID (always a group of 1)
-        if self.group_by_instance_id:
-            self.inventory[instance.id] = [hostname]
-            if self.nested_groups:
-                self.push_group(self.inventory, 'instances', instance.id)
-
-        # Inventory: Group by region
-        if self.group_by_region:
-            self.push(self.inventory, region, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'regions', region)
-
-        # Inventory: Group by availability zone
-        if self.group_by_availability_zone:
-            self.push(self.inventory, instance.placement, hostname)
-            if self.nested_groups:
-                if self.group_by_region:
-                    self.push_group(self.inventory, region, instance.placement)
-                self.push_group(self.inventory, 'zones', instance.placement)
-
-        # Inventory: Group by Amazon Machine Image (AMI) ID
-        if self.group_by_ami_id:
-            ami_id = self.to_safe(instance.image_id)
-            self.push(self.inventory, ami_id, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'images', ami_id)
-
-        # Inventory: Group by instance type
-        if self.group_by_instance_type:
-            type_name = self.to_safe('type_' + instance.instance_type)
-            self.push(self.inventory, type_name, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'types', type_name)
-
-        # Inventory: Group by key pair
-        if self.group_by_key_pair and instance.key_name:
-            key_name = self.to_safe('key_' + instance.key_name)
-            self.push(self.inventory, key_name, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'keys', key_name)
-
-        # Inventory: Group by VPC
-        if self.group_by_vpc_id and instance.vpc_id:
-            vpc_id_name = self.to_safe('vpc_id_' + instance.vpc_id)
-            self.push(self.inventory, vpc_id_name, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'vpcs', vpc_id_name)
-
-        # Inventory: Group by security group
-        if self.group_by_security_group:
-            try:
-                for group in instance.groups:
-                    key = self.to_safe("security_group_" + group.name)
-                    self.push(self.inventory, key, hostname)
-                    if self.nested_groups:
-                        self.push_group(self.inventory, 'security_groups', key)
-            except AttributeError:
-                self.fail_with_error('\n'.join(['Package boto seems a bit older.',
-                                                'Please upgrade boto >= 2.3.0.']))
-
-        # Inventory: Group by tag keys
-        if self.group_by_tag_keys:
-            for k, v in instance.tags.items():
-                if self.expand_csv_tags and v and ',' in v:
-                    values = map(lambda x: x.strip(), v.split(','))
-                else:
-                    values = [v]
-
-                for v in values:
-                    if v:
-                        key = self.to_safe("tag_" + k + "=" + v)
-                    else:
-                        key = self.to_safe("tag_" + k)
-                    self.push(self.inventory, key, hostname)
-                    if self.nested_groups:
-                        self.push_group(self.inventory, 'tags', self.to_safe("tag_" + k))
-                        if v:
-                            self.push_group(self.inventory, self.to_safe("tag_" + k), key)
-
-        # Inventory: Group by Route53 domain names if enabled
-        if self.route53_enabled and self.group_by_route53_names:
-            route53_names = self.get_instance_route53_names(instance)
-            for name in route53_names:
-                self.push(self.inventory, name, hostname)
-                if self.nested_groups:
-                    self.push_group(self.inventory, 'route53', name)
-
-        # Global Tag: instances without tags
-        if self.group_by_tag_none and len(instance.tags) == 0:
-            self.push(self.inventory, 'tag_none', hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'tags', 'tag_none')
-
-        # Global Tag: tag all EC2 instances
-        self.push(self.inventory, 'ec2', hostname)
-
-        self.inventory["_meta"]["hostvars"][hostname] = self.get_host_info_dict_from_instance(instance)
-        self.inventory["_meta"]["hostvars"][hostname]['ansible_ssh_host'] = dest
-
-
-    def add_rds_instance(self, instance, region):
-        ''' Adds an RDS instance to the inventory and index, as long as it is
-        addressable '''
-
-        # Only want available instances unless all_rds_instances is True
-        if not self.all_rds_instances and instance.status != 'available':
-            return
-
-        # Select the best destination address
-        dest = instance.endpoint[0]
-
-        if not dest:
-            # Skip instances we cannot address (e.g. private VPC subnet)
-            return
-
-        # Set the inventory name
-        hostname = None
-        if self.hostname_variable:
-            if self.hostname_variable.startswith('tag_'):
-                hostname = instance.tags.get(self.hostname_variable[4:], None)
-            else:
-                hostname = getattr(instance, self.hostname_variable)
-
-        # If we can't get a nice hostname, use the destination address
-        if not hostname:
-            hostname = dest
-
-        hostname = self.to_safe(hostname).lower()
-
-        # Add to index
-        self.index[hostname] = [region, instance.id]
-
-        # Inventory: Group by instance ID (always a group of 1)
-        if self.group_by_instance_id:
-            self.inventory[instance.id] = [hostname]
-            if self.nested_groups:
-                self.push_group(self.inventory, 'instances', instance.id)
-
-        # Inventory: Group by region
-        if self.group_by_region:
-            self.push(self.inventory, region, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'regions', region)
-
-        # Inventory: Group by availability zone
-        if self.group_by_availability_zone:
-            self.push(self.inventory, instance.availability_zone, hostname)
-            if self.nested_groups:
-                if self.group_by_region:
-                    self.push_group(self.inventory, region, instance.availability_zone)
-                self.push_group(self.inventory, 'zones', instance.availability_zone)
-
-        # Inventory: Group by instance type
-        if self.group_by_instance_type:
-            type_name = self.to_safe('type_' + instance.instance_class)
-            self.push(self.inventory, type_name, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'types', type_name)
-
-        # Inventory: Group by VPC
-        if self.group_by_vpc_id and instance.subnet_group and instance.subnet_group.vpc_id:
-            vpc_id_name = self.to_safe('vpc_id_' + instance.subnet_group.vpc_id)
-            self.push(self.inventory, vpc_id_name, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'vpcs', vpc_id_name)
-
-        # Inventory: Group by security group
-        if self.group_by_security_group:
-            try:
-                if instance.security_group:
-                    key = self.to_safe("security_group_" + instance.security_group.name)
-                    self.push(self.inventory, key, hostname)
-                    if self.nested_groups:
-                        self.push_group(self.inventory, 'security_groups', key)
-
-            except AttributeError:
-                self.fail_with_error('\n'.join(['Package boto seems a bit older.',
-                                                'Please upgrade boto >= 2.3.0.']))
-
-
-        # Inventory: Group by engine
-        if self.group_by_rds_engine:
-            self.push(self.inventory, self.to_safe("rds_" + instance.engine), hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'rds_engines', self.to_safe("rds_" + instance.engine))
-
-        # Inventory: Group by parameter group
-        if self.group_by_rds_parameter_group:
-            self.push(self.inventory, self.to_safe("rds_parameter_group_" + instance.parameter_group.name), hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'rds_parameter_groups', self.to_safe("rds_parameter_group_" + instance.parameter_group.name))
-
-        # Global Tag: all RDS instances
-        self.push(self.inventory, 'rds', hostname)
-
-        self.inventory["_meta"]["hostvars"][hostname] = self.get_host_info_dict_from_instance(instance)
-        self.inventory["_meta"]["hostvars"][hostname]['ansible_ssh_host'] = dest
-
-    def add_elasticache_cluster(self, cluster, region):
-        ''' Adds an ElastiCache cluster to the inventory and index, as long as
-        it's nodes are addressable '''
-
-        # Only want available clusters unless all_elasticache_clusters is True
-        if not self.all_elasticache_clusters and cluster['CacheClusterStatus'] != 'available':
-            return
-
-        # Select the best destination address
-        if 'ConfigurationEndpoint' in cluster and cluster['ConfigurationEndpoint']:
-            # Memcached cluster
-            dest = cluster['ConfigurationEndpoint']['Address']
-            is_redis = False
-        else:
-            # Redis sigle node cluster
-            # Because all Redis clusters are single nodes, we'll merge the
-            # info from the cluster with info about the node
-            dest = cluster['CacheNodes'][0]['Endpoint']['Address']
-            is_redis = True
-
-        if not dest:
-            # Skip clusters we cannot address (e.g. private VPC subnet)
-            return
-
-        # Add to index
-        self.index[dest] = [region, cluster['CacheClusterId']]
-
-        # Inventory: Group by instance ID (always a group of 1)
-        if self.group_by_instance_id:
-            self.inventory[cluster['CacheClusterId']] = [dest]
-            if self.nested_groups:
-                self.push_group(self.inventory, 'instances', cluster['CacheClusterId'])
-
-        # Inventory: Group by region
-        if self.group_by_region and not is_redis:
-            self.push(self.inventory, region, dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'regions', region)
-
-        # Inventory: Group by availability zone
-        if self.group_by_availability_zone and not is_redis:
-            self.push(self.inventory, cluster['PreferredAvailabilityZone'], dest)
-            if self.nested_groups:
-                if self.group_by_region:
-                    self.push_group(self.inventory, region, cluster['PreferredAvailabilityZone'])
-                self.push_group(self.inventory, 'zones', cluster['PreferredAvailabilityZone'])
-
-        # Inventory: Group by node type
-        if self.group_by_instance_type and not is_redis:
-            type_name = self.to_safe('type_' + cluster['CacheNodeType'])
-            self.push(self.inventory, type_name, dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'types', type_name)
-
-        # Inventory: Group by VPC (information not available in the current
-        # AWS API version for ElastiCache)
-
-        # Inventory: Group by security group
-        if self.group_by_security_group and not is_redis:
-
-            # Check for the existence of the 'SecurityGroups' key and also if
-            # this key has some value. When the cluster is not placed in a SG
-            # the query can return None here and cause an error.
-            if 'SecurityGroups' in cluster and cluster['SecurityGroups'] is not None:
-                for security_group in cluster['SecurityGroups']:
-                    key = self.to_safe("security_group_" + security_group['SecurityGroupId'])
-                    self.push(self.inventory, key, dest)
-                    if self.nested_groups:
-                        self.push_group(self.inventory, 'security_groups', key)
-
-        # Inventory: Group by engine
-        if self.group_by_elasticache_engine and not is_redis:
-            self.push(self.inventory, self.to_safe("elasticache_" + cluster['Engine']), dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'elasticache_engines', self.to_safe(cluster['Engine']))
-
-        # Inventory: Group by parameter group
-        if self.group_by_elasticache_parameter_group:
-            self.push(self.inventory, self.to_safe("elasticache_parameter_group_" + cluster['CacheParameterGroup']['CacheParameterGroupName']), dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'elasticache_parameter_groups', self.to_safe(cluster['CacheParameterGroup']['CacheParameterGroupName']))
-
-        # Inventory: Group by replication group
-        if self.group_by_elasticache_replication_group and 'ReplicationGroupId' in cluster and cluster['ReplicationGroupId']:
-            self.push(self.inventory, self.to_safe("elasticache_replication_group_" + cluster['ReplicationGroupId']), dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'elasticache_replication_groups', self.to_safe(cluster['ReplicationGroupId']))
-
-        # Global Tag: all ElastiCache clusters
-        self.push(self.inventory, 'elasticache_clusters', cluster['CacheClusterId'])
-
-        host_info = self.get_host_info_dict_from_describe_dict(cluster)
-
-        self.inventory["_meta"]["hostvars"][dest] = host_info
-
-        # Add the nodes
-        for node in cluster['CacheNodes']:
-            self.add_elasticache_node(node, cluster, region)
-
-    def add_elasticache_node(self, node, cluster, region):
-        ''' Adds an ElastiCache node to the inventory and index, as long as
-        it is addressable '''
-
-        # Only want available nodes unless all_elasticache_nodes is True
-        if not self.all_elasticache_nodes and node['CacheNodeStatus'] != 'available':
-            return
-
-        # Select the best destination address
-        dest = node['Endpoint']['Address']
-
-        if not dest:
-            # Skip nodes we cannot address (e.g. private VPC subnet)
-            return
-
-        node_id = self.to_safe(cluster['CacheClusterId'] + '_' + node['CacheNodeId'])
-
-        # Add to index
-        self.index[dest] = [region, node_id]
-
-        # Inventory: Group by node ID (always a group of 1)
-        if self.group_by_instance_id:
-            self.inventory[node_id] = [dest]
-            if self.nested_groups:
-                self.push_group(self.inventory, 'instances', node_id)
-
-        # Inventory: Group by region
-        if self.group_by_region:
-            self.push(self.inventory, region, dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'regions', region)
-
-        # Inventory: Group by availability zone
-        if self.group_by_availability_zone:
-            self.push(self.inventory, cluster['PreferredAvailabilityZone'], dest)
-            if self.nested_groups:
-                if self.group_by_region:
-                    self.push_group(self.inventory, region, cluster['PreferredAvailabilityZone'])
-                self.push_group(self.inventory, 'zones', cluster['PreferredAvailabilityZone'])
-
-        # Inventory: Group by node type
-        if self.group_by_instance_type:
-            type_name = self.to_safe('type_' + cluster['CacheNodeType'])
-            self.push(self.inventory, type_name, dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'types', type_name)
-
-        # Inventory: Group by VPC (information not available in the current
-        # AWS API version for ElastiCache)
-
-        # Inventory: Group by security group
-        if self.group_by_security_group:
-
-            # Check for the existence of the 'SecurityGroups' key and also if
-            # this key has some value. When the cluster is not placed in a SG
-            # the query can return None here and cause an error.
-            if 'SecurityGroups' in cluster and cluster['SecurityGroups'] is not None:
-                for security_group in cluster['SecurityGroups']:
-                    key = self.to_safe("security_group_" + security_group['SecurityGroupId'])
-                    self.push(self.inventory, key, dest)
-                    if self.nested_groups:
-                        self.push_group(self.inventory, 'security_groups', key)
-
-        # Inventory: Group by engine
-        if self.group_by_elasticache_engine:
-            self.push(self.inventory, self.to_safe("elasticache_" + cluster['Engine']), dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'elasticache_engines', self.to_safe("elasticache_" + cluster['Engine']))
-
-        # Inventory: Group by parameter group (done at cluster level)
-
-        # Inventory: Group by replication group (done at cluster level)
-
-        # Inventory: Group by ElastiCache Cluster
-        if self.group_by_elasticache_cluster:
-            self.push(self.inventory, self.to_safe("elasticache_cluster_" + cluster['CacheClusterId']), dest)
-
-        # Global Tag: all ElastiCache nodes
-        self.push(self.inventory, 'elasticache_nodes', dest)
-
-        host_info = self.get_host_info_dict_from_describe_dict(node)
-
-        if dest in self.inventory["_meta"]["hostvars"]:
-            self.inventory["_meta"]["hostvars"][dest].update(host_info)
-        else:
-            self.inventory["_meta"]["hostvars"][dest] = host_info
-
-    def add_elasticache_replication_group(self, replication_group, region):
-        ''' Adds an ElastiCache replication group to the inventory and index '''
-
-        # Only want available clusters unless all_elasticache_replication_groups is True
-        if not self.all_elasticache_replication_groups and replication_group['Status'] != 'available':
-            return
-
-        # Select the best destination address (PrimaryEndpoint)
-        dest = replication_group['NodeGroups'][0]['PrimaryEndpoint']['Address']
-
-        if not dest:
-            # Skip clusters we cannot address (e.g. private VPC subnet)
-            return
-
-        # Add to index
-        self.index[dest] = [region, replication_group['ReplicationGroupId']]
-
-        # Inventory: Group by ID (always a group of 1)
-        if self.group_by_instance_id:
-            self.inventory[replication_group['ReplicationGroupId']] = [dest]
-            if self.nested_groups:
-                self.push_group(self.inventory, 'instances', replication_group['ReplicationGroupId'])
-
-        # Inventory: Group by region
-        if self.group_by_region:
-            self.push(self.inventory, region, dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'regions', region)
-
-        # Inventory: Group by availability zone (doesn't apply to replication groups)
-
-        # Inventory: Group by node type (doesn't apply to replication groups)
-
-        # Inventory: Group by VPC (information not available in the current
-        # AWS API version for replication groups
-
-        # Inventory: Group by security group (doesn't apply to replication groups)
-        # Check this value in cluster level
-
-        # Inventory: Group by engine (replication groups are always Redis)
-        if self.group_by_elasticache_engine:
-            self.push(self.inventory, 'elasticache_redis', dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'elasticache_engines', 'redis')
-
-        # Global Tag: all ElastiCache clusters
-        self.push(self.inventory, 'elasticache_replication_groups', replication_group['ReplicationGroupId'])
-
-        host_info = self.get_host_info_dict_from_describe_dict(replication_group)
-
-        self.inventory["_meta"]["hostvars"][dest] = host_info
-
-    def get_route53_records(self):
-        ''' Get and store the map of resource records to domain names that
-        point to them. '''
-
-        r53_conn = route53.Route53Connection()
-        all_zones = r53_conn.get_zones()
-
-        route53_zones = [ zone for zone in all_zones if zone.name[:-1]
-                          not in self.route53_excluded_zones ]
-
-        self.route53_records = {}
-
-        for zone in route53_zones:
-            rrsets = r53_conn.get_all_rrsets(zone.id)
-
-            for record_set in rrsets:
-                record_name = record_set.name
-
-                if record_name.endswith('.'):
-                    record_name = record_name[:-1]
-
-                for resource in record_set.resource_records:
-                    self.route53_records.setdefault(resource, set())
-                    self.route53_records[resource].add(record_name)
-
-
-    def get_instance_route53_names(self, instance):
-        ''' Check if an instance is referenced in the records we have from
-        Route53. If it is, return the list of domain names pointing to said
-        instance. If nothing points to it, return an empty list. '''
-
-        instance_attributes = [ 'public_dns_name', 'private_dns_name',
-                                'ip_address', 'private_ip_address' ]
-
-        name_list = set()
-
-        for attrib in instance_attributes:
-            try:
-                value = getattr(instance, attrib)
-            except AttributeError:
-                continue
-
-            if value in self.route53_records:
-                name_list.update(self.route53_records[value])
-
-        return list(name_list)
-
-    def get_host_info_dict_from_instance(self, instance):
-        instance_vars = {}
-        for key in vars(instance):
-            value = getattr(instance, key)
-            key = self.to_safe('ec2_' + key)
-
-            # Handle complex types
-            # state/previous_state changed to properties in boto in https://github.com/boto/boto/commit/a23c379837f698212252720d2af8dec0325c9518
-            if key == 'ec2__state':
-                instance_vars['ec2_state'] = instance.state or ''
-                instance_vars['ec2_state_code'] = instance.state_code
-            elif key == 'ec2__previous_state':
-                instance_vars['ec2_previous_state'] = instance.previous_state or ''
-                instance_vars['ec2_previous_state_code'] = instance.previous_state_code
-            elif type(value) in [int, bool]:
-                instance_vars[key] = value
-            elif isinstance(value, six.string_types):
-                instance_vars[key] = value.strip()
-            elif type(value) == type(None):
-                instance_vars[key] = ''
-            elif key == 'ec2_region':
-                instance_vars[key] = value.name
-            elif key == 'ec2__placement':
-                instance_vars['ec2_placement'] = value.zone
-            elif key == 'ec2_tags':
-                for k, v in value.items():
-                    if self.expand_csv_tags and ',' in v:
-                        v = map(lambda x: x.strip(), v.split(','))
-                    key = self.to_safe('ec2_tag_' + k)
-                    instance_vars[key] = v
-            elif key == 'ec2_groups':
-                group_ids = []
-                group_names = []
-                for group in value:
-                    group_ids.append(group.id)
-                    group_names.append(group.name)
-                instance_vars["ec2_security_group_ids"] = ','.join([str(i) for i in group_ids])
-                instance_vars["ec2_security_group_names"] = ','.join([str(i) for i in group_names])
-            else:
-                pass
-                # TODO Product codes if someone finds them useful
-                #print key
-                #print type(value)
-                #print value
-
-        return instance_vars
-
-    def get_host_info_dict_from_describe_dict(self, describe_dict):
-        ''' Parses the dictionary returned by the API call into a flat list
-            of parameters. This method should be used only when 'describe' is
-            used directly because Boto doesn't provide specific classes. '''
-
-        # I really don't agree with prefixing everything with 'ec2'
-        # because EC2, RDS and ElastiCache are different services.
-        # I'm just following the pattern used until now to not break any
-        # compatibility.
-
-        host_info = {}
-        for key in describe_dict:
-            value = describe_dict[key]
-            key = self.to_safe('ec2_' + self.uncammelize(key))
-
-            # Handle complex types
-
-            # Target: Memcached Cache Clusters
-            if key == 'ec2_configuration_endpoint' and value:
-                host_info['ec2_configuration_endpoint_address'] = value['Address']
-                host_info['ec2_configuration_endpoint_port'] = value['Port']
-
-            # Target: Cache Nodes and Redis Cache Clusters (single node)
-            if key == 'ec2_endpoint' and value:
-                host_info['ec2_endpoint_address'] = value['Address']
-                host_info['ec2_endpoint_port'] = value['Port']
-
-            # Target: Redis Replication Groups
-            if key == 'ec2_node_groups' and value:
-                host_info['ec2_endpoint_address'] = value[0]['PrimaryEndpoint']['Address']
-                host_info['ec2_endpoint_port'] = value[0]['PrimaryEndpoint']['Port']
-                replica_count = 0
-                for node in value[0]['NodeGroupMembers']:
-                    if node['CurrentRole'] == 'primary':
-                        host_info['ec2_primary_cluster_address'] = node['ReadEndpoint']['Address']
-                        host_info['ec2_primary_cluster_port'] = node['ReadEndpoint']['Port']
-                        host_info['ec2_primary_cluster_id'] = node['CacheClusterId']
-                    elif node['CurrentRole'] == 'replica':
-                        host_info['ec2_replica_cluster_address_'+ str(replica_count)] = node['ReadEndpoint']['Address']
-                        host_info['ec2_replica_cluster_port_'+ str(replica_count)] = node['ReadEndpoint']['Port']
-                        host_info['ec2_replica_cluster_id_'+ str(replica_count)] = node['CacheClusterId']
-                        replica_count += 1
-
-            # Target: Redis Replication Groups
-            if key == 'ec2_member_clusters' and value:
-                host_info['ec2_member_clusters'] = ','.join([str(i) for i in value])
-
-            # Target: All Cache Clusters
-            elif key == 'ec2_cache_parameter_group':
-                host_info["ec2_cache_node_ids_to_reboot"] = ','.join([str(i) for i in value['CacheNodeIdsToReboot']])
-                host_info['ec2_cache_parameter_group_name'] = value['CacheParameterGroupName']
-                host_info['ec2_cache_parameter_apply_status'] = value['ParameterApplyStatus']
-
-            # Target: Almost everything
-            elif key == 'ec2_security_groups':
-
-                # Skip if SecurityGroups is None
-                # (it is possible to have the key defined but no value in it).
-                if value is not None:
-                    sg_ids = []
-                    for sg in value:
-                        sg_ids.append(sg['SecurityGroupId'])
-                    host_info["ec2_security_group_ids"] = ','.join([str(i) for i in sg_ids])
-
-            # Target: Everything
-            # Preserve booleans and integers
-            elif type(value) in [int, bool]:
-                host_info[key] = value
-
-            # Target: Everything
-            # Sanitize string values
-            elif isinstance(value, six.string_types):
-                host_info[key] = value.strip()
-
-            # Target: Everything
-            # Replace None by an empty string
-            elif type(value) == type(None):
-                host_info[key] = ''
-
-            else:
-                # Remove non-processed complex types
-                pass
-
-        return host_info
-
-    def get_host_info(self):
-        ''' Get variables about a specific host '''
-
-        if len(self.index) == 0:
-            # Need to load index from cache
-            self.load_index_from_cache()
-
-        if not self.args.host in self.index:
-            # try updating the cache
-            self.do_api_calls_update_cache()
-            if not self.args.host in self.index:
-                # host might not exist anymore
-                return self.json_format_dict({}, True)
-
-        (region, instance_id) = self.index[self.args.host]
-
-        instance = self.get_instance(region, instance_id)
-        return self.json_format_dict(self.get_host_info_dict_from_instance(instance), True)
-
-    def push(self, my_dict, key, element):
-        ''' Push an element onto an array that may not have been defined in
-        the dict '''
-        group_info = my_dict.setdefault(key, [])
-        if isinstance(group_info, dict):
-            host_list = group_info.setdefault('hosts', [])
-            host_list.append(element)
-        else:
-            group_info.append(element)
-
-    def push_group(self, my_dict, key, element):
-        ''' Push a group as a child of another group. '''
-        parent_group = my_dict.setdefault(key, {})
-        if not isinstance(parent_group, dict):
-            parent_group = my_dict[key] = {'hosts': parent_group}
-        child_groups = parent_group.setdefault('children', [])
-        if element not in child_groups:
-            child_groups.append(element)
-
-    def get_inventory_from_cache(self):
-        ''' Reads the inventory from the cache file and returns it as a JSON
-        object '''
-
-        cache = open(self.cache_path_cache, 'r')
-        json_inventory = cache.read()
-        return json_inventory
-
-
-    def load_index_from_cache(self):
-        ''' Reads the index from the cache file sets self.index '''
-
-        cache = open(self.cache_path_index, 'r')
-        json_index = cache.read()
-        self.index = json.loads(json_index)
-
-
-    def write_to_cache(self, data, filename):
-        ''' Writes data in JSON format to a file '''
-
-        json_data = self.json_format_dict(data, True)
-        cache = open(filename, 'w')
-        cache.write(json_data)
-        cache.close()
-
-    def uncammelize(self, key):
-        temp = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', key)
-        return re.sub('([a-z0-9])([A-Z])', r'\1_\2', temp).lower()
-
-    def to_safe(self, word):
-        ''' Converts 'bad' characters in a string to underscores so they can be used as Ansible groups '''
-        regex = "[^A-Za-z0-9\_"
-        if not self.replace_dash_in_groups:
-            regex += "\-"
-        return re.sub(regex + "]", "_", word)
-
-    def json_format_dict(self, data, pretty=False):
-        ''' Converts a dict to a JSON object and dumps it as a formatted
-        string '''
-
-        if pretty:
-            return json.dumps(data, sort_keys=True, indent=2)
-        else:
-            return json.dumps(data)
-
-
-# Run the script
-Ec2Inventory()
diff --git a/baas-1701-dc5-dc6/inventory-dc5 b/baas-1701-dc5-dc6/inventory-dc5
deleted file mode 100644
index dc769fe..0000000
--- a/baas-1701-dc5-dc6/inventory-dc5
+++ /dev/null
@@ -1,67 +0,0 @@
-[tag_Name_dc5_n1]
-[tag_Name_dc5_n2]
-[tag_Name_dc5_n3]
-[tag_Name_dc5_n4]
-[tag_Name_dc5_n5]
-[tag_Name_dc5_n6]
-[tag_Name_dc5_n7]
-[tag_Name_dc5_n8]
-[tag_Name_dc5_n9]
-[tag_Name_dc5_n10]
-
-[planet:children]
-dc-1
-
-[dc-1:children]
-tag_Name_dc5_n1
-tag_Name_dc5_n2
-tag_Name_dc5_n3
-tag_Name_dc5_n4
-tag_Name_dc5_n5
-tag_Name_dc5_n6
-tag_Name_dc5_n7
-tag_Name_dc5_n8
-tag_Name_dc5_n9
-tag_Name_dc5_n10
-
-[elastic:children]
-dc-1-elastic
-
-[dc-1-elastic:children]
-tag_Name_dc5_n1
-tag_Name_dc5_n2
-tag_Name_dc5_n3
-
-[baas:children]
-dc-1-baas
-
-[dc-1-baas:children]
-tag_Name_dc5_n4
-tag_Name_dc5_n5
-tag_Name_dc5_n6
-
-[portal:children]
-dc-1-portal
-
-[dc-1-portal:children]
-tag_Name_dc5_n7
-
-[ds:children]
-dc-1-ds
-
-[dc-1-ds:children]
-dc-1-cassandra
-
-[cassandra:children]
-dc-1-cassandra
-
-[dc-1-cassandra:children]
-tag_Name_dc5_n8
-tag_Name_dc5_n9
-tag_Name_dc5_n10
-
-[ms:children]
-dc-1-ms
-
-[dc-1-ms:children]
-tag_Name_dc5_n7
diff --git a/baas-1701-dc5-dc6/inventory-dc6 b/baas-1701-dc5-dc6/inventory-dc6
deleted file mode 100644
index 509f36c..0000000
--- a/baas-1701-dc5-dc6/inventory-dc6
+++ /dev/null
@@ -1,67 +0,0 @@
-[tag_Name_dc6_n1]
-[tag_Name_dc6_n2]
-[tag_Name_dc6_n3]
-[tag_Name_dc6_n4]
-[tag_Name_dc6_n5]
-[tag_Name_dc6_n6]
-[tag_Name_dc6_n7]
-[tag_Name_dc6_n8]
-[tag_Name_dc6_n9]
-[tag_Name_dc6_n10]
-
-[planet:children]
-dc-2
-
-[dc-2:children]
-tag_Name_dc6_n1
-tag_Name_dc6_n2
-tag_Name_dc6_n3
-tag_Name_dc6_n4
-tag_Name_dc6_n5
-tag_Name_dc6_n6
-tag_Name_dc6_n7
-tag_Name_dc6_n8
-tag_Name_dc6_n9
-tag_Name_dc6_n10
-
-[elastic:children]
-dc-2-elastic
-
-[dc-2-elastic:children]
-tag_Name_dc6_n1
-tag_Name_dc6_n2
-tag_Name_dc6_n3
-
-[baas:children]
-dc-2-baas
-
-[dc-2-baas:children]
-tag_Name_dc6_n4
-tag_Name_dc6_n5
-tag_Name_dc6_n6
-
-[portal:children]
-dc-2-portal
-
-[dc-2-portal:children]
-tag_Name_dc6_n7
-
-[ds:children]
-dc-2-ds
-
-[dc-2-ds:children]
-dc-2-cassandra
-
-[cassandra:children]
-dc-2-cassandra
-
-[dc-2-cassandra:children]
-tag_Name_dc6_n8
-tag_Name_dc6_n9
-tag_Name_dc6_n10
-
-[ms:children]
-dc-2-ms
-
-[dc-2-ms:children]
-tag_Name_dc6_n7
diff --git a/baas-1701-dc5/ec2.ini b/baas-1701-dc5/ec2.ini
deleted file mode 100644
index 36b3921..0000000
--- a/baas-1701-dc5/ec2.ini
+++ /dev/null
@@ -1,200 +0,0 @@
-# Ansible EC2 external inventory script settings
-#
-
-[ec2]
-
-# to talk to a private eucalyptus instance uncomment these lines
-# and edit edit eucalyptus_host to be the host name of your cloud controller
-#eucalyptus = True
-#eucalyptus_host = clc.cloud.domain.org
-
-# AWS regions to make calls to. Set this to 'all' to make request to all regions
-# in AWS and merge the results together. Alternatively, set this to a comma
-# separated list of regions. E.g. 'us-east-1,us-west-1,us-west-2'
-regions = all
-regions_exclude = us-gov-west-1,cn-north-1
-
-# When generating inventory, Ansible needs to know how to address a server.
-# Each EC2 instance has a lot of variables associated with it. Here is the list:
-#   http://docs.pythonboto.org/en/latest/ref/ec2.html#module-boto.ec2.instance
-# Below are 2 variables that are used as the address of a server:
-#   - destination_variable
-#   - vpc_destination_variable
-
-# This is the normal destination variable to use. If you are running Ansible
-# from outside EC2, then 'public_dns_name' makes the most sense. If you are
-# running Ansible from within EC2, then perhaps you want to use the internal
-# address, and should set this to 'private_dns_name'. The key of an EC2 tag
-# may optionally be used; however the boto instance variables hold precedence
-# in the event of a collision.
-destination_variable = public_dns_name
-
-# This allows you to override the inventory_name with an ec2 variable, instead
-# of using the destination_variable above. Addressing (aka ansible_ssh_host)
-# will still use destination_variable. Tags should be written as 'tag_TAGNAME'.
-#hostname_variable = tag_Name
-
-# For server inside a VPC, using DNS names may not make sense. When an instance
-# has 'subnet_id' set, this variable is used. If the subnet is public, setting
-# this to 'ip_address' will return the public IP address. For instances in a
-# private subnet, this should be set to 'private_ip_address', and Ansible must
-# be run from within EC2. The key of an EC2 tag may optionally be used; however
-# the boto instance variables hold precedence in the event of a collision.
-# WARNING: - instances that are in the private vpc, _without_ public ip address
-# will not be listed in the inventory until You set:
-# vpc_destination_variable = private_ip_address
-vpc_destination_variable = ip_address
-
-# The following two settings allow flexible ansible host naming based on a
-# python format string and a comma-separated list of ec2 tags.  Note that:
-#
-# 1) If the tags referenced are not present for some instances, empty strings
-#    will be substituted in the format string.
-# 2) This overrides both destination_variable and vpc_destination_variable.
-#
-#destination_format = {0}.{1}.example.com
-#destination_format_tags = Name,environment
-
-# To tag instances on EC2 with the resource records that point to them from
-# Route53, uncomment and set 'route53' to True.
-route53 = False
-
-# To exclude RDS instances from the inventory, uncomment and set to False.
-rds = False
-
-# To exclude ElastiCache instances from the inventory, uncomment and set to False.
-elasticache = False
-
-# Additionally, you can specify the list of zones to exclude looking up in
-# 'route53_excluded_zones' as a comma-separated list.
-# route53_excluded_zones = samplezone1.com, samplezone2.com
-
-# By default, only EC2 instances in the 'running' state are returned. Set
-# 'all_instances' to True to return all instances regardless of state.
-all_instances = True
-
-# By default, only EC2 instances in the 'running' state are returned. Specify
-# EC2 instance states to return as a comma-separated list. This
-# option is overriden when 'all_instances' is True.
-# instance_states = pending, running, shutting-down, terminated, stopping, stopped
-
-# By default, only RDS instances in the 'available' state are returned.  Set
-# 'all_rds_instances' to True return all RDS instances regardless of state.
-all_rds_instances = False
-
-# By default, only ElastiCache clusters and nodes in the 'available' state
-# are returned. Set 'all_elasticache_clusters' and/or 'all_elastic_nodes'
-# to True return all ElastiCache clusters and nodes, regardless of state.
-#
-# Note that all_elasticache_nodes only applies to listed clusters. That means
-# if you set all_elastic_clusters to false, no node will be return from
-# unavailable clusters, regardless of the state and to what you set for
-# all_elasticache_nodes.
-all_elasticache_replication_groups = False
-all_elasticache_clusters = False
-all_elasticache_nodes = False
-
-# API calls to EC2 are slow. For this reason, we cache the results of an API
-# call. Set this to the path you want cache files to be written to. Two files
-# will be written to this directory:
-#   - ansible-ec2.cache
-#   - ansible-ec2.index
-cache_path = ~/.ansible/tmp
-
-# The number of seconds a cache file is considered valid. After this many
-# seconds, a new API call will be made, and the cache file will be updated.
-# To disable the cache, set this value to 0
-cache_max_age = 300
-
-# Organize groups into a nested/hierarchy instead of a flat namespace.
-nested_groups = False
-
-# Replace - tags when creating groups to avoid issues with ansible
-replace_dash_in_groups = True
-
-# If set to true, any tag of the form "a,b,c" is expanded into a list
-# and the results are used to create additional tag_* inventory groups.
-expand_csv_tags = False
-
-# The EC2 inventory output can become very large. To manage its size,
-# configure which groups should be created.
-group_by_instance_id = True
-group_by_region = True
-group_by_availability_zone = True
-group_by_ami_id = True
-group_by_instance_type = True
-group_by_key_pair = True
-group_by_vpc_id = True
-group_by_security_group = True
-group_by_tag_keys = True
-group_by_tag_none = True
-group_by_route53_names = True
-group_by_rds_engine = False
-group_by_rds_parameter_group = False
-group_by_elasticache_engine = True
-group_by_elasticache_cluster = True
-group_by_elasticache_parameter_group = True
-group_by_elasticache_replication_group = True
-
-# If you only want to include hosts that match a certain regular expression
-# pattern_include = staging-*
-
-# If you want to exclude any hosts that match a certain regular expression
-# pattern_exclude = staging-*
-# Ansible EC2 external inventory script settings
-#
-
-##[ec2]
-##
-### to talk to a private eucalyptus instance uncomment these lines
-### and edit edit eucalyptus_host to be the host name of your cloud controller
-###eucalyptus = True
-###eucalyptus_host = clc.cloud.domain.org
-##
-### AWS regions to make calls to. Set this to 'all' to make request to all regions
-##
-### in AWS and merge the results together. Alternatively, set this to a comma
-### separated list of regions. E.g. 'us-east-1,us-west-1,us-west-2'
-##regions = all
-##regions_exclude = us-gov-west-1,cn-north-1
-##
-### When generating inventory, Ansible needs to know how to address a server.
-### Each EC2 instance has a lot of variables associated with it. Here is the list:
-###   http://docs.pythonboto.org/en/latest/ref/ec2.html#module-boto.ec2.instance
-### Below are 2 variables that are used as the address of a server:
-###   - destination_variable
-###   - vpc_destination_variable
-##
-### This is the normal destination variable to use. If you are running Ansible
-### from outside EC2, then 'public_dns_name' makes the most sense. If you are
-### running Ansible from within EC2, then perhaps you want to use the internal
-### address, and should set this to 'private_dns_name'. The key of an EC2 tag
-##...skipping...
-### pattern_include = staging-*
-##
-### If you want to exclude any hosts that match a certain regular expression
-### pattern_exclude = staging-*
-
-# Instance filters can be used to control which instances are retrieved for
-# inventory. For the full list of possible filters, please read the EC2 API
-# docs: http://docs.aws.amazon.com/AWSEC2/latest/APIReference/ApiReference-query-DescribeInstances.html#query-DescribeInstances-filters
-# Filters are key/value pairs separated by '=', to list multiple filters use
-# a list separated by commas. See examples below.
-
-# Retrieve only instances with (key=value) env=staging tag
-# instance_filters = tag:env=staging
-
-# Retrieve only instances with role=webservers OR role=dbservers tag
-# instance_filters = tag:role=webservers,tag:role=dbservers
-
-# Retrieve only t1.micro instances OR instances with tag env=staging
-# instance_filters = instance-type=t1.micro,tag:env=staging
-
-# You can use wildcards in filter values also. Below will list instances which
-# tag Name value matches webservers1*
-# (ex. webservers15, webservers1a, webservers123 etc)
-# instance_filters = tag:Name=webservers1*
-
-# A boto configuration profile may be used to separate out credentials
-# see http://boto.readthedocs.org/en/latest/boto_config_tut.html
-# boto_profile = some-boto-profile-name
diff --git a/baas-1701-dc5/ec2.py b/baas-1701-dc5/ec2.py
deleted file mode 100755
index f30958a..0000000
--- a/baas-1701-dc5/ec2.py
+++ /dev/null
@@ -1,1385 +0,0 @@
-#!/usr/bin/env python
-
-'''
-EC2 external inventory script
-=================================
-
-Generates inventory that Ansible can understand by making API request to
-AWS EC2 using the Boto library.
-
-NOTE: This script assumes Ansible is being executed where the environment
-variables needed for Boto have already been set:
-    export AWS_ACCESS_KEY_ID='AK123'
-    export AWS_SECRET_ACCESS_KEY='abc123'
-
-This script also assumes there is an ec2.ini file alongside it.  To specify a
-different path to ec2.ini, define the EC2_INI_PATH environment variable:
-
-    export EC2_INI_PATH=/path/to/my_ec2.ini
-
-If you're using eucalyptus you need to set the above variables and
-you need to define:
-
-    export EC2_URL=http://hostname_of_your_cc:port/services/Eucalyptus
-
-If you're using boto profiles (requires boto>=2.24.0) you can choose a profile
-using the --boto-profile command line argument (e.g. ec2.py --boto-profile prod) or using
-the AWS_PROFILE variable:
-
-    AWS_PROFILE=prod ansible-playbook -i ec2.py myplaybook.yml
-
-For more details, see: http://docs.pythonboto.org/en/latest/boto_config_tut.html
-
-When run against a specific host, this script returns the following variables:
- - ec2_ami_launch_index
- - ec2_architecture
- - ec2_association
- - ec2_attachTime
- - ec2_attachment
- - ec2_attachmentId
- - ec2_client_token
- - ec2_deleteOnTermination
- - ec2_description
- - ec2_deviceIndex
- - ec2_dns_name
- - ec2_eventsSet
- - ec2_group_name
- - ec2_hypervisor
- - ec2_id
- - ec2_image_id
- - ec2_instanceState
- - ec2_instance_type
- - ec2_ipOwnerId
- - ec2_ip_address
- - ec2_item
- - ec2_kernel
- - ec2_key_name
- - ec2_launch_time
- - ec2_monitored
- - ec2_monitoring
- - ec2_networkInterfaceId
- - ec2_ownerId
- - ec2_persistent
- - ec2_placement
- - ec2_platform
- - ec2_previous_state
- - ec2_private_dns_name
- - ec2_private_ip_address
- - ec2_publicIp
- - ec2_public_dns_name
- - ec2_ramdisk
- - ec2_reason
- - ec2_region
- - ec2_requester_id
- - ec2_root_device_name
- - ec2_root_device_type
- - ec2_security_group_ids
- - ec2_security_group_names
- - ec2_shutdown_state
- - ec2_sourceDestCheck
- - ec2_spot_instance_request_id
- - ec2_state
- - ec2_state_code
- - ec2_state_reason
- - ec2_status
- - ec2_subnet_id
- - ec2_tenancy
- - ec2_virtualization_type
- - ec2_vpc_id
-
-These variables are pulled out of a boto.ec2.instance object. There is a lack of
-consistency with variable spellings (camelCase and underscores) since this
-just loops through all variables the object exposes. It is preferred to use the
-ones with underscores when multiple exist.
-
-In addition, if an instance has AWS Tags associated with it, each tag is a new
-variable named:
- - ec2_tag_[Key] = [Value]
-
-Security groups are comma-separated in 'ec2_security_group_ids' and
-'ec2_security_group_names'.
-'''
-
-# (c) 2012, Peter Sankauskas
-#
-# This file is part of Ansible,
-#
-# Ansible is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# Ansible is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with Ansible.  If not, see <http://www.gnu.org/licenses/>.
-
-######################################################################
-
-import sys
-import os
-import argparse
-import re
-from time import time
-import boto
-from boto import ec2
-from boto import rds
-from boto import elasticache
-from boto import route53
-import six
-
-from six.moves import configparser
-from collections import defaultdict
-
-try:
-    import json
-except ImportError:
-    import simplejson as json
-
-
-class Ec2Inventory(object):
-
-    def _empty_inventory(self):
-        return {"_meta" : {"hostvars" : {}}}
-
-    def __init__(self):
-        ''' Main execution path '''
-
-        # Inventory grouped by instance IDs, tags, security groups, regions,
-        # and availability zones
-        self.inventory = self._empty_inventory()
-
-        # Index of hostname (address) to instance ID
-        self.index = {}
-
-        # Boto profile to use (if any)
-        self.boto_profile = None
-
-        # Read settings and parse CLI arguments
-        self.parse_cli_args()
-        self.read_settings()
-
-        # Make sure that profile_name is not passed at all if not set
-        # as pre 2.24 boto will fall over otherwise
-        if self.boto_profile:
-            if not hasattr(boto.ec2.EC2Connection, 'profile_name'):
-                self.fail_with_error("boto version must be >= 2.24 to use profile")
-
-        # Cache
-        if self.args.refresh_cache:
-            self.do_api_calls_update_cache()
-        elif not self.is_cache_valid():
-            self.do_api_calls_update_cache()
-
-        # Data to print
-        if self.args.host:
-            data_to_print = self.get_host_info()
-
-        elif self.args.list:
-            # Display list of instances for inventory
-            if self.inventory == self._empty_inventory():
-                data_to_print = self.get_inventory_from_cache()
-            else:
-                data_to_print = self.json_format_dict(self.inventory, True)
-
-        print(data_to_print)
-
-
-    def is_cache_valid(self):
-        ''' Determines if the cache files have expired, or if it is still valid '''
-
-        if os.path.isfile(self.cache_path_cache):
-            mod_time = os.path.getmtime(self.cache_path_cache)
-            current_time = time()
-            if (mod_time + self.cache_max_age) > current_time:
-                if os.path.isfile(self.cache_path_index):
-                    return True
-
-        return False
-
-
-    def read_settings(self):
-        ''' Reads the settings from the ec2.ini file '''
-        if six.PY3:
-            config = configparser.ConfigParser()
-        else:
-            config = configparser.SafeConfigParser()
-        ec2_default_ini_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'ec2.ini')
-        ec2_ini_path = os.path.expanduser(os.path.expandvars(os.environ.get('EC2_INI_PATH', ec2_default_ini_path)))
-        config.read(ec2_ini_path)
-
-        # is eucalyptus?
-        self.eucalyptus_host = None
-        self.eucalyptus = False
-        if config.has_option('ec2', 'eucalyptus'):
-            self.eucalyptus = config.getboolean('ec2', 'eucalyptus')
-        if self.eucalyptus and config.has_option('ec2', 'eucalyptus_host'):
-            self.eucalyptus_host = config.get('ec2', 'eucalyptus_host')
-
-        # Regions
-        self.regions = []
-        configRegions = config.get('ec2', 'regions')
-        configRegions_exclude = config.get('ec2', 'regions_exclude')
-        if (configRegions == 'all'):
-            if self.eucalyptus_host:
-                self.regions.append(boto.connect_euca(host=self.eucalyptus_host).region.name)
-            else:
-                for regionInfo in ec2.regions():
-                    if regionInfo.name not in configRegions_exclude:
-                        self.regions.append(regionInfo.name)
-        else:
-            self.regions = configRegions.split(",")
-
-        # Destination addresses
-        self.destination_variable = config.get('ec2', 'destination_variable')
-        self.vpc_destination_variable = config.get('ec2', 'vpc_destination_variable')
-
-        if config.has_option('ec2', 'hostname_variable'):
-            self.hostname_variable = config.get('ec2', 'hostname_variable')
-        else:
-            self.hostname_variable = None
-
-        if config.has_option('ec2', 'destination_format') and \
-                config.has_option('ec2', 'destination_format_tags'):
-            self.destination_format = config.get('ec2', 'destination_format')
-            self.destination_format_tags = config.get('ec2', 'destination_format_tags').split(',')
-        else:
-            self.destination_format = None
-            self.destination_format_tags = None
-
-        # Route53
-        self.route53_enabled = config.getboolean('ec2', 'route53')
-        self.route53_excluded_zones = []
-        if config.has_option('ec2', 'route53_excluded_zones'):
-            self.route53_excluded_zones.extend(
-                    config.get('ec2', 'route53_excluded_zones', '').split(','))
-
-        # Include RDS instances?
-        self.rds_enabled = True
-        if config.has_option('ec2', 'rds'):
-            self.rds_enabled = config.getboolean('ec2', 'rds')
-
-        # Include ElastiCache instances?
-        self.elasticache_enabled = True
-        if config.has_option('ec2', 'elasticache'):
-            self.elasticache_enabled = config.getboolean('ec2', 'elasticache')
-
-        # Return all EC2 instances?
-        if config.has_option('ec2', 'all_instances'):
-            self.all_instances = config.getboolean('ec2', 'all_instances')
-        else:
-            self.all_instances = False
-
-        # Instance states to be gathered in inventory. Default is 'running'.
-        # Setting 'all_instances' to 'yes' overrides this option.
-        ec2_valid_instance_states = [
-            'pending',
-            'running',
-            'shutting-down',
-            'terminated',
-            'stopping',
-            'stopped'
-        ]
-        self.ec2_instance_states = []
-        if self.all_instances:
-            self.ec2_instance_states = ec2_valid_instance_states
-        elif config.has_option('ec2', 'instance_states'):
-            for instance_state in config.get('ec2', 'instance_states').split(','):
-                instance_state = instance_state.strip()
-                if instance_state not in ec2_valid_instance_states:
-                    continue
-                self.ec2_instance_states.append(instance_state)
-        else:
-            self.ec2_instance_states = ['running']
-
-        # Return all RDS instances? (if RDS is enabled)
-        if config.has_option('ec2', 'all_rds_instances') and self.rds_enabled:
-            self.all_rds_instances = config.getboolean('ec2', 'all_rds_instances')
-        else:
-            self.all_rds_instances = False
-
-        # Return all ElastiCache replication groups? (if ElastiCache is enabled)
-        if config.has_option('ec2', 'all_elasticache_replication_groups') and self.elasticache_enabled:
-            self.all_elasticache_replication_groups = config.getboolean('ec2', 'all_elasticache_replication_groups')
-        else:
-            self.all_elasticache_replication_groups = False
-
-        # Return all ElastiCache clusters? (if ElastiCache is enabled)
-        if config.has_option('ec2', 'all_elasticache_clusters') and self.elasticache_enabled:
-            self.all_elasticache_clusters = config.getboolean('ec2', 'all_elasticache_clusters')
-        else:
-            self.all_elasticache_clusters = False
-
-        # Return all ElastiCache nodes? (if ElastiCache is enabled)
-        if config.has_option('ec2', 'all_elasticache_nodes') and self.elasticache_enabled:
-            self.all_elasticache_nodes = config.getboolean('ec2', 'all_elasticache_nodes')
-        else:
-            self.all_elasticache_nodes = False
-
-        # boto configuration profile (prefer CLI argument)
-        self.boto_profile = self.args.boto_profile
-        if config.has_option('ec2', 'boto_profile') and not self.boto_profile:
-            self.boto_profile = config.get('ec2', 'boto_profile')
-
-        # Cache related
-        cache_dir = os.path.expanduser(config.get('ec2', 'cache_path'))
-        if self.boto_profile:
-            cache_dir = os.path.join(cache_dir, 'profile_' + self.boto_profile)
-        if not os.path.exists(cache_dir):
-            os.makedirs(cache_dir)
-
-        cache_name = 'ansible-ec2'
-        aws_profile = lambda: (self.boto_profile or
-                               os.environ.get('AWS_PROFILE') or
-                               os.environ.get('AWS_ACCESS_KEY_ID'))
-        if aws_profile():
-            cache_name = '%s-%s' % (cache_name, aws_profile())
-        self.cache_path_cache = cache_dir + "/%s.cache" % cache_name
-        self.cache_path_index = cache_dir + "/%s.index" % cache_name
-        self.cache_max_age = config.getint('ec2', 'cache_max_age')
-
-        if config.has_option('ec2', 'expand_csv_tags'):
-            self.expand_csv_tags = config.getboolean('ec2', 'expand_csv_tags')
-        else:
-            self.expand_csv_tags = False
-
-        # Configure nested groups instead of flat namespace.
-        if config.has_option('ec2', 'nested_groups'):
-            self.nested_groups = config.getboolean('ec2', 'nested_groups')
-        else:
-            self.nested_groups = False
-
-        # Replace dash or not in group names
-        if config.has_option('ec2', 'replace_dash_in_groups'):
-            self.replace_dash_in_groups = config.getboolean('ec2', 'replace_dash_in_groups')
-        else:
-            self.replace_dash_in_groups = True
-
-        # Configure which groups should be created.
-        group_by_options = [
-            'group_by_instance_id',
-            'group_by_region',
-            'group_by_availability_zone',
-            'group_by_ami_id',
-            'group_by_instance_type',
-            'group_by_key_pair',
-            'group_by_vpc_id',
-            'group_by_security_group',
-            'group_by_tag_keys',
-            'group_by_tag_none',
-            'group_by_route53_names',
-            'group_by_rds_engine',
-            'group_by_rds_parameter_group',
-            'group_by_elasticache_engine',
-            'group_by_elasticache_cluster',
-            'group_by_elasticache_parameter_group',
-            'group_by_elasticache_replication_group',
-        ]
-        for option in group_by_options:
-            if config.has_option('ec2', option):
-                setattr(self, option, config.getboolean('ec2', option))
-            else:
-                setattr(self, option, True)
-
-        # Do we need to just include hosts that match a pattern?
-        try:
-            pattern_include = config.get('ec2', 'pattern_include')
-            if pattern_include and len(pattern_include) > 0:
-                self.pattern_include = re.compile(pattern_include)
-            else:
-                self.pattern_include = None
-        except configparser.NoOptionError:
-            self.pattern_include = None
-
-        # Do we need to exclude hosts that match a pattern?
-        try:
-            pattern_exclude = config.get('ec2', 'pattern_exclude');
-            if pattern_exclude and len(pattern_exclude) > 0:
-                self.pattern_exclude = re.compile(pattern_exclude)
-            else:
-                self.pattern_exclude = None
-        except configparser.NoOptionError:
-            self.pattern_exclude = None
-
-        # Instance filters (see boto and EC2 API docs). Ignore invalid filters.
-        self.ec2_instance_filters = defaultdict(list)
-        if config.has_option('ec2', 'instance_filters'):
-
-            filters = [f for f in config.get('ec2', 'instance_filters').split(',') if f]
-
-            for instance_filter in filters:
-                instance_filter = instance_filter.strip()
-                if not instance_filter or '=' not in instance_filter:
-                    continue
-                filter_key, filter_value = [x.strip() for x in instance_filter.split('=', 1)]
-                if not filter_key:
-                    continue
-                self.ec2_instance_filters[filter_key].append(filter_value)
-
-    def parse_cli_args(self):
-        ''' Command line argument processing '''
-
-        parser = argparse.ArgumentParser(description='Produce an Ansible Inventory file based on EC2')
-        parser.add_argument('--list', action='store_true', default=True,
-                            help='List instances (default: True)')
-        parser.add_argument('--host', action='store',
-                            help='Get all the variables about a specific instance')
-        parser.add_argument('--refresh-cache', action='store_true', default=False,
-                            help='Force refresh of cache by making API requests to EC2 (default: False - use cache files)')
-        parser.add_argument('--profile', '--boto-profile', action='store', dest='boto_profile',
-                            help='Use boto profile for connections to EC2')
-        self.args = parser.parse_args()
-
-
-    def do_api_calls_update_cache(self):
-        ''' Do API calls to each region, and save data in cache files '''
-
-        if self.route53_enabled:
-            self.get_route53_records()
-
-        for region in self.regions:
-            self.get_instances_by_region(region)
-            if self.rds_enabled:
-                self.get_rds_instances_by_region(region)
-            if self.elasticache_enabled:
-                self.get_elasticache_clusters_by_region(region)
-                self.get_elasticache_replication_groups_by_region(region)
-
-        self.write_to_cache(self.inventory, self.cache_path_cache)
-        self.write_to_cache(self.index, self.cache_path_index)
-
-    def connect(self, region):
-        ''' create connection to api server'''
-        if self.eucalyptus:
-            conn = boto.connect_euca(host=self.eucalyptus_host)
-            conn.APIVersion = '2010-08-31'
-        else:
-            conn = self.connect_to_aws(ec2, region)
-        return conn
-
-    def boto_fix_security_token_in_profile(self, connect_args):
-        ''' monkey patch for boto issue boto/boto#2100 '''
-        profile = 'profile ' + self.boto_profile
-        if boto.config.has_option(profile, 'aws_security_token'):
-            connect_args['security_token'] = boto.config.get(profile, 'aws_security_token')
-        return connect_args
-
-    def connect_to_aws(self, module, region):
-        connect_args = {}
-
-        # only pass the profile name if it's set (as it is not supported by older boto versions)
-        if self.boto_profile:
-            connect_args['profile_name'] = self.boto_profile
-            self.boto_fix_security_token_in_profile(connect_args)
-
-        conn = module.connect_to_region(region, **connect_args)
-        # connect_to_region will fail "silently" by returning None if the region name is wrong or not supported
-        if conn is None:
-            self.fail_with_error("region name: %s likely not supported, or AWS is down.  connection to region failed." % region)
-        return conn
-
-    def get_instances_by_region(self, region):
-        ''' Makes an AWS EC2 API call to the list of instances in a particular
-        region '''
-
-        try:
-            conn = self.connect(region)
-            reservations = []
-            if self.ec2_instance_filters:
-                for filter_key, filter_values in self.ec2_instance_filters.items():
-                    reservations.extend(conn.get_all_instances(filters = { filter_key : filter_values }))
-            else:
-                reservations = conn.get_all_instances()
-
-            for reservation in reservations:
-                for instance in reservation.instances:
-                    self.add_instance(instance, region)
-
-        except boto.exception.BotoServerError as e:
-            if e.error_code == 'AuthFailure':
-                error = self.get_auth_error_message()
-            else:
-                backend = 'Eucalyptus' if self.eucalyptus else 'AWS'
-                error = "Error connecting to %s backend.\n%s" % (backend, e.message)
-            self.fail_with_error(error, 'getting EC2 instances')
-
-    def get_rds_instances_by_region(self, region):
-        ''' Makes an AWS API call to the list of RDS instances in a particular
-        region '''
-
-        try:
-            conn = self.connect_to_aws(rds, region)
-            if conn:
-                marker = None
-                while True:
-                    instances = conn.get_all_dbinstances(marker=marker)
-                    marker = instances.marker
-                    for instance in instances:
-                        self.add_rds_instance(instance, region)
-                    if not marker:
-                        break
-        except boto.exception.BotoServerError as e:
-            error = e.reason
-
-            if e.error_code == 'AuthFailure':
-                error = self.get_auth_error_message()
-            if not e.reason == "Forbidden":
-                error = "Looks like AWS RDS is down:\n%s" % e.message
-            self.fail_with_error(error, 'getting RDS instances')
-
-    def get_elasticache_clusters_by_region(self, region):
-        ''' Makes an AWS API call to the list of ElastiCache clusters (with
-        nodes' info) in a particular region.'''
-
-        # ElastiCache boto module doesn't provide a get_all_intances method,
-        # that's why we need to call describe directly (it would be called by
-        # the shorthand method anyway...)
-        try:
-            conn = self.connect_to_aws(elasticache, region)
-            if conn:
-                # show_cache_node_info = True
-                # because we also want nodes' information
-                response = conn.describe_cache_clusters(None, None, None, True)
-
-        except boto.exception.BotoServerError as e:
-            error = e.reason
-
-            if e.error_code == 'AuthFailure':
-                error = self.get_auth_error_message()
-            if not e.reason == "Forbidden":
-                error = "Looks like AWS ElastiCache is down:\n%s" % e.message
-            self.fail_with_error(error, 'getting ElastiCache clusters')
-
-        try:
-            # Boto also doesn't provide wrapper classes to CacheClusters or
-            # CacheNodes. Because of that wo can't make use of the get_list
-            # method in the AWSQueryConnection. Let's do the work manually
-            clusters = response['DescribeCacheClustersResponse']['DescribeCacheClustersResult']['CacheClusters']
-
-        except KeyError as e:
-            error = "ElastiCache query to AWS failed (unexpected format)."
-            self.fail_with_error(error, 'getting ElastiCache clusters')
-
-        for cluster in clusters:
-            self.add_elasticache_cluster(cluster, region)
-
-    def get_elasticache_replication_groups_by_region(self, region):
-        ''' Makes an AWS API call to the list of ElastiCache replication groups
-        in a particular region.'''
-
-        # ElastiCache boto module doesn't provide a get_all_intances method,
-        # that's why we need to call describe directly (it would be called by
-        # the shorthand method anyway...)
-        try:
-            conn = self.connect_to_aws(elasticache, region)
-            if conn:
-                response = conn.describe_replication_groups()
-
-        except boto.exception.BotoServerError as e:
-            error = e.reason
-
-            if e.error_code == 'AuthFailure':
-                error = self.get_auth_error_message()
-            if not e.reason == "Forbidden":
-                error = "Looks like AWS ElastiCache [Replication Groups] is down:\n%s" % e.message
-            self.fail_with_error(error, 'getting ElastiCache clusters')
-
-        try:
-            # Boto also doesn't provide wrapper classes to ReplicationGroups
-            # Because of that wo can't make use of the get_list method in the
-            # AWSQueryConnection. Let's do the work manually
-            replication_groups = response['DescribeReplicationGroupsResponse']['DescribeReplicationGroupsResult']['ReplicationGroups']
-
-        except KeyError as e:
-            error = "ElastiCache [Replication Groups] query to AWS failed (unexpected format)."
-            self.fail_with_error(error, 'getting ElastiCache clusters')
-
-        for replication_group in replication_groups:
-            self.add_elasticache_replication_group(replication_group, region)
-
-    def get_auth_error_message(self):
-        ''' create an informative error message if there is an issue authenticating'''
-        errors = ["Authentication error retrieving ec2 inventory."]
-        if None in [os.environ.get('AWS_ACCESS_KEY_ID'), os.environ.get('AWS_SECRET_ACCESS_KEY')]:
-            errors.append(' - No AWS_ACCESS_KEY_ID or AWS_SECRET_ACCESS_KEY environment vars found')
-        else:
-            errors.append(' - AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY environment vars found but may not be correct')
-
-        boto_paths = ['/etc/boto.cfg', '~/.boto', '~/.aws/credentials']
-        boto_config_found = list(p for p in boto_paths if os.path.isfile(os.path.expanduser(p)))
-        if len(boto_config_found) > 0:
-            errors.append(" - Boto configs found at '%s', but the credentials contained may not be correct" % ', '.join(boto_config_found))
-        else:
-            errors.append(" - No Boto config found at any expected location '%s'" % ', '.join(boto_paths))
-
-        return '\n'.join(errors)
-
-    def fail_with_error(self, err_msg, err_operation=None):
-        '''log an error to std err for ansible-playbook to consume and exit'''
-        if err_operation:
-            err_msg = 'ERROR: "{err_msg}", while: {err_operation}'.format(
-                    err_msg=err_msg, err_operation=err_operation)
-        sys.stderr.write(err_msg)
-        sys.exit(1)
-
-    def get_instance(self, region, instance_id):
-        conn = self.connect(region)
-
-        reservations = conn.get_all_instances([instance_id])
-        for reservation in reservations:
-            for instance in reservation.instances:
-                return instance
-
-    def add_instance(self, instance, region):
-        ''' Adds an instance to the inventory and index, as long as it is
-        addressable '''
-
-        # Only return instances with desired instance states
-        if instance.state not in self.ec2_instance_states:
-            return
-
-        # Select the best destination address
-        if self.destination_format and self.destination_format_tags:
-            dest = self.destination_format.format(*[ getattr(instance, 'tags').get(tag, '') for tag in self.destination_format_tags ])
-        elif instance.subnet_id:
-            dest = getattr(instance, self.vpc_destination_variable, None)
-            if dest is None:
-                dest = getattr(instance, 'tags').get(self.vpc_destination_variable, None)
-        else:
-            dest = getattr(instance, self.destination_variable, None)
-            if dest is None:
-                dest = getattr(instance, 'tags').get(self.destination_variable, None)
-
-        if not dest:
-            # Skip instances we cannot address (e.g. private VPC subnet)
-            return
-
-        # Set the inventory name
-        hostname = None
-        if self.hostname_variable:
-            if self.hostname_variable.startswith('tag_'):
-                hostname = instance.tags.get(self.hostname_variable[4:], None)
-            else:
-                hostname = getattr(instance, self.hostname_variable)
-
-        # If we can't get a nice hostname, use the destination address
-        if not hostname:
-            hostname = dest
-        else:
-            hostname = self.to_safe(hostname).lower()
-
-        # if we only want to include hosts that match a pattern, skip those that don't
-        if self.pattern_include and not self.pattern_include.match(hostname):
-            return
-
-        # if we need to exclude hosts that match a pattern, skip those
-        if self.pattern_exclude and self.pattern_exclude.match(hostname):
-            return
-
-        # Add to index
-        self.index[hostname] = [region, instance.id]
-
-        # Inventory: Group by instance ID (always a group of 1)
-        if self.group_by_instance_id:
-            self.inventory[instance.id] = [hostname]
-            if self.nested_groups:
-                self.push_group(self.inventory, 'instances', instance.id)
-
-        # Inventory: Group by region
-        if self.group_by_region:
-            self.push(self.inventory, region, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'regions', region)
-
-        # Inventory: Group by availability zone
-        if self.group_by_availability_zone:
-            self.push(self.inventory, instance.placement, hostname)
-            if self.nested_groups:
-                if self.group_by_region:
-                    self.push_group(self.inventory, region, instance.placement)
-                self.push_group(self.inventory, 'zones', instance.placement)
-
-        # Inventory: Group by Amazon Machine Image (AMI) ID
-        if self.group_by_ami_id:
-            ami_id = self.to_safe(instance.image_id)
-            self.push(self.inventory, ami_id, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'images', ami_id)
-
-        # Inventory: Group by instance type
-        if self.group_by_instance_type:
-            type_name = self.to_safe('type_' + instance.instance_type)
-            self.push(self.inventory, type_name, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'types', type_name)
-
-        # Inventory: Group by key pair
-        if self.group_by_key_pair and instance.key_name:
-            key_name = self.to_safe('key_' + instance.key_name)
-            self.push(self.inventory, key_name, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'keys', key_name)
-
-        # Inventory: Group by VPC
-        if self.group_by_vpc_id and instance.vpc_id:
-            vpc_id_name = self.to_safe('vpc_id_' + instance.vpc_id)
-            self.push(self.inventory, vpc_id_name, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'vpcs', vpc_id_name)
-
-        # Inventory: Group by security group
-        if self.group_by_security_group:
-            try:
-                for group in instance.groups:
-                    key = self.to_safe("security_group_" + group.name)
-                    self.push(self.inventory, key, hostname)
-                    if self.nested_groups:
-                        self.push_group(self.inventory, 'security_groups', key)
-            except AttributeError:
-                self.fail_with_error('\n'.join(['Package boto seems a bit older.',
-                                                'Please upgrade boto >= 2.3.0.']))
-
-        # Inventory: Group by tag keys
-        if self.group_by_tag_keys:
-            for k, v in instance.tags.items():
-                if self.expand_csv_tags and v and ',' in v:
-                    values = map(lambda x: x.strip(), v.split(','))
-                else:
-                    values = [v]
-
-                for v in values:
-                    if v:
-                        key = self.to_safe("tag_" + k + "=" + v)
-                    else:
-                        key = self.to_safe("tag_" + k)
-                    self.push(self.inventory, key, hostname)
-                    if self.nested_groups:
-                        self.push_group(self.inventory, 'tags', self.to_safe("tag_" + k))
-                        if v:
-                            self.push_group(self.inventory, self.to_safe("tag_" + k), key)
-
-        # Inventory: Group by Route53 domain names if enabled
-        if self.route53_enabled and self.group_by_route53_names:
-            route53_names = self.get_instance_route53_names(instance)
-            for name in route53_names:
-                self.push(self.inventory, name, hostname)
-                if self.nested_groups:
-                    self.push_group(self.inventory, 'route53', name)
-
-        # Global Tag: instances without tags
-        if self.group_by_tag_none and len(instance.tags) == 0:
-            self.push(self.inventory, 'tag_none', hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'tags', 'tag_none')
-
-        # Global Tag: tag all EC2 instances
-        self.push(self.inventory, 'ec2', hostname)
-
-        self.inventory["_meta"]["hostvars"][hostname] = self.get_host_info_dict_from_instance(instance)
-        self.inventory["_meta"]["hostvars"][hostname]['ansible_ssh_host'] = dest
-
-
-    def add_rds_instance(self, instance, region):
-        ''' Adds an RDS instance to the inventory and index, as long as it is
-        addressable '''
-
-        # Only want available instances unless all_rds_instances is True
-        if not self.all_rds_instances and instance.status != 'available':
-            return
-
-        # Select the best destination address
-        dest = instance.endpoint[0]
-
-        if not dest:
-            # Skip instances we cannot address (e.g. private VPC subnet)
-            return
-
-        # Set the inventory name
-        hostname = None
-        if self.hostname_variable:
-            if self.hostname_variable.startswith('tag_'):
-                hostname = instance.tags.get(self.hostname_variable[4:], None)
-            else:
-                hostname = getattr(instance, self.hostname_variable)
-
-        # If we can't get a nice hostname, use the destination address
-        if not hostname:
-            hostname = dest
-
-        hostname = self.to_safe(hostname).lower()
-
-        # Add to index
-        self.index[hostname] = [region, instance.id]
-
-        # Inventory: Group by instance ID (always a group of 1)
-        if self.group_by_instance_id:
-            self.inventory[instance.id] = [hostname]
-            if self.nested_groups:
-                self.push_group(self.inventory, 'instances', instance.id)
-
-        # Inventory: Group by region
-        if self.group_by_region:
-            self.push(self.inventory, region, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'regions', region)
-
-        # Inventory: Group by availability zone
-        if self.group_by_availability_zone:
-            self.push(self.inventory, instance.availability_zone, hostname)
-            if self.nested_groups:
-                if self.group_by_region:
-                    self.push_group(self.inventory, region, instance.availability_zone)
-                self.push_group(self.inventory, 'zones', instance.availability_zone)
-
-        # Inventory: Group by instance type
-        if self.group_by_instance_type:
-            type_name = self.to_safe('type_' + instance.instance_class)
-            self.push(self.inventory, type_name, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'types', type_name)
-
-        # Inventory: Group by VPC
-        if self.group_by_vpc_id and instance.subnet_group and instance.subnet_group.vpc_id:
-            vpc_id_name = self.to_safe('vpc_id_' + instance.subnet_group.vpc_id)
-            self.push(self.inventory, vpc_id_name, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'vpcs', vpc_id_name)
-
-        # Inventory: Group by security group
-        if self.group_by_security_group:
-            try:
-                if instance.security_group:
-                    key = self.to_safe("security_group_" + instance.security_group.name)
-                    self.push(self.inventory, key, hostname)
-                    if self.nested_groups:
-                        self.push_group(self.inventory, 'security_groups', key)
-
-            except AttributeError:
-                self.fail_with_error('\n'.join(['Package boto seems a bit older.',
-                                                'Please upgrade boto >= 2.3.0.']))
-
-
-        # Inventory: Group by engine
-        if self.group_by_rds_engine:
-            self.push(self.inventory, self.to_safe("rds_" + instance.engine), hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'rds_engines', self.to_safe("rds_" + instance.engine))
-
-        # Inventory: Group by parameter group
-        if self.group_by_rds_parameter_group:
-            self.push(self.inventory, self.to_safe("rds_parameter_group_" + instance.parameter_group.name), hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'rds_parameter_groups', self.to_safe("rds_parameter_group_" + instance.parameter_group.name))
-
-        # Global Tag: all RDS instances
-        self.push(self.inventory, 'rds', hostname)
-
-        self.inventory["_meta"]["hostvars"][hostname] = self.get_host_info_dict_from_instance(instance)
-        self.inventory["_meta"]["hostvars"][hostname]['ansible_ssh_host'] = dest
-
-    def add_elasticache_cluster(self, cluster, region):
-        ''' Adds an ElastiCache cluster to the inventory and index, as long as
-        it's nodes are addressable '''
-
-        # Only want available clusters unless all_elasticache_clusters is True
-        if not self.all_elasticache_clusters and cluster['CacheClusterStatus'] != 'available':
-            return
-
-        # Select the best destination address
-        if 'ConfigurationEndpoint' in cluster and cluster['ConfigurationEndpoint']:
-            # Memcached cluster
-            dest = cluster['ConfigurationEndpoint']['Address']
-            is_redis = False
-        else:
-            # Redis sigle node cluster
-            # Because all Redis clusters are single nodes, we'll merge the
-            # info from the cluster with info about the node
-            dest = cluster['CacheNodes'][0]['Endpoint']['Address']
-            is_redis = True
-
-        if not dest:
-            # Skip clusters we cannot address (e.g. private VPC subnet)
-            return
-
-        # Add to index
-        self.index[dest] = [region, cluster['CacheClusterId']]
-
-        # Inventory: Group by instance ID (always a group of 1)
-        if self.group_by_instance_id:
-            self.inventory[cluster['CacheClusterId']] = [dest]
-            if self.nested_groups:
-                self.push_group(self.inventory, 'instances', cluster['CacheClusterId'])
-
-        # Inventory: Group by region
-        if self.group_by_region and not is_redis:
-            self.push(self.inventory, region, dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'regions', region)
-
-        # Inventory: Group by availability zone
-        if self.group_by_availability_zone and not is_redis:
-            self.push(self.inventory, cluster['PreferredAvailabilityZone'], dest)
-            if self.nested_groups:
-                if self.group_by_region:
-                    self.push_group(self.inventory, region, cluster['PreferredAvailabilityZone'])
-                self.push_group(self.inventory, 'zones', cluster['PreferredAvailabilityZone'])
-
-        # Inventory: Group by node type
-        if self.group_by_instance_type and not is_redis:
-            type_name = self.to_safe('type_' + cluster['CacheNodeType'])
-            self.push(self.inventory, type_name, dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'types', type_name)
-
-        # Inventory: Group by VPC (information not available in the current
-        # AWS API version for ElastiCache)
-
-        # Inventory: Group by security group
-        if self.group_by_security_group and not is_redis:
-
-            # Check for the existence of the 'SecurityGroups' key and also if
-            # this key has some value. When the cluster is not placed in a SG
-            # the query can return None here and cause an error.
-            if 'SecurityGroups' in cluster and cluster['SecurityGroups'] is not None:
-                for security_group in cluster['SecurityGroups']:
-                    key = self.to_safe("security_group_" + security_group['SecurityGroupId'])
-                    self.push(self.inventory, key, dest)
-                    if self.nested_groups:
-                        self.push_group(self.inventory, 'security_groups', key)
-
-        # Inventory: Group by engine
-        if self.group_by_elasticache_engine and not is_redis:
-            self.push(self.inventory, self.to_safe("elasticache_" + cluster['Engine']), dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'elasticache_engines', self.to_safe(cluster['Engine']))
-
-        # Inventory: Group by parameter group
-        if self.group_by_elasticache_parameter_group:
-            self.push(self.inventory, self.to_safe("elasticache_parameter_group_" + cluster['CacheParameterGroup']['CacheParameterGroupName']), dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'elasticache_parameter_groups', self.to_safe(cluster['CacheParameterGroup']['CacheParameterGroupName']))
-
-        # Inventory: Group by replication group
-        if self.group_by_elasticache_replication_group and 'ReplicationGroupId' in cluster and cluster['ReplicationGroupId']:
-            self.push(self.inventory, self.to_safe("elasticache_replication_group_" + cluster['ReplicationGroupId']), dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'elasticache_replication_groups', self.to_safe(cluster['ReplicationGroupId']))
-
-        # Global Tag: all ElastiCache clusters
-        self.push(self.inventory, 'elasticache_clusters', cluster['CacheClusterId'])
-
-        host_info = self.get_host_info_dict_from_describe_dict(cluster)
-
-        self.inventory["_meta"]["hostvars"][dest] = host_info
-
-        # Add the nodes
-        for node in cluster['CacheNodes']:
-            self.add_elasticache_node(node, cluster, region)
-
-    def add_elasticache_node(self, node, cluster, region):
-        ''' Adds an ElastiCache node to the inventory and index, as long as
-        it is addressable '''
-
-        # Only want available nodes unless all_elasticache_nodes is True
-        if not self.all_elasticache_nodes and node['CacheNodeStatus'] != 'available':
-            return
-
-        # Select the best destination address
-        dest = node['Endpoint']['Address']
-
-        if not dest:
-            # Skip nodes we cannot address (e.g. private VPC subnet)
-            return
-
-        node_id = self.to_safe(cluster['CacheClusterId'] + '_' + node['CacheNodeId'])
-
-        # Add to index
-        self.index[dest] = [region, node_id]
-
-        # Inventory: Group by node ID (always a group of 1)
-        if self.group_by_instance_id:
-            self.inventory[node_id] = [dest]
-            if self.nested_groups:
-                self.push_group(self.inventory, 'instances', node_id)
-
-        # Inventory: Group by region
-        if self.group_by_region:
-            self.push(self.inventory, region, dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'regions', region)
-
-        # Inventory: Group by availability zone
-        if self.group_by_availability_zone:
-            self.push(self.inventory, cluster['PreferredAvailabilityZone'], dest)
-            if self.nested_groups:
-                if self.group_by_region:
-                    self.push_group(self.inventory, region, cluster['PreferredAvailabilityZone'])
-                self.push_group(self.inventory, 'zones', cluster['PreferredAvailabilityZone'])
-
-        # Inventory: Group by node type
-        if self.group_by_instance_type:
-            type_name = self.to_safe('type_' + cluster['CacheNodeType'])
-            self.push(self.inventory, type_name, dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'types', type_name)
-
-        # Inventory: Group by VPC (information not available in the current
-        # AWS API version for ElastiCache)
-
-        # Inventory: Group by security group
-        if self.group_by_security_group:
-
-            # Check for the existence of the 'SecurityGroups' key and also if
-            # this key has some value. When the cluster is not placed in a SG
-            # the query can return None here and cause an error.
-            if 'SecurityGroups' in cluster and cluster['SecurityGroups'] is not None:
-                for security_group in cluster['SecurityGroups']:
-                    key = self.to_safe("security_group_" + security_group['SecurityGroupId'])
-                    self.push(self.inventory, key, dest)
-                    if self.nested_groups:
-                        self.push_group(self.inventory, 'security_groups', key)
-
-        # Inventory: Group by engine
-        if self.group_by_elasticache_engine:
-            self.push(self.inventory, self.to_safe("elasticache_" + cluster['Engine']), dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'elasticache_engines', self.to_safe("elasticache_" + cluster['Engine']))
-
-        # Inventory: Group by parameter group (done at cluster level)
-
-        # Inventory: Group by replication group (done at cluster level)
-
-        # Inventory: Group by ElastiCache Cluster
-        if self.group_by_elasticache_cluster:
-            self.push(self.inventory, self.to_safe("elasticache_cluster_" + cluster['CacheClusterId']), dest)
-
-        # Global Tag: all ElastiCache nodes
-        self.push(self.inventory, 'elasticache_nodes', dest)
-
-        host_info = self.get_host_info_dict_from_describe_dict(node)
-
-        if dest in self.inventory["_meta"]["hostvars"]:
-            self.inventory["_meta"]["hostvars"][dest].update(host_info)
-        else:
-            self.inventory["_meta"]["hostvars"][dest] = host_info
-
-    def add_elasticache_replication_group(self, replication_group, region):
-        ''' Adds an ElastiCache replication group to the inventory and index '''
-
-        # Only want available clusters unless all_elasticache_replication_groups is True
-        if not self.all_elasticache_replication_groups and replication_group['Status'] != 'available':
-            return
-
-        # Select the best destination address (PrimaryEndpoint)
-        dest = replication_group['NodeGroups'][0]['PrimaryEndpoint']['Address']
-
-        if not dest:
-            # Skip clusters we cannot address (e.g. private VPC subnet)
-            return
-
-        # Add to index
-        self.index[dest] = [region, replication_group['ReplicationGroupId']]
-
-        # Inventory: Group by ID (always a group of 1)
-        if self.group_by_instance_id:
-            self.inventory[replication_group['ReplicationGroupId']] = [dest]
-            if self.nested_groups:
-                self.push_group(self.inventory, 'instances', replication_group['ReplicationGroupId'])
-
-        # Inventory: Group by region
-        if self.group_by_region:
-            self.push(self.inventory, region, dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'regions', region)
-
-        # Inventory: Group by availability zone (doesn't apply to replication groups)
-
-        # Inventory: Group by node type (doesn't apply to replication groups)
-
-        # Inventory: Group by VPC (information not available in the current
-        # AWS API version for replication groups
-
-        # Inventory: Group by security group (doesn't apply to replication groups)
-        # Check this value in cluster level
-
-        # Inventory: Group by engine (replication groups are always Redis)
-        if self.group_by_elasticache_engine:
-            self.push(self.inventory, 'elasticache_redis', dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'elasticache_engines', 'redis')
-
-        # Global Tag: all ElastiCache clusters
-        self.push(self.inventory, 'elasticache_replication_groups', replication_group['ReplicationGroupId'])
-
-        host_info = self.get_host_info_dict_from_describe_dict(replication_group)
-
-        self.inventory["_meta"]["hostvars"][dest] = host_info
-
-    def get_route53_records(self):
-        ''' Get and store the map of resource records to domain names that
-        point to them. '''
-
-        r53_conn = route53.Route53Connection()
-        all_zones = r53_conn.get_zones()
-
-        route53_zones = [ zone for zone in all_zones if zone.name[:-1]
-                          not in self.route53_excluded_zones ]
-
-        self.route53_records = {}
-
-        for zone in route53_zones:
-            rrsets = r53_conn.get_all_rrsets(zone.id)
-
-            for record_set in rrsets:
-                record_name = record_set.name
-
-                if record_name.endswith('.'):
-                    record_name = record_name[:-1]
-
-                for resource in record_set.resource_records:
-                    self.route53_records.setdefault(resource, set())
-                    self.route53_records[resource].add(record_name)
-
-
-    def get_instance_route53_names(self, instance):
-        ''' Check if an instance is referenced in the records we have from
-        Route53. If it is, return the list of domain names pointing to said
-        instance. If nothing points to it, return an empty list. '''
-
-        instance_attributes = [ 'public_dns_name', 'private_dns_name',
-                                'ip_address', 'private_ip_address' ]
-
-        name_list = set()
-
-        for attrib in instance_attributes:
-            try:
-                value = getattr(instance, attrib)
-            except AttributeError:
-                continue
-
-            if value in self.route53_records:
-                name_list.update(self.route53_records[value])
-
-        return list(name_list)
-
-    def get_host_info_dict_from_instance(self, instance):
-        instance_vars = {}
-        for key in vars(instance):
-            value = getattr(instance, key)
-            key = self.to_safe('ec2_' + key)
-
-            # Handle complex types
-            # state/previous_state changed to properties in boto in https://github.com/boto/boto/commit/a23c379837f698212252720d2af8dec0325c9518
-            if key == 'ec2__state':
-                instance_vars['ec2_state'] = instance.state or ''
-                instance_vars['ec2_state_code'] = instance.state_code
-            elif key == 'ec2__previous_state':
-                instance_vars['ec2_previous_state'] = instance.previous_state or ''
-                instance_vars['ec2_previous_state_code'] = instance.previous_state_code
-            elif type(value) in [int, bool]:
-                instance_vars[key] = value
-            elif isinstance(value, six.string_types):
-                instance_vars[key] = value.strip()
-            elif type(value) == type(None):
-                instance_vars[key] = ''
-            elif key == 'ec2_region':
-                instance_vars[key] = value.name
-            elif key == 'ec2__placement':
-                instance_vars['ec2_placement'] = value.zone
-            elif key == 'ec2_tags':
-                for k, v in value.items():
-                    if self.expand_csv_tags and ',' in v:
-                        v = map(lambda x: x.strip(), v.split(','))
-                    key = self.to_safe('ec2_tag_' + k)
-                    instance_vars[key] = v
-            elif key == 'ec2_groups':
-                group_ids = []
-                group_names = []
-                for group in value:
-                    group_ids.append(group.id)
-                    group_names.append(group.name)
-                instance_vars["ec2_security_group_ids"] = ','.join([str(i) for i in group_ids])
-                instance_vars["ec2_security_group_names"] = ','.join([str(i) for i in group_names])
-            else:
-                pass
-                # TODO Product codes if someone finds them useful
-                #print key
-                #print type(value)
-                #print value
-
-        return instance_vars
-
-    def get_host_info_dict_from_describe_dict(self, describe_dict):
-        ''' Parses the dictionary returned by the API call into a flat list
-            of parameters. This method should be used only when 'describe' is
-            used directly because Boto doesn't provide specific classes. '''
-
-        # I really don't agree with prefixing everything with 'ec2'
-        # because EC2, RDS and ElastiCache are different services.
-        # I'm just following the pattern used until now to not break any
-        # compatibility.
-
-        host_info = {}
-        for key in describe_dict:
-            value = describe_dict[key]
-            key = self.to_safe('ec2_' + self.uncammelize(key))
-
-            # Handle complex types
-
-            # Target: Memcached Cache Clusters
-            if key == 'ec2_configuration_endpoint' and value:
-                host_info['ec2_configuration_endpoint_address'] = value['Address']
-                host_info['ec2_configuration_endpoint_port'] = value['Port']
-
-            # Target: Cache Nodes and Redis Cache Clusters (single node)
-            if key == 'ec2_endpoint' and value:
-                host_info['ec2_endpoint_address'] = value['Address']
-                host_info['ec2_endpoint_port'] = value['Port']
-
-            # Target: Redis Replication Groups
-            if key == 'ec2_node_groups' and value:
-                host_info['ec2_endpoint_address'] = value[0]['PrimaryEndpoint']['Address']
-                host_info['ec2_endpoint_port'] = value[0]['PrimaryEndpoint']['Port']
-                replica_count = 0
-                for node in value[0]['NodeGroupMembers']:
-                    if node['CurrentRole'] == 'primary':
-                        host_info['ec2_primary_cluster_address'] = node['ReadEndpoint']['Address']
-                        host_info['ec2_primary_cluster_port'] = node['ReadEndpoint']['Port']
-                        host_info['ec2_primary_cluster_id'] = node['CacheClusterId']
-                    elif node['CurrentRole'] == 'replica':
-                        host_info['ec2_replica_cluster_address_'+ str(replica_count)] = node['ReadEndpoint']['Address']
-                        host_info['ec2_replica_cluster_port_'+ str(replica_count)] = node['ReadEndpoint']['Port']
-                        host_info['ec2_replica_cluster_id_'+ str(replica_count)] = node['CacheClusterId']
-                        replica_count += 1
-
-            # Target: Redis Replication Groups
-            if key == 'ec2_member_clusters' and value:
-                host_info['ec2_member_clusters'] = ','.join([str(i) for i in value])
-
-            # Target: All Cache Clusters
-            elif key == 'ec2_cache_parameter_group':
-                host_info["ec2_cache_node_ids_to_reboot"] = ','.join([str(i) for i in value['CacheNodeIdsToReboot']])
-                host_info['ec2_cache_parameter_group_name'] = value['CacheParameterGroupName']
-                host_info['ec2_cache_parameter_apply_status'] = value['ParameterApplyStatus']
-
-            # Target: Almost everything
-            elif key == 'ec2_security_groups':
-
-                # Skip if SecurityGroups is None
-                # (it is possible to have the key defined but no value in it).
-                if value is not None:
-                    sg_ids = []
-                    for sg in value:
-                        sg_ids.append(sg['SecurityGroupId'])
-                    host_info["ec2_security_group_ids"] = ','.join([str(i) for i in sg_ids])
-
-            # Target: Everything
-            # Preserve booleans and integers
-            elif type(value) in [int, bool]:
-                host_info[key] = value
-
-            # Target: Everything
-            # Sanitize string values
-            elif isinstance(value, six.string_types):
-                host_info[key] = value.strip()
-
-            # Target: Everything
-            # Replace None by an empty string
-            elif type(value) == type(None):
-                host_info[key] = ''
-
-            else:
-                # Remove non-processed complex types
-                pass
-
-        return host_info
-
-    def get_host_info(self):
-        ''' Get variables about a specific host '''
-
-        if len(self.index) == 0:
-            # Need to load index from cache
-            self.load_index_from_cache()
-
-        if not self.args.host in self.index:
-            # try updating the cache
-            self.do_api_calls_update_cache()
-            if not self.args.host in self.index:
-                # host might not exist anymore
-                return self.json_format_dict({}, True)
-
-        (region, instance_id) = self.index[self.args.host]
-
-        instance = self.get_instance(region, instance_id)
-        return self.json_format_dict(self.get_host_info_dict_from_instance(instance), True)
-
-    def push(self, my_dict, key, element):
-        ''' Push an element onto an array that may not have been defined in
-        the dict '''
-        group_info = my_dict.setdefault(key, [])
-        if isinstance(group_info, dict):
-            host_list = group_info.setdefault('hosts', [])
-            host_list.append(element)
-        else:
-            group_info.append(element)
-
-    def push_group(self, my_dict, key, element):
-        ''' Push a group as a child of another group. '''
-        parent_group = my_dict.setdefault(key, {})
-        if not isinstance(parent_group, dict):
-            parent_group = my_dict[key] = {'hosts': parent_group}
-        child_groups = parent_group.setdefault('children', [])
-        if element not in child_groups:
-            child_groups.append(element)
-
-    def get_inventory_from_cache(self):
-        ''' Reads the inventory from the cache file and returns it as a JSON
-        object '''
-
-        cache = open(self.cache_path_cache, 'r')
-        json_inventory = cache.read()
-        return json_inventory
-
-
-    def load_index_from_cache(self):
-        ''' Reads the index from the cache file sets self.index '''
-
-        cache = open(self.cache_path_index, 'r')
-        json_index = cache.read()
-        self.index = json.loads(json_index)
-
-
-    def write_to_cache(self, data, filename):
-        ''' Writes data in JSON format to a file '''
-
-        json_data = self.json_format_dict(data, True)
-        cache = open(filename, 'w')
-        cache.write(json_data)
-        cache.close()
-
-    def uncammelize(self, key):
-        temp = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', key)
-        return re.sub('([a-z0-9])([A-Z])', r'\1_\2', temp).lower()
-
-    def to_safe(self, word):
-        ''' Converts 'bad' characters in a string to underscores so they can be used as Ansible groups '''
-        regex = "[^A-Za-z0-9\_"
-        if not self.replace_dash_in_groups:
-            regex += "\-"
-        return re.sub(regex + "]", "_", word)
-
-    def json_format_dict(self, data, pretty=False):
-        ''' Converts a dict to a JSON object and dumps it as a formatted
-        string '''
-
-        if pretty:
-            return json.dumps(data, sort_keys=True, indent=2)
-        else:
-            return json.dumps(data)
-
-
-# Run the script
-Ec2Inventory()
diff --git a/baas-1701-dc5/inventory b/baas-1701-dc5/inventory
deleted file mode 100644
index dc769fe..0000000
--- a/baas-1701-dc5/inventory
+++ /dev/null
@@ -1,67 +0,0 @@
-[tag_Name_dc5_n1]
-[tag_Name_dc5_n2]
-[tag_Name_dc5_n3]
-[tag_Name_dc5_n4]
-[tag_Name_dc5_n5]
-[tag_Name_dc5_n6]
-[tag_Name_dc5_n7]
-[tag_Name_dc5_n8]
-[tag_Name_dc5_n9]
-[tag_Name_dc5_n10]
-
-[planet:children]
-dc-1
-
-[dc-1:children]
-tag_Name_dc5_n1
-tag_Name_dc5_n2
-tag_Name_dc5_n3
-tag_Name_dc5_n4
-tag_Name_dc5_n5
-tag_Name_dc5_n6
-tag_Name_dc5_n7
-tag_Name_dc5_n8
-tag_Name_dc5_n9
-tag_Name_dc5_n10
-
-[elastic:children]
-dc-1-elastic
-
-[dc-1-elastic:children]
-tag_Name_dc5_n1
-tag_Name_dc5_n2
-tag_Name_dc5_n3
-
-[baas:children]
-dc-1-baas
-
-[dc-1-baas:children]
-tag_Name_dc5_n4
-tag_Name_dc5_n5
-tag_Name_dc5_n6
-
-[portal:children]
-dc-1-portal
-
-[dc-1-portal:children]
-tag_Name_dc5_n7
-
-[ds:children]
-dc-1-ds
-
-[dc-1-ds:children]
-dc-1-cassandra
-
-[cassandra:children]
-dc-1-cassandra
-
-[dc-1-cassandra:children]
-tag_Name_dc5_n8
-tag_Name_dc5_n9
-tag_Name_dc5_n10
-
-[ms:children]
-dc-1-ms
-
-[dc-1-ms:children]
-tag_Name_dc5_n7
diff --git a/baas-1701-dc6/ec2.ini b/baas-1701-dc6/ec2.ini
deleted file mode 100644
index 36b3921..0000000
--- a/baas-1701-dc6/ec2.ini
+++ /dev/null
@@ -1,200 +0,0 @@
-# Ansible EC2 external inventory script settings
-#
-
-[ec2]
-
-# to talk to a private eucalyptus instance uncomment these lines
-# and edit edit eucalyptus_host to be the host name of your cloud controller
-#eucalyptus = True
-#eucalyptus_host = clc.cloud.domain.org
-
-# AWS regions to make calls to. Set this to 'all' to make request to all regions
-# in AWS and merge the results together. Alternatively, set this to a comma
-# separated list of regions. E.g. 'us-east-1,us-west-1,us-west-2'
-regions = all
-regions_exclude = us-gov-west-1,cn-north-1
-
-# When generating inventory, Ansible needs to know how to address a server.
-# Each EC2 instance has a lot of variables associated with it. Here is the list:
-#   http://docs.pythonboto.org/en/latest/ref/ec2.html#module-boto.ec2.instance
-# Below are 2 variables that are used as the address of a server:
-#   - destination_variable
-#   - vpc_destination_variable
-
-# This is the normal destination variable to use. If you are running Ansible
-# from outside EC2, then 'public_dns_name' makes the most sense. If you are
-# running Ansible from within EC2, then perhaps you want to use the internal
-# address, and should set this to 'private_dns_name'. The key of an EC2 tag
-# may optionally be used; however the boto instance variables hold precedence
-# in the event of a collision.
-destination_variable = public_dns_name
-
-# This allows you to override the inventory_name with an ec2 variable, instead
-# of using the destination_variable above. Addressing (aka ansible_ssh_host)
-# will still use destination_variable. Tags should be written as 'tag_TAGNAME'.
-#hostname_variable = tag_Name
-
-# For server inside a VPC, using DNS names may not make sense. When an instance
-# has 'subnet_id' set, this variable is used. If the subnet is public, setting
-# this to 'ip_address' will return the public IP address. For instances in a
-# private subnet, this should be set to 'private_ip_address', and Ansible must
-# be run from within EC2. The key of an EC2 tag may optionally be used; however
-# the boto instance variables hold precedence in the event of a collision.
-# WARNING: - instances that are in the private vpc, _without_ public ip address
-# will not be listed in the inventory until You set:
-# vpc_destination_variable = private_ip_address
-vpc_destination_variable = ip_address
-
-# The following two settings allow flexible ansible host naming based on a
-# python format string and a comma-separated list of ec2 tags.  Note that:
-#
-# 1) If the tags referenced are not present for some instances, empty strings
-#    will be substituted in the format string.
-# 2) This overrides both destination_variable and vpc_destination_variable.
-#
-#destination_format = {0}.{1}.example.com
-#destination_format_tags = Name,environment
-
-# To tag instances on EC2 with the resource records that point to them from
-# Route53, uncomment and set 'route53' to True.
-route53 = False
-
-# To exclude RDS instances from the inventory, uncomment and set to False.
-rds = False
-
-# To exclude ElastiCache instances from the inventory, uncomment and set to False.
-elasticache = False
-
-# Additionally, you can specify the list of zones to exclude looking up in
-# 'route53_excluded_zones' as a comma-separated list.
-# route53_excluded_zones = samplezone1.com, samplezone2.com
-
-# By default, only EC2 instances in the 'running' state are returned. Set
-# 'all_instances' to True to return all instances regardless of state.
-all_instances = True
-
-# By default, only EC2 instances in the 'running' state are returned. Specify
-# EC2 instance states to return as a comma-separated list. This
-# option is overriden when 'all_instances' is True.
-# instance_states = pending, running, shutting-down, terminated, stopping, stopped
-
-# By default, only RDS instances in the 'available' state are returned.  Set
-# 'all_rds_instances' to True return all RDS instances regardless of state.
-all_rds_instances = False
-
-# By default, only ElastiCache clusters and nodes in the 'available' state
-# are returned. Set 'all_elasticache_clusters' and/or 'all_elastic_nodes'
-# to True return all ElastiCache clusters and nodes, regardless of state.
-#
-# Note that all_elasticache_nodes only applies to listed clusters. That means
-# if you set all_elastic_clusters to false, no node will be return from
-# unavailable clusters, regardless of the state and to what you set for
-# all_elasticache_nodes.
-all_elasticache_replication_groups = False
-all_elasticache_clusters = False
-all_elasticache_nodes = False
-
-# API calls to EC2 are slow. For this reason, we cache the results of an API
-# call. Set this to the path you want cache files to be written to. Two files
-# will be written to this directory:
-#   - ansible-ec2.cache
-#   - ansible-ec2.index
-cache_path = ~/.ansible/tmp
-
-# The number of seconds a cache file is considered valid. After this many
-# seconds, a new API call will be made, and the cache file will be updated.
-# To disable the cache, set this value to 0
-cache_max_age = 300
-
-# Organize groups into a nested/hierarchy instead of a flat namespace.
-nested_groups = False
-
-# Replace - tags when creating groups to avoid issues with ansible
-replace_dash_in_groups = True
-
-# If set to true, any tag of the form "a,b,c" is expanded into a list
-# and the results are used to create additional tag_* inventory groups.
-expand_csv_tags = False
-
-# The EC2 inventory output can become very large. To manage its size,
-# configure which groups should be created.
-group_by_instance_id = True
-group_by_region = True
-group_by_availability_zone = True
-group_by_ami_id = True
-group_by_instance_type = True
-group_by_key_pair = True
-group_by_vpc_id = True
-group_by_security_group = True
-group_by_tag_keys = True
-group_by_tag_none = True
-group_by_route53_names = True
-group_by_rds_engine = False
-group_by_rds_parameter_group = False
-group_by_elasticache_engine = True
-group_by_elasticache_cluster = True
-group_by_elasticache_parameter_group = True
-group_by_elasticache_replication_group = True
-
-# If you only want to include hosts that match a certain regular expression
-# pattern_include = staging-*
-
-# If you want to exclude any hosts that match a certain regular expression
-# pattern_exclude = staging-*
-# Ansible EC2 external inventory script settings
-#
-
-##[ec2]
-##
-### to talk to a private eucalyptus instance uncomment these lines
-### and edit edit eucalyptus_host to be the host name of your cloud controller
-###eucalyptus = True
-###eucalyptus_host = clc.cloud.domain.org
-##
-### AWS regions to make calls to. Set this to 'all' to make request to all regions
-##
-### in AWS and merge the results together. Alternatively, set this to a comma
-### separated list of regions. E.g. 'us-east-1,us-west-1,us-west-2'
-##regions = all
-##regions_exclude = us-gov-west-1,cn-north-1
-##
-### When generating inventory, Ansible needs to know how to address a server.
-### Each EC2 instance has a lot of variables associated with it. Here is the list:
-###   http://docs.pythonboto.org/en/latest/ref/ec2.html#module-boto.ec2.instance
-### Below are 2 variables that are used as the address of a server:
-###   - destination_variable
-###   - vpc_destination_variable
-##
-### This is the normal destination variable to use. If you are running Ansible
-### from outside EC2, then 'public_dns_name' makes the most sense. If you are
-### running Ansible from within EC2, then perhaps you want to use the internal
-### address, and should set this to 'private_dns_name'. The key of an EC2 tag
-##...skipping...
-### pattern_include = staging-*
-##
-### If you want to exclude any hosts that match a certain regular expression
-### pattern_exclude = staging-*
-
-# Instance filters can be used to control which instances are retrieved for
-# inventory. For the full list of possible filters, please read the EC2 API
-# docs: http://docs.aws.amazon.com/AWSEC2/latest/APIReference/ApiReference-query-DescribeInstances.html#query-DescribeInstances-filters
-# Filters are key/value pairs separated by '=', to list multiple filters use
-# a list separated by commas. See examples below.
-
-# Retrieve only instances with (key=value) env=staging tag
-# instance_filters = tag:env=staging
-
-# Retrieve only instances with role=webservers OR role=dbservers tag
-# instance_filters = tag:role=webservers,tag:role=dbservers
-
-# Retrieve only t1.micro instances OR instances with tag env=staging
-# instance_filters = instance-type=t1.micro,tag:env=staging
-
-# You can use wildcards in filter values also. Below will list instances which
-# tag Name value matches webservers1*
-# (ex. webservers15, webservers1a, webservers123 etc)
-# instance_filters = tag:Name=webservers1*
-
-# A boto configuration profile may be used to separate out credentials
-# see http://boto.readthedocs.org/en/latest/boto_config_tut.html
-# boto_profile = some-boto-profile-name
diff --git a/baas-1701-dc6/ec2.py b/baas-1701-dc6/ec2.py
deleted file mode 100755
index f30958a..0000000
--- a/baas-1701-dc6/ec2.py
+++ /dev/null
@@ -1,1385 +0,0 @@
-#!/usr/bin/env python
-
-'''
-EC2 external inventory script
-=================================
-
-Generates inventory that Ansible can understand by making API request to
-AWS EC2 using the Boto library.
-
-NOTE: This script assumes Ansible is being executed where the environment
-variables needed for Boto have already been set:
-    export AWS_ACCESS_KEY_ID='AK123'
-    export AWS_SECRET_ACCESS_KEY='abc123'
-
-This script also assumes there is an ec2.ini file alongside it.  To specify a
-different path to ec2.ini, define the EC2_INI_PATH environment variable:
-
-    export EC2_INI_PATH=/path/to/my_ec2.ini
-
-If you're using eucalyptus you need to set the above variables and
-you need to define:
-
-    export EC2_URL=http://hostname_of_your_cc:port/services/Eucalyptus
-
-If you're using boto profiles (requires boto>=2.24.0) you can choose a profile
-using the --boto-profile command line argument (e.g. ec2.py --boto-profile prod) or using
-the AWS_PROFILE variable:
-
-    AWS_PROFILE=prod ansible-playbook -i ec2.py myplaybook.yml
-
-For more details, see: http://docs.pythonboto.org/en/latest/boto_config_tut.html
-
-When run against a specific host, this script returns the following variables:
- - ec2_ami_launch_index
- - ec2_architecture
- - ec2_association
- - ec2_attachTime
- - ec2_attachment
- - ec2_attachmentId
- - ec2_client_token
- - ec2_deleteOnTermination
- - ec2_description
- - ec2_deviceIndex
- - ec2_dns_name
- - ec2_eventsSet
- - ec2_group_name
- - ec2_hypervisor
- - ec2_id
- - ec2_image_id
- - ec2_instanceState
- - ec2_instance_type
- - ec2_ipOwnerId
- - ec2_ip_address
- - ec2_item
- - ec2_kernel
- - ec2_key_name
- - ec2_launch_time
- - ec2_monitored
- - ec2_monitoring
- - ec2_networkInterfaceId
- - ec2_ownerId
- - ec2_persistent
- - ec2_placement
- - ec2_platform
- - ec2_previous_state
- - ec2_private_dns_name
- - ec2_private_ip_address
- - ec2_publicIp
- - ec2_public_dns_name
- - ec2_ramdisk
- - ec2_reason
- - ec2_region
- - ec2_requester_id
- - ec2_root_device_name
- - ec2_root_device_type
- - ec2_security_group_ids
- - ec2_security_group_names
- - ec2_shutdown_state
- - ec2_sourceDestCheck
- - ec2_spot_instance_request_id
- - ec2_state
- - ec2_state_code
- - ec2_state_reason
- - ec2_status
- - ec2_subnet_id
- - ec2_tenancy
- - ec2_virtualization_type
- - ec2_vpc_id
-
-These variables are pulled out of a boto.ec2.instance object. There is a lack of
-consistency with variable spellings (camelCase and underscores) since this
-just loops through all variables the object exposes. It is preferred to use the
-ones with underscores when multiple exist.
-
-In addition, if an instance has AWS Tags associated with it, each tag is a new
-variable named:
- - ec2_tag_[Key] = [Value]
-
-Security groups are comma-separated in 'ec2_security_group_ids' and
-'ec2_security_group_names'.
-'''
-
-# (c) 2012, Peter Sankauskas
-#
-# This file is part of Ansible,
-#
-# Ansible is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# Ansible is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with Ansible.  If not, see <http://www.gnu.org/licenses/>.
-
-######################################################################
-
-import sys
-import os
-import argparse
-import re
-from time import time
-import boto
-from boto import ec2
-from boto import rds
-from boto import elasticache
-from boto import route53
-import six
-
-from six.moves import configparser
-from collections import defaultdict
-
-try:
-    import json
-except ImportError:
-    import simplejson as json
-
-
-class Ec2Inventory(object):
-
-    def _empty_inventory(self):
-        return {"_meta" : {"hostvars" : {}}}
-
-    def __init__(self):
-        ''' Main execution path '''
-
-        # Inventory grouped by instance IDs, tags, security groups, regions,
-        # and availability zones
-        self.inventory = self._empty_inventory()
-
-        # Index of hostname (address) to instance ID
-        self.index = {}
-
-        # Boto profile to use (if any)
-        self.boto_profile = None
-
-        # Read settings and parse CLI arguments
-        self.parse_cli_args()
-        self.read_settings()
-
-        # Make sure that profile_name is not passed at all if not set
-        # as pre 2.24 boto will fall over otherwise
-        if self.boto_profile:
-            if not hasattr(boto.ec2.EC2Connection, 'profile_name'):
-                self.fail_with_error("boto version must be >= 2.24 to use profile")
-
-        # Cache
-        if self.args.refresh_cache:
-            self.do_api_calls_update_cache()
-        elif not self.is_cache_valid():
-            self.do_api_calls_update_cache()
-
-        # Data to print
-        if self.args.host:
-            data_to_print = self.get_host_info()
-
-        elif self.args.list:
-            # Display list of instances for inventory
-            if self.inventory == self._empty_inventory():
-                data_to_print = self.get_inventory_from_cache()
-            else:
-                data_to_print = self.json_format_dict(self.inventory, True)
-
-        print(data_to_print)
-
-
-    def is_cache_valid(self):
-        ''' Determines if the cache files have expired, or if it is still valid '''
-
-        if os.path.isfile(self.cache_path_cache):
-            mod_time = os.path.getmtime(self.cache_path_cache)
-            current_time = time()
-            if (mod_time + self.cache_max_age) > current_time:
-                if os.path.isfile(self.cache_path_index):
-                    return True
-
-        return False
-
-
-    def read_settings(self):
-        ''' Reads the settings from the ec2.ini file '''
-        if six.PY3:
-            config = configparser.ConfigParser()
-        else:
-            config = configparser.SafeConfigParser()
-        ec2_default_ini_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'ec2.ini')
-        ec2_ini_path = os.path.expanduser(os.path.expandvars(os.environ.get('EC2_INI_PATH', ec2_default_ini_path)))
-        config.read(ec2_ini_path)
-
-        # is eucalyptus?
-        self.eucalyptus_host = None
-        self.eucalyptus = False
-        if config.has_option('ec2', 'eucalyptus'):
-            self.eucalyptus = config.getboolean('ec2', 'eucalyptus')
-        if self.eucalyptus and config.has_option('ec2', 'eucalyptus_host'):
-            self.eucalyptus_host = config.get('ec2', 'eucalyptus_host')
-
-        # Regions
-        self.regions = []
-        configRegions = config.get('ec2', 'regions')
-        configRegions_exclude = config.get('ec2', 'regions_exclude')
-        if (configRegions == 'all'):
-            if self.eucalyptus_host:
-                self.regions.append(boto.connect_euca(host=self.eucalyptus_host).region.name)
-            else:
-                for regionInfo in ec2.regions():
-                    if regionInfo.name not in configRegions_exclude:
-                        self.regions.append(regionInfo.name)
-        else:
-            self.regions = configRegions.split(",")
-
-        # Destination addresses
-        self.destination_variable = config.get('ec2', 'destination_variable')
-        self.vpc_destination_variable = config.get('ec2', 'vpc_destination_variable')
-
-        if config.has_option('ec2', 'hostname_variable'):
-            self.hostname_variable = config.get('ec2', 'hostname_variable')
-        else:
-            self.hostname_variable = None
-
-        if config.has_option('ec2', 'destination_format') and \
-                config.has_option('ec2', 'destination_format_tags'):
-            self.destination_format = config.get('ec2', 'destination_format')
-            self.destination_format_tags = config.get('ec2', 'destination_format_tags').split(',')
-        else:
-            self.destination_format = None
-            self.destination_format_tags = None
-
-        # Route53
-        self.route53_enabled = config.getboolean('ec2', 'route53')
-        self.route53_excluded_zones = []
-        if config.has_option('ec2', 'route53_excluded_zones'):
-            self.route53_excluded_zones.extend(
-                    config.get('ec2', 'route53_excluded_zones', '').split(','))
-
-        # Include RDS instances?
-        self.rds_enabled = True
-        if config.has_option('ec2', 'rds'):
-            self.rds_enabled = config.getboolean('ec2', 'rds')
-
-        # Include ElastiCache instances?
-        self.elasticache_enabled = True
-        if config.has_option('ec2', 'elasticache'):
-            self.elasticache_enabled = config.getboolean('ec2', 'elasticache')
-
-        # Return all EC2 instances?
-        if config.has_option('ec2', 'all_instances'):
-            self.all_instances = config.getboolean('ec2', 'all_instances')
-        else:
-            self.all_instances = False
-
-        # Instance states to be gathered in inventory. Default is 'running'.
-        # Setting 'all_instances' to 'yes' overrides this option.
-        ec2_valid_instance_states = [
-            'pending',
-            'running',
-            'shutting-down',
-            'terminated',
-            'stopping',
-            'stopped'
-        ]
-        self.ec2_instance_states = []
-        if self.all_instances:
-            self.ec2_instance_states = ec2_valid_instance_states
-        elif config.has_option('ec2', 'instance_states'):
-            for instance_state in config.get('ec2', 'instance_states').split(','):
-                instance_state = instance_state.strip()
-                if instance_state not in ec2_valid_instance_states:
-                    continue
-                self.ec2_instance_states.append(instance_state)
-        else:
-            self.ec2_instance_states = ['running']
-
-        # Return all RDS instances? (if RDS is enabled)
-        if config.has_option('ec2', 'all_rds_instances') and self.rds_enabled:
-            self.all_rds_instances = config.getboolean('ec2', 'all_rds_instances')
-        else:
-            self.all_rds_instances = False
-
-        # Return all ElastiCache replication groups? (if ElastiCache is enabled)
-        if config.has_option('ec2', 'all_elasticache_replication_groups') and self.elasticache_enabled:
-            self.all_elasticache_replication_groups = config.getboolean('ec2', 'all_elasticache_replication_groups')
-        else:
-            self.all_elasticache_replication_groups = False
-
-        # Return all ElastiCache clusters? (if ElastiCache is enabled)
-        if config.has_option('ec2', 'all_elasticache_clusters') and self.elasticache_enabled:
-            self.all_elasticache_clusters = config.getboolean('ec2', 'all_elasticache_clusters')
-        else:
-            self.all_elasticache_clusters = False
-
-        # Return all ElastiCache nodes? (if ElastiCache is enabled)
-        if config.has_option('ec2', 'all_elasticache_nodes') and self.elasticache_enabled:
-            self.all_elasticache_nodes = config.getboolean('ec2', 'all_elasticache_nodes')
-        else:
-            self.all_elasticache_nodes = False
-
-        # boto configuration profile (prefer CLI argument)
-        self.boto_profile = self.args.boto_profile
-        if config.has_option('ec2', 'boto_profile') and not self.boto_profile:
-            self.boto_profile = config.get('ec2', 'boto_profile')
-
-        # Cache related
-        cache_dir = os.path.expanduser(config.get('ec2', 'cache_path'))
-        if self.boto_profile:
-            cache_dir = os.path.join(cache_dir, 'profile_' + self.boto_profile)
-        if not os.path.exists(cache_dir):
-            os.makedirs(cache_dir)
-
-        cache_name = 'ansible-ec2'
-        aws_profile = lambda: (self.boto_profile or
-                               os.environ.get('AWS_PROFILE') or
-                               os.environ.get('AWS_ACCESS_KEY_ID'))
-        if aws_profile():
-            cache_name = '%s-%s' % (cache_name, aws_profile())
-        self.cache_path_cache = cache_dir + "/%s.cache" % cache_name
-        self.cache_path_index = cache_dir + "/%s.index" % cache_name
-        self.cache_max_age = config.getint('ec2', 'cache_max_age')
-
-        if config.has_option('ec2', 'expand_csv_tags'):
-            self.expand_csv_tags = config.getboolean('ec2', 'expand_csv_tags')
-        else:
-            self.expand_csv_tags = False
-
-        # Configure nested groups instead of flat namespace.
-        if config.has_option('ec2', 'nested_groups'):
-            self.nested_groups = config.getboolean('ec2', 'nested_groups')
-        else:
-            self.nested_groups = False
-
-        # Replace dash or not in group names
-        if config.has_option('ec2', 'replace_dash_in_groups'):
-            self.replace_dash_in_groups = config.getboolean('ec2', 'replace_dash_in_groups')
-        else:
-            self.replace_dash_in_groups = True
-
-        # Configure which groups should be created.
-        group_by_options = [
-            'group_by_instance_id',
-            'group_by_region',
-            'group_by_availability_zone',
-            'group_by_ami_id',
-            'group_by_instance_type',
-            'group_by_key_pair',
-            'group_by_vpc_id',
-            'group_by_security_group',
-            'group_by_tag_keys',
-            'group_by_tag_none',
-            'group_by_route53_names',
-            'group_by_rds_engine',
-            'group_by_rds_parameter_group',
-            'group_by_elasticache_engine',
-            'group_by_elasticache_cluster',
-            'group_by_elasticache_parameter_group',
-            'group_by_elasticache_replication_group',
-        ]
-        for option in group_by_options:
-            if config.has_option('ec2', option):
-                setattr(self, option, config.getboolean('ec2', option))
-            else:
-                setattr(self, option, True)
-
-        # Do we need to just include hosts that match a pattern?
-        try:
-            pattern_include = config.get('ec2', 'pattern_include')
-            if pattern_include and len(pattern_include) > 0:
-                self.pattern_include = re.compile(pattern_include)
-            else:
-                self.pattern_include = None
-        except configparser.NoOptionError:
-            self.pattern_include = None
-
-        # Do we need to exclude hosts that match a pattern?
-        try:
-            pattern_exclude = config.get('ec2', 'pattern_exclude');
-            if pattern_exclude and len(pattern_exclude) > 0:
-                self.pattern_exclude = re.compile(pattern_exclude)
-            else:
-                self.pattern_exclude = None
-        except configparser.NoOptionError:
-            self.pattern_exclude = None
-
-        # Instance filters (see boto and EC2 API docs). Ignore invalid filters.
-        self.ec2_instance_filters = defaultdict(list)
-        if config.has_option('ec2', 'instance_filters'):
-
-            filters = [f for f in config.get('ec2', 'instance_filters').split(',') if f]
-
-            for instance_filter in filters:
-                instance_filter = instance_filter.strip()
-                if not instance_filter or '=' not in instance_filter:
-                    continue
-                filter_key, filter_value = [x.strip() for x in instance_filter.split('=', 1)]
-                if not filter_key:
-                    continue
-                self.ec2_instance_filters[filter_key].append(filter_value)
-
-    def parse_cli_args(self):
-        ''' Command line argument processing '''
-
-        parser = argparse.ArgumentParser(description='Produce an Ansible Inventory file based on EC2')
-        parser.add_argument('--list', action='store_true', default=True,
-                            help='List instances (default: True)')
-        parser.add_argument('--host', action='store',
-                            help='Get all the variables about a specific instance')
-        parser.add_argument('--refresh-cache', action='store_true', default=False,
-                            help='Force refresh of cache by making API requests to EC2 (default: False - use cache files)')
-        parser.add_argument('--profile', '--boto-profile', action='store', dest='boto_profile',
-                            help='Use boto profile for connections to EC2')
-        self.args = parser.parse_args()
-
-
-    def do_api_calls_update_cache(self):
-        ''' Do API calls to each region, and save data in cache files '''
-
-        if self.route53_enabled:
-            self.get_route53_records()
-
-        for region in self.regions:
-            self.get_instances_by_region(region)
-            if self.rds_enabled:
-                self.get_rds_instances_by_region(region)
-            if self.elasticache_enabled:
-                self.get_elasticache_clusters_by_region(region)
-                self.get_elasticache_replication_groups_by_region(region)
-
-        self.write_to_cache(self.inventory, self.cache_path_cache)
-        self.write_to_cache(self.index, self.cache_path_index)
-
-    def connect(self, region):
-        ''' create connection to api server'''
-        if self.eucalyptus:
-            conn = boto.connect_euca(host=self.eucalyptus_host)
-            conn.APIVersion = '2010-08-31'
-        else:
-            conn = self.connect_to_aws(ec2, region)
-        return conn
-
-    def boto_fix_security_token_in_profile(self, connect_args):
-        ''' monkey patch for boto issue boto/boto#2100 '''
-        profile = 'profile ' + self.boto_profile
-        if boto.config.has_option(profile, 'aws_security_token'):
-            connect_args['security_token'] = boto.config.get(profile, 'aws_security_token')
-        return connect_args
-
-    def connect_to_aws(self, module, region):
-        connect_args = {}
-
-        # only pass the profile name if it's set (as it is not supported by older boto versions)
-        if self.boto_profile:
-            connect_args['profile_name'] = self.boto_profile
-            self.boto_fix_security_token_in_profile(connect_args)
-
-        conn = module.connect_to_region(region, **connect_args)
-        # connect_to_region will fail "silently" by returning None if the region name is wrong or not supported
-        if conn is None:
-            self.fail_with_error("region name: %s likely not supported, or AWS is down.  connection to region failed." % region)
-        return conn
-
-    def get_instances_by_region(self, region):
-        ''' Makes an AWS EC2 API call to the list of instances in a particular
-        region '''
-
-        try:
-            conn = self.connect(region)
-            reservations = []
-            if self.ec2_instance_filters:
-                for filter_key, filter_values in self.ec2_instance_filters.items():
-                    reservations.extend(conn.get_all_instances(filters = { filter_key : filter_values }))
-            else:
-                reservations = conn.get_all_instances()
-
-            for reservation in reservations:
-                for instance in reservation.instances:
-                    self.add_instance(instance, region)
-
-        except boto.exception.BotoServerError as e:
-            if e.error_code == 'AuthFailure':
-                error = self.get_auth_error_message()
-            else:
-                backend = 'Eucalyptus' if self.eucalyptus else 'AWS'
-                error = "Error connecting to %s backend.\n%s" % (backend, e.message)
-            self.fail_with_error(error, 'getting EC2 instances')
-
-    def get_rds_instances_by_region(self, region):
-        ''' Makes an AWS API call to the list of RDS instances in a particular
-        region '''
-
-        try:
-            conn = self.connect_to_aws(rds, region)
-            if conn:
-                marker = None
-                while True:
-                    instances = conn.get_all_dbinstances(marker=marker)
-                    marker = instances.marker
-                    for instance in instances:
-                        self.add_rds_instance(instance, region)
-                    if not marker:
-                        break
-        except boto.exception.BotoServerError as e:
-            error = e.reason
-
-            if e.error_code == 'AuthFailure':
-                error = self.get_auth_error_message()
-            if not e.reason == "Forbidden":
-                error = "Looks like AWS RDS is down:\n%s" % e.message
-            self.fail_with_error(error, 'getting RDS instances')
-
-    def get_elasticache_clusters_by_region(self, region):
-        ''' Makes an AWS API call to the list of ElastiCache clusters (with
-        nodes' info) in a particular region.'''
-
-        # ElastiCache boto module doesn't provide a get_all_intances method,
-        # that's why we need to call describe directly (it would be called by
-        # the shorthand method anyway...)
-        try:
-            conn = self.connect_to_aws(elasticache, region)
-            if conn:
-                # show_cache_node_info = True
-                # because we also want nodes' information
-                response = conn.describe_cache_clusters(None, None, None, True)
-
-        except boto.exception.BotoServerError as e:
-            error = e.reason
-
-            if e.error_code == 'AuthFailure':
-                error = self.get_auth_error_message()
-            if not e.reason == "Forbidden":
-                error = "Looks like AWS ElastiCache is down:\n%s" % e.message
-            self.fail_with_error(error, 'getting ElastiCache clusters')
-
-        try:
-            # Boto also doesn't provide wrapper classes to CacheClusters or
-            # CacheNodes. Because of that wo can't make use of the get_list
-            # method in the AWSQueryConnection. Let's do the work manually
-            clusters = response['DescribeCacheClustersResponse']['DescribeCacheClustersResult']['CacheClusters']
-
-        except KeyError as e:
-            error = "ElastiCache query to AWS failed (unexpected format)."
-            self.fail_with_error(error, 'getting ElastiCache clusters')
-
-        for cluster in clusters:
-            self.add_elasticache_cluster(cluster, region)
-
-    def get_elasticache_replication_groups_by_region(self, region):
-        ''' Makes an AWS API call to the list of ElastiCache replication groups
-        in a particular region.'''
-
-        # ElastiCache boto module doesn't provide a get_all_intances method,
-        # that's why we need to call describe directly (it would be called by
-        # the shorthand method anyway...)
-        try:
-            conn = self.connect_to_aws(elasticache, region)
-            if conn:
-                response = conn.describe_replication_groups()
-
-        except boto.exception.BotoServerError as e:
-            error = e.reason
-
-            if e.error_code == 'AuthFailure':
-                error = self.get_auth_error_message()
-            if not e.reason == "Forbidden":
-                error = "Looks like AWS ElastiCache [Replication Groups] is down:\n%s" % e.message
-            self.fail_with_error(error, 'getting ElastiCache clusters')
-
-        try:
-            # Boto also doesn't provide wrapper classes to ReplicationGroups
-            # Because of that wo can't make use of the get_list method in the
-            # AWSQueryConnection. Let's do the work manually
-            replication_groups = response['DescribeReplicationGroupsResponse']['DescribeReplicationGroupsResult']['ReplicationGroups']
-
-        except KeyError as e:
-            error = "ElastiCache [Replication Groups] query to AWS failed (unexpected format)."
-            self.fail_with_error(error, 'getting ElastiCache clusters')
-
-        for replication_group in replication_groups:
-            self.add_elasticache_replication_group(replication_group, region)
-
-    def get_auth_error_message(self):
-        ''' create an informative error message if there is an issue authenticating'''
-        errors = ["Authentication error retrieving ec2 inventory."]
-        if None in [os.environ.get('AWS_ACCESS_KEY_ID'), os.environ.get('AWS_SECRET_ACCESS_KEY')]:
-            errors.append(' - No AWS_ACCESS_KEY_ID or AWS_SECRET_ACCESS_KEY environment vars found')
-        else:
-            errors.append(' - AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY environment vars found but may not be correct')
-
-        boto_paths = ['/etc/boto.cfg', '~/.boto', '~/.aws/credentials']
-        boto_config_found = list(p for p in boto_paths if os.path.isfile(os.path.expanduser(p)))
-        if len(boto_config_found) > 0:
-            errors.append(" - Boto configs found at '%s', but the credentials contained may not be correct" % ', '.join(boto_config_found))
-        else:
-            errors.append(" - No Boto config found at any expected location '%s'" % ', '.join(boto_paths))
-
-        return '\n'.join(errors)
-
-    def fail_with_error(self, err_msg, err_operation=None):
-        '''log an error to std err for ansible-playbook to consume and exit'''
-        if err_operation:
-            err_msg = 'ERROR: "{err_msg}", while: {err_operation}'.format(
-                    err_msg=err_msg, err_operation=err_operation)
-        sys.stderr.write(err_msg)
-        sys.exit(1)
-
-    def get_instance(self, region, instance_id):
-        conn = self.connect(region)
-
-        reservations = conn.get_all_instances([instance_id])
-        for reservation in reservations:
-            for instance in reservation.instances:
-                return instance
-
-    def add_instance(self, instance, region):
-        ''' Adds an instance to the inventory and index, as long as it is
-        addressable '''
-
-        # Only return instances with desired instance states
-        if instance.state not in self.ec2_instance_states:
-            return
-
-        # Select the best destination address
-        if self.destination_format and self.destination_format_tags:
-            dest = self.destination_format.format(*[ getattr(instance, 'tags').get(tag, '') for tag in self.destination_format_tags ])
-        elif instance.subnet_id:
-            dest = getattr(instance, self.vpc_destination_variable, None)
-            if dest is None:
-                dest = getattr(instance, 'tags').get(self.vpc_destination_variable, None)
-        else:
-            dest = getattr(instance, self.destination_variable, None)
-            if dest is None:
-                dest = getattr(instance, 'tags').get(self.destination_variable, None)
-
-        if not dest:
-            # Skip instances we cannot address (e.g. private VPC subnet)
-            return
-
-        # Set the inventory name
-        hostname = None
-        if self.hostname_variable:
-            if self.hostname_variable.startswith('tag_'):
-                hostname = instance.tags.get(self.hostname_variable[4:], None)
-            else:
-                hostname = getattr(instance, self.hostname_variable)
-
-        # If we can't get a nice hostname, use the destination address
-        if not hostname:
-            hostname = dest
-        else:
-            hostname = self.to_safe(hostname).lower()
-
-        # if we only want to include hosts that match a pattern, skip those that don't
-        if self.pattern_include and not self.pattern_include.match(hostname):
-            return
-
-        # if we need to exclude hosts that match a pattern, skip those
-        if self.pattern_exclude and self.pattern_exclude.match(hostname):
-            return
-
-        # Add to index
-        self.index[hostname] = [region, instance.id]
-
-        # Inventory: Group by instance ID (always a group of 1)
-        if self.group_by_instance_id:
-            self.inventory[instance.id] = [hostname]
-            if self.nested_groups:
-                self.push_group(self.inventory, 'instances', instance.id)
-
-        # Inventory: Group by region
-        if self.group_by_region:
-            self.push(self.inventory, region, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'regions', region)
-
-        # Inventory: Group by availability zone
-        if self.group_by_availability_zone:
-            self.push(self.inventory, instance.placement, hostname)
-            if self.nested_groups:
-                if self.group_by_region:
-                    self.push_group(self.inventory, region, instance.placement)
-                self.push_group(self.inventory, 'zones', instance.placement)
-
-        # Inventory: Group by Amazon Machine Image (AMI) ID
-        if self.group_by_ami_id:
-            ami_id = self.to_safe(instance.image_id)
-            self.push(self.inventory, ami_id, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'images', ami_id)
-
-        # Inventory: Group by instance type
-        if self.group_by_instance_type:
-            type_name = self.to_safe('type_' + instance.instance_type)
-            self.push(self.inventory, type_name, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'types', type_name)
-
-        # Inventory: Group by key pair
-        if self.group_by_key_pair and instance.key_name:
-            key_name = self.to_safe('key_' + instance.key_name)
-            self.push(self.inventory, key_name, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'keys', key_name)
-
-        # Inventory: Group by VPC
-        if self.group_by_vpc_id and instance.vpc_id:
-            vpc_id_name = self.to_safe('vpc_id_' + instance.vpc_id)
-            self.push(self.inventory, vpc_id_name, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'vpcs', vpc_id_name)
-
-        # Inventory: Group by security group
-        if self.group_by_security_group:
-            try:
-                for group in instance.groups:
-                    key = self.to_safe("security_group_" + group.name)
-                    self.push(self.inventory, key, hostname)
-                    if self.nested_groups:
-                        self.push_group(self.inventory, 'security_groups', key)
-            except AttributeError:
-                self.fail_with_error('\n'.join(['Package boto seems a bit older.',
-                                                'Please upgrade boto >= 2.3.0.']))
-
-        # Inventory: Group by tag keys
-        if self.group_by_tag_keys:
-            for k, v in instance.tags.items():
-                if self.expand_csv_tags and v and ',' in v:
-                    values = map(lambda x: x.strip(), v.split(','))
-                else:
-                    values = [v]
-
-                for v in values:
-                    if v:
-                        key = self.to_safe("tag_" + k + "=" + v)
-                    else:
-                        key = self.to_safe("tag_" + k)
-                    self.push(self.inventory, key, hostname)
-                    if self.nested_groups:
-                        self.push_group(self.inventory, 'tags', self.to_safe("tag_" + k))
-                        if v:
-                            self.push_group(self.inventory, self.to_safe("tag_" + k), key)
-
-        # Inventory: Group by Route53 domain names if enabled
-        if self.route53_enabled and self.group_by_route53_names:
-            route53_names = self.get_instance_route53_names(instance)
-            for name in route53_names:
-                self.push(self.inventory, name, hostname)
-                if self.nested_groups:
-                    self.push_group(self.inventory, 'route53', name)
-
-        # Global Tag: instances without tags
-        if self.group_by_tag_none and len(instance.tags) == 0:
-            self.push(self.inventory, 'tag_none', hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'tags', 'tag_none')
-
-        # Global Tag: tag all EC2 instances
-        self.push(self.inventory, 'ec2', hostname)
-
-        self.inventory["_meta"]["hostvars"][hostname] = self.get_host_info_dict_from_instance(instance)
-        self.inventory["_meta"]["hostvars"][hostname]['ansible_ssh_host'] = dest
-
-
-    def add_rds_instance(self, instance, region):
-        ''' Adds an RDS instance to the inventory and index, as long as it is
-        addressable '''
-
-        # Only want available instances unless all_rds_instances is True
-        if not self.all_rds_instances and instance.status != 'available':
-            return
-
-        # Select the best destination address
-        dest = instance.endpoint[0]
-
-        if not dest:
-            # Skip instances we cannot address (e.g. private VPC subnet)
-            return
-
-        # Set the inventory name
-        hostname = None
-        if self.hostname_variable:
-            if self.hostname_variable.startswith('tag_'):
-                hostname = instance.tags.get(self.hostname_variable[4:], None)
-            else:
-                hostname = getattr(instance, self.hostname_variable)
-
-        # If we can't get a nice hostname, use the destination address
-        if not hostname:
-            hostname = dest
-
-        hostname = self.to_safe(hostname).lower()
-
-        # Add to index
-        self.index[hostname] = [region, instance.id]
-
-        # Inventory: Group by instance ID (always a group of 1)
-        if self.group_by_instance_id:
-            self.inventory[instance.id] = [hostname]
-            if self.nested_groups:
-                self.push_group(self.inventory, 'instances', instance.id)
-
-        # Inventory: Group by region
-        if self.group_by_region:
-            self.push(self.inventory, region, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'regions', region)
-
-        # Inventory: Group by availability zone
-        if self.group_by_availability_zone:
-            self.push(self.inventory, instance.availability_zone, hostname)
-            if self.nested_groups:
-                if self.group_by_region:
-                    self.push_group(self.inventory, region, instance.availability_zone)
-                self.push_group(self.inventory, 'zones', instance.availability_zone)
-
-        # Inventory: Group by instance type
-        if self.group_by_instance_type:
-            type_name = self.to_safe('type_' + instance.instance_class)
-            self.push(self.inventory, type_name, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'types', type_name)
-
-        # Inventory: Group by VPC
-        if self.group_by_vpc_id and instance.subnet_group and instance.subnet_group.vpc_id:
-            vpc_id_name = self.to_safe('vpc_id_' + instance.subnet_group.vpc_id)
-            self.push(self.inventory, vpc_id_name, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'vpcs', vpc_id_name)
-
-        # Inventory: Group by security group
-        if self.group_by_security_group:
-            try:
-                if instance.security_group:
-                    key = self.to_safe("security_group_" + instance.security_group.name)
-                    self.push(self.inventory, key, hostname)
-                    if self.nested_groups:
-                        self.push_group(self.inventory, 'security_groups', key)
-
-            except AttributeError:
-                self.fail_with_error('\n'.join(['Package boto seems a bit older.',
-                                                'Please upgrade boto >= 2.3.0.']))
-
-
-        # Inventory: Group by engine
-        if self.group_by_rds_engine:
-            self.push(self.inventory, self.to_safe("rds_" + instance.engine), hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'rds_engines', self.to_safe("rds_" + instance.engine))
-
-        # Inventory: Group by parameter group
-        if self.group_by_rds_parameter_group:
-            self.push(self.inventory, self.to_safe("rds_parameter_group_" + instance.parameter_group.name), hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'rds_parameter_groups', self.to_safe("rds_parameter_group_" + instance.parameter_group.name))
-
-        # Global Tag: all RDS instances
-        self.push(self.inventory, 'rds', hostname)
-
-        self.inventory["_meta"]["hostvars"][hostname] = self.get_host_info_dict_from_instance(instance)
-        self.inventory["_meta"]["hostvars"][hostname]['ansible_ssh_host'] = dest
-
-    def add_elasticache_cluster(self, cluster, region):
-        ''' Adds an ElastiCache cluster to the inventory and index, as long as
-        it's nodes are addressable '''
-
-        # Only want available clusters unless all_elasticache_clusters is True
-        if not self.all_elasticache_clusters and cluster['CacheClusterStatus'] != 'available':
-            return
-
-        # Select the best destination address
-        if 'ConfigurationEndpoint' in cluster and cluster['ConfigurationEndpoint']:
-            # Memcached cluster
-            dest = cluster['ConfigurationEndpoint']['Address']
-            is_redis = False
-        else:
-            # Redis sigle node cluster
-            # Because all Redis clusters are single nodes, we'll merge the
-            # info from the cluster with info about the node
-            dest = cluster['CacheNodes'][0]['Endpoint']['Address']
-            is_redis = True
-
-        if not dest:
-            # Skip clusters we cannot address (e.g. private VPC subnet)
-            return
-
-        # Add to index
-        self.index[dest] = [region, cluster['CacheClusterId']]
-
-        # Inventory: Group by instance ID (always a group of 1)
-        if self.group_by_instance_id:
-            self.inventory[cluster['CacheClusterId']] = [dest]
-            if self.nested_groups:
-                self.push_group(self.inventory, 'instances', cluster['CacheClusterId'])
-
-        # Inventory: Group by region
-        if self.group_by_region and not is_redis:
-            self.push(self.inventory, region, dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'regions', region)
-
-        # Inventory: Group by availability zone
-        if self.group_by_availability_zone and not is_redis:
-            self.push(self.inventory, cluster['PreferredAvailabilityZone'], dest)
-            if self.nested_groups:
-                if self.group_by_region:
-                    self.push_group(self.inventory, region, cluster['PreferredAvailabilityZone'])
-                self.push_group(self.inventory, 'zones', cluster['PreferredAvailabilityZone'])
-
-        # Inventory: Group by node type
-        if self.group_by_instance_type and not is_redis:
-            type_name = self.to_safe('type_' + cluster['CacheNodeType'])
-            self.push(self.inventory, type_name, dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'types', type_name)
-
-        # Inventory: Group by VPC (information not available in the current
-        # AWS API version for ElastiCache)
-
-        # Inventory: Group by security group
-        if self.group_by_security_group and not is_redis:
-
-            # Check for the existence of the 'SecurityGroups' key and also if
-            # this key has some value. When the cluster is not placed in a SG
-            # the query can return None here and cause an error.
-            if 'SecurityGroups' in cluster and cluster['SecurityGroups'] is not None:
-                for security_group in cluster['SecurityGroups']:
-                    key = self.to_safe("security_group_" + security_group['SecurityGroupId'])
-                    self.push(self.inventory, key, dest)
-                    if self.nested_groups:
-                        self.push_group(self.inventory, 'security_groups', key)
-
-        # Inventory: Group by engine
-        if self.group_by_elasticache_engine and not is_redis:
-            self.push(self.inventory, self.to_safe("elasticache_" + cluster['Engine']), dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'elasticache_engines', self.to_safe(cluster['Engine']))
-
-        # Inventory: Group by parameter group
-        if self.group_by_elasticache_parameter_group:
-            self.push(self.inventory, self.to_safe("elasticache_parameter_group_" + cluster['CacheParameterGroup']['CacheParameterGroupName']), dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'elasticache_parameter_groups', self.to_safe(cluster['CacheParameterGroup']['CacheParameterGroupName']))
-
-        # Inventory: Group by replication group
-        if self.group_by_elasticache_replication_group and 'ReplicationGroupId' in cluster and cluster['ReplicationGroupId']:
-            self.push(self.inventory, self.to_safe("elasticache_replication_group_" + cluster['ReplicationGroupId']), dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'elasticache_replication_groups', self.to_safe(cluster['ReplicationGroupId']))
-
-        # Global Tag: all ElastiCache clusters
-        self.push(self.inventory, 'elasticache_clusters', cluster['CacheClusterId'])
-
-        host_info = self.get_host_info_dict_from_describe_dict(cluster)
-
-        self.inventory["_meta"]["hostvars"][dest] = host_info
-
-        # Add the nodes
-        for node in cluster['CacheNodes']:
-            self.add_elasticache_node(node, cluster, region)
-
-    def add_elasticache_node(self, node, cluster, region):
-        ''' Adds an ElastiCache node to the inventory and index, as long as
-        it is addressable '''
-
-        # Only want available nodes unless all_elasticache_nodes is True
-        if not self.all_elasticache_nodes and node['CacheNodeStatus'] != 'available':
-            return
-
-        # Select the best destination address
-        dest = node['Endpoint']['Address']
-
-        if not dest:
-            # Skip nodes we cannot address (e.g. private VPC subnet)
-            return
-
-        node_id = self.to_safe(cluster['CacheClusterId'] + '_' + node['CacheNodeId'])
-
-        # Add to index
-        self.index[dest] = [region, node_id]
-
-        # Inventory: Group by node ID (always a group of 1)
-        if self.group_by_instance_id:
-            self.inventory[node_id] = [dest]
-            if self.nested_groups:
-                self.push_group(self.inventory, 'instances', node_id)
-
-        # Inventory: Group by region
-        if self.group_by_region:
-            self.push(self.inventory, region, dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'regions', region)
-
-        # Inventory: Group by availability zone
-        if self.group_by_availability_zone:
-            self.push(self.inventory, cluster['PreferredAvailabilityZone'], dest)
-            if self.nested_groups:
-                if self.group_by_region:
-                    self.push_group(self.inventory, region, cluster['PreferredAvailabilityZone'])
-                self.push_group(self.inventory, 'zones', cluster['PreferredAvailabilityZone'])
-
-        # Inventory: Group by node type
-        if self.group_by_instance_type:
-            type_name = self.to_safe('type_' + cluster['CacheNodeType'])
-            self.push(self.inventory, type_name, dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'types', type_name)
-
-        # Inventory: Group by VPC (information not available in the current
-        # AWS API version for ElastiCache)
-
-        # Inventory: Group by security group
-        if self.group_by_security_group:
-
-            # Check for the existence of the 'SecurityGroups' key and also if
-            # this key has some value. When the cluster is not placed in a SG
-            # the query can return None here and cause an error.
-            if 'SecurityGroups' in cluster and cluster['SecurityGroups'] is not None:
-                for security_group in cluster['SecurityGroups']:
-                    key = self.to_safe("security_group_" + security_group['SecurityGroupId'])
-                    self.push(self.inventory, key, dest)
-                    if self.nested_groups:
-                        self.push_group(self.inventory, 'security_groups', key)
-
-        # Inventory: Group by engine
-        if self.group_by_elasticache_engine:
-            self.push(self.inventory, self.to_safe("elasticache_" + cluster['Engine']), dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'elasticache_engines', self.to_safe("elasticache_" + cluster['Engine']))
-
-        # Inventory: Group by parameter group (done at cluster level)
-
-        # Inventory: Group by replication group (done at cluster level)
-
-        # Inventory: Group by ElastiCache Cluster
-        if self.group_by_elasticache_cluster:
-            self.push(self.inventory, self.to_safe("elasticache_cluster_" + cluster['CacheClusterId']), dest)
-
-        # Global Tag: all ElastiCache nodes
-        self.push(self.inventory, 'elasticache_nodes', dest)
-
-        host_info = self.get_host_info_dict_from_describe_dict(node)
-
-        if dest in self.inventory["_meta"]["hostvars"]:
-            self.inventory["_meta"]["hostvars"][dest].update(host_info)
-        else:
-            self.inventory["_meta"]["hostvars"][dest] = host_info
-
-    def add_elasticache_replication_group(self, replication_group, region):
-        ''' Adds an ElastiCache replication group to the inventory and index '''
-
-        # Only want available clusters unless all_elasticache_replication_groups is True
-        if not self.all_elasticache_replication_groups and replication_group['Status'] != 'available':
-            return
-
-        # Select the best destination address (PrimaryEndpoint)
-        dest = replication_group['NodeGroups'][0]['PrimaryEndpoint']['Address']
-
-        if not dest:
-            # Skip clusters we cannot address (e.g. private VPC subnet)
-            return
-
-        # Add to index
-        self.index[dest] = [region, replication_group['ReplicationGroupId']]
-
-        # Inventory: Group by ID (always a group of 1)
-        if self.group_by_instance_id:
-            self.inventory[replication_group['ReplicationGroupId']] = [dest]
-            if self.nested_groups:
-                self.push_group(self.inventory, 'instances', replication_group['ReplicationGroupId'])
-
-        # Inventory: Group by region
-        if self.group_by_region:
-            self.push(self.inventory, region, dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'regions', region)
-
-        # Inventory: Group by availability zone (doesn't apply to replication groups)
-
-        # Inventory: Group by node type (doesn't apply to replication groups)
-
-        # Inventory: Group by VPC (information not available in the current
-        # AWS API version for replication groups
-
-        # Inventory: Group by security group (doesn't apply to replication groups)
-        # Check this value in cluster level
-
-        # Inventory: Group by engine (replication groups are always Redis)
-        if self.group_by_elasticache_engine:
-            self.push(self.inventory, 'elasticache_redis', dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'elasticache_engines', 'redis')
-
-        # Global Tag: all ElastiCache clusters
-        self.push(self.inventory, 'elasticache_replication_groups', replication_group['ReplicationGroupId'])
-
-        host_info = self.get_host_info_dict_from_describe_dict(replication_group)
-
-        self.inventory["_meta"]["hostvars"][dest] = host_info
-
-    def get_route53_records(self):
-        ''' Get and store the map of resource records to domain names that
-        point to them. '''
-
-        r53_conn = route53.Route53Connection()
-        all_zones = r53_conn.get_zones()
-
-        route53_zones = [ zone for zone in all_zones if zone.name[:-1]
-                          not in self.route53_excluded_zones ]
-
-        self.route53_records = {}
-
-        for zone in route53_zones:
-            rrsets = r53_conn.get_all_rrsets(zone.id)
-
-            for record_set in rrsets:
-                record_name = record_set.name
-
-                if record_name.endswith('.'):
-                    record_name = record_name[:-1]
-
-                for resource in record_set.resource_records:
-                    self.route53_records.setdefault(resource, set())
-                    self.route53_records[resource].add(record_name)
-
-
-    def get_instance_route53_names(self, instance):
-        ''' Check if an instance is referenced in the records we have from
-        Route53. If it is, return the list of domain names pointing to said
-        instance. If nothing points to it, return an empty list. '''
-
-        instance_attributes = [ 'public_dns_name', 'private_dns_name',
-                                'ip_address', 'private_ip_address' ]
-
-        name_list = set()
-
-        for attrib in instance_attributes:
-            try:
-                value = getattr(instance, attrib)
-            except AttributeError:
-                continue
-
-            if value in self.route53_records:
-                name_list.update(self.route53_records[value])
-
-        return list(name_list)
-
-    def get_host_info_dict_from_instance(self, instance):
-        instance_vars = {}
-        for key in vars(instance):
-            value = getattr(instance, key)
-            key = self.to_safe('ec2_' + key)
-
-            # Handle complex types
-            # state/previous_state changed to properties in boto in https://github.com/boto/boto/commit/a23c379837f698212252720d2af8dec0325c9518
-            if key == 'ec2__state':
-                instance_vars['ec2_state'] = instance.state or ''
-                instance_vars['ec2_state_code'] = instance.state_code
-            elif key == 'ec2__previous_state':
-                instance_vars['ec2_previous_state'] = instance.previous_state or ''
-                instance_vars['ec2_previous_state_code'] = instance.previous_state_code
-            elif type(value) in [int, bool]:
-                instance_vars[key] = value
-            elif isinstance(value, six.string_types):
-                instance_vars[key] = value.strip()
-            elif type(value) == type(None):
-                instance_vars[key] = ''
-            elif key == 'ec2_region':
-                instance_vars[key] = value.name
-            elif key == 'ec2__placement':
-                instance_vars['ec2_placement'] = value.zone
-            elif key == 'ec2_tags':
-                for k, v in value.items():
-                    if self.expand_csv_tags and ',' in v:
-                        v = map(lambda x: x.strip(), v.split(','))
-                    key = self.to_safe('ec2_tag_' + k)
-                    instance_vars[key] = v
-            elif key == 'ec2_groups':
-                group_ids = []
-                group_names = []
-                for group in value:
-                    group_ids.append(group.id)
-                    group_names.append(group.name)
-                instance_vars["ec2_security_group_ids"] = ','.join([str(i) for i in group_ids])
-                instance_vars["ec2_security_group_names"] = ','.join([str(i) for i in group_names])
-            else:
-                pass
-                # TODO Product codes if someone finds them useful
-                #print key
-                #print type(value)
-                #print value
-
-        return instance_vars
-
-    def get_host_info_dict_from_describe_dict(self, describe_dict):
-        ''' Parses the dictionary returned by the API call into a flat list
-            of parameters. This method should be used only when 'describe' is
-            used directly because Boto doesn't provide specific classes. '''
-
-        # I really don't agree with prefixing everything with 'ec2'
-        # because EC2, RDS and ElastiCache are different services.
-        # I'm just following the pattern used until now to not break any
-        # compatibility.
-
-        host_info = {}
-        for key in describe_dict:
-            value = describe_dict[key]
-            key = self.to_safe('ec2_' + self.uncammelize(key))
-
-            # Handle complex types
-
-            # Target: Memcached Cache Clusters
-            if key == 'ec2_configuration_endpoint' and value:
-                host_info['ec2_configuration_endpoint_address'] = value['Address']
-                host_info['ec2_configuration_endpoint_port'] = value['Port']
-
-            # Target: Cache Nodes and Redis Cache Clusters (single node)
-            if key == 'ec2_endpoint' and value:
-                host_info['ec2_endpoint_address'] = value['Address']
-                host_info['ec2_endpoint_port'] = value['Port']
-
-            # Target: Redis Replication Groups
-            if key == 'ec2_node_groups' and value:
-                host_info['ec2_endpoint_address'] = value[0]['PrimaryEndpoint']['Address']
-                host_info['ec2_endpoint_port'] = value[0]['PrimaryEndpoint']['Port']
-                replica_count = 0
-                for node in value[0]['NodeGroupMembers']:
-                    if node['CurrentRole'] == 'primary':
-                        host_info['ec2_primary_cluster_address'] = node['ReadEndpoint']['Address']
-                        host_info['ec2_primary_cluster_port'] = node['ReadEndpoint']['Port']
-                        host_info['ec2_primary_cluster_id'] = node['CacheClusterId']
-                    elif node['CurrentRole'] == 'replica':
-                        host_info['ec2_replica_cluster_address_'+ str(replica_count)] = node['ReadEndpoint']['Address']
-                        host_info['ec2_replica_cluster_port_'+ str(replica_count)] = node['ReadEndpoint']['Port']
-                        host_info['ec2_replica_cluster_id_'+ str(replica_count)] = node['CacheClusterId']
-                        replica_count += 1
-
-            # Target: Redis Replication Groups
-            if key == 'ec2_member_clusters' and value:
-                host_info['ec2_member_clusters'] = ','.join([str(i) for i in value])
-
-            # Target: All Cache Clusters
-            elif key == 'ec2_cache_parameter_group':
-                host_info["ec2_cache_node_ids_to_reboot"] = ','.join([str(i) for i in value['CacheNodeIdsToReboot']])
-                host_info['ec2_cache_parameter_group_name'] = value['CacheParameterGroupName']
-                host_info['ec2_cache_parameter_apply_status'] = value['ParameterApplyStatus']
-
-            # Target: Almost everything
-            elif key == 'ec2_security_groups':
-
-                # Skip if SecurityGroups is None
-                # (it is possible to have the key defined but no value in it).
-                if value is not None:
-                    sg_ids = []
-                    for sg in value:
-                        sg_ids.append(sg['SecurityGroupId'])
-                    host_info["ec2_security_group_ids"] = ','.join([str(i) for i in sg_ids])
-
-            # Target: Everything
-            # Preserve booleans and integers
-            elif type(value) in [int, bool]:
-                host_info[key] = value
-
-            # Target: Everything
-            # Sanitize string values
-            elif isinstance(value, six.string_types):
-                host_info[key] = value.strip()
-
-            # Target: Everything
-            # Replace None by an empty string
-            elif type(value) == type(None):
-                host_info[key] = ''
-
-            else:
-                # Remove non-processed complex types
-                pass
-
-        return host_info
-
-    def get_host_info(self):
-        ''' Get variables about a specific host '''
-
-        if len(self.index) == 0:
-            # Need to load index from cache
-            self.load_index_from_cache()
-
-        if not self.args.host in self.index:
-            # try updating the cache
-            self.do_api_calls_update_cache()
-            if not self.args.host in self.index:
-                # host might not exist anymore
-                return self.json_format_dict({}, True)
-
-        (region, instance_id) = self.index[self.args.host]
-
-        instance = self.get_instance(region, instance_id)
-        return self.json_format_dict(self.get_host_info_dict_from_instance(instance), True)
-
-    def push(self, my_dict, key, element):
-        ''' Push an element onto an array that may not have been defined in
-        the dict '''
-        group_info = my_dict.setdefault(key, [])
-        if isinstance(group_info, dict):
-            host_list = group_info.setdefault('hosts', [])
-            host_list.append(element)
-        else:
-            group_info.append(element)
-
-    def push_group(self, my_dict, key, element):
-        ''' Push a group as a child of another group. '''
-        parent_group = my_dict.setdefault(key, {})
-        if not isinstance(parent_group, dict):
-            parent_group = my_dict[key] = {'hosts': parent_group}
-        child_groups = parent_group.setdefault('children', [])
-        if element not in child_groups:
-            child_groups.append(element)
-
-    def get_inventory_from_cache(self):
-        ''' Reads the inventory from the cache file and returns it as a JSON
-        object '''
-
-        cache = open(self.cache_path_cache, 'r')
-        json_inventory = cache.read()
-        return json_inventory
-
-
-    def load_index_from_cache(self):
-        ''' Reads the index from the cache file sets self.index '''
-
-        cache = open(self.cache_path_index, 'r')
-        json_index = cache.read()
-        self.index = json.loads(json_index)
-
-
-    def write_to_cache(self, data, filename):
-        ''' Writes data in JSON format to a file '''
-
-        json_data = self.json_format_dict(data, True)
-        cache = open(filename, 'w')
-        cache.write(json_data)
-        cache.close()
-
-    def uncammelize(self, key):
-        temp = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', key)
-        return re.sub('([a-z0-9])([A-Z])', r'\1_\2', temp).lower()
-
-    def to_safe(self, word):
-        ''' Converts 'bad' characters in a string to underscores so they can be used as Ansible groups '''
-        regex = "[^A-Za-z0-9\_"
-        if not self.replace_dash_in_groups:
-            regex += "\-"
-        return re.sub(regex + "]", "_", word)
-
-    def json_format_dict(self, data, pretty=False):
-        ''' Converts a dict to a JSON object and dumps it as a formatted
-        string '''
-
-        if pretty:
-            return json.dumps(data, sort_keys=True, indent=2)
-        else:
-            return json.dumps(data)
-
-
-# Run the script
-Ec2Inventory()
diff --git a/baas-1701-dc6/inventory b/baas-1701-dc6/inventory
deleted file mode 100644
index 454f2d4..0000000
--- a/baas-1701-dc6/inventory
+++ /dev/null
@@ -1,67 +0,0 @@
-[tag_Name_dc6_n1]
-[tag_Name_dc6_n2]
-[tag_Name_dc6_n3]
-[tag_Name_dc6_n4]
-[tag_Name_dc6_n5]
-[tag_Name_dc6_n6]
-[tag_Name_dc6_n7]
-[tag_Name_dc6_n8]
-[tag_Name_dc6_n9]
-[tag_Name_dc6_n10]
-
-[planet:children]
-dc-1
-
-[dc-1:children]
-tag_Name_dc6_n1
-tag_Name_dc6_n2
-tag_Name_dc6_n3
-tag_Name_dc6_n4
-tag_Name_dc6_n5
-tag_Name_dc6_n6
-tag_Name_dc6_n7
-tag_Name_dc6_n8
-tag_Name_dc6_n9
-tag_Name_dc6_n10
-
-[elastic:children]
-dc-1-elastic
-
-[dc-1-elastic:children]
-tag_Name_dc6_n1
-tag_Name_dc6_n2
-tag_Name_dc6_n3
-
-[baas:children]
-dc-1-baas
-
-[dc-1-baas:children]
-tag_Name_dc6_n4
-tag_Name_dc6_n5
-tag_Name_dc6_n6
-
-[portal:children]
-dc-1-portal
-
-[dc-1-portal:children]
-tag_Name_dc6_n7
-
-[ds:children]
-dc-1-ds
-
-[dc-1-ds:children]
-dc-1-cassandra
-
-[cassandra:children]
-dc-1-cassandra
-
-[dc-1-cassandra:children]
-tag_Name_dc6_n8
-tag_Name_dc6_n9
-tag_Name_dc6_n10
-
-[ms:children]
-dc-1-ms
-
-[dc-1-ms:children]
-tag_Name_dc6_n7
diff --git a/baas-1701-dc7/ec2.ini b/baas-1701-dc7/ec2.ini
deleted file mode 100644
index 36b3921..0000000
--- a/baas-1701-dc7/ec2.ini
+++ /dev/null
@@ -1,200 +0,0 @@
-# Ansible EC2 external inventory script settings
-#
-
-[ec2]
-
-# to talk to a private eucalyptus instance uncomment these lines
-# and edit edit eucalyptus_host to be the host name of your cloud controller
-#eucalyptus = True
-#eucalyptus_host = clc.cloud.domain.org
-
-# AWS regions to make calls to. Set this to 'all' to make request to all regions
-# in AWS and merge the results together. Alternatively, set this to a comma
-# separated list of regions. E.g. 'us-east-1,us-west-1,us-west-2'
-regions = all
-regions_exclude = us-gov-west-1,cn-north-1
-
-# When generating inventory, Ansible needs to know how to address a server.
-# Each EC2 instance has a lot of variables associated with it. Here is the list:
-#   http://docs.pythonboto.org/en/latest/ref/ec2.html#module-boto.ec2.instance
-# Below are 2 variables that are used as the address of a server:
-#   - destination_variable
-#   - vpc_destination_variable
-
-# This is the normal destination variable to use. If you are running Ansible
-# from outside EC2, then 'public_dns_name' makes the most sense. If you are
-# running Ansible from within EC2, then perhaps you want to use the internal
-# address, and should set this to 'private_dns_name'. The key of an EC2 tag
-# may optionally be used; however the boto instance variables hold precedence
-# in the event of a collision.
-destination_variable = public_dns_name
-
-# This allows you to override the inventory_name with an ec2 variable, instead
-# of using the destination_variable above. Addressing (aka ansible_ssh_host)
-# will still use destination_variable. Tags should be written as 'tag_TAGNAME'.
-#hostname_variable = tag_Name
-
-# For server inside a VPC, using DNS names may not make sense. When an instance
-# has 'subnet_id' set, this variable is used. If the subnet is public, setting
-# this to 'ip_address' will return the public IP address. For instances in a
-# private subnet, this should be set to 'private_ip_address', and Ansible must
-# be run from within EC2. The key of an EC2 tag may optionally be used; however
-# the boto instance variables hold precedence in the event of a collision.
-# WARNING: - instances that are in the private vpc, _without_ public ip address
-# will not be listed in the inventory until You set:
-# vpc_destination_variable = private_ip_address
-vpc_destination_variable = ip_address
-
-# The following two settings allow flexible ansible host naming based on a
-# python format string and a comma-separated list of ec2 tags.  Note that:
-#
-# 1) If the tags referenced are not present for some instances, empty strings
-#    will be substituted in the format string.
-# 2) This overrides both destination_variable and vpc_destination_variable.
-#
-#destination_format = {0}.{1}.example.com
-#destination_format_tags = Name,environment
-
-# To tag instances on EC2 with the resource records that point to them from
-# Route53, uncomment and set 'route53' to True.
-route53 = False
-
-# To exclude RDS instances from the inventory, uncomment and set to False.
-rds = False
-
-# To exclude ElastiCache instances from the inventory, uncomment and set to False.
-elasticache = False
-
-# Additionally, you can specify the list of zones to exclude looking up in
-# 'route53_excluded_zones' as a comma-separated list.
-# route53_excluded_zones = samplezone1.com, samplezone2.com
-
-# By default, only EC2 instances in the 'running' state are returned. Set
-# 'all_instances' to True to return all instances regardless of state.
-all_instances = True
-
-# By default, only EC2 instances in the 'running' state are returned. Specify
-# EC2 instance states to return as a comma-separated list. This
-# option is overriden when 'all_instances' is True.
-# instance_states = pending, running, shutting-down, terminated, stopping, stopped
-
-# By default, only RDS instances in the 'available' state are returned.  Set
-# 'all_rds_instances' to True return all RDS instances regardless of state.
-all_rds_instances = False
-
-# By default, only ElastiCache clusters and nodes in the 'available' state
-# are returned. Set 'all_elasticache_clusters' and/or 'all_elastic_nodes'
-# to True return all ElastiCache clusters and nodes, regardless of state.
-#
-# Note that all_elasticache_nodes only applies to listed clusters. That means
-# if you set all_elastic_clusters to false, no node will be return from
-# unavailable clusters, regardless of the state and to what you set for
-# all_elasticache_nodes.
-all_elasticache_replication_groups = False
-all_elasticache_clusters = False
-all_elasticache_nodes = False
-
-# API calls to EC2 are slow. For this reason, we cache the results of an API
-# call. Set this to the path you want cache files to be written to. Two files
-# will be written to this directory:
-#   - ansible-ec2.cache
-#   - ansible-ec2.index
-cache_path = ~/.ansible/tmp
-
-# The number of seconds a cache file is considered valid. After this many
-# seconds, a new API call will be made, and the cache file will be updated.
-# To disable the cache, set this value to 0
-cache_max_age = 300
-
-# Organize groups into a nested/hierarchy instead of a flat namespace.
-nested_groups = False
-
-# Replace - tags when creating groups to avoid issues with ansible
-replace_dash_in_groups = True
-
-# If set to true, any tag of the form "a,b,c" is expanded into a list
-# and the results are used to create additional tag_* inventory groups.
-expand_csv_tags = False
-
-# The EC2 inventory output can become very large. To manage its size,
-# configure which groups should be created.
-group_by_instance_id = True
-group_by_region = True
-group_by_availability_zone = True
-group_by_ami_id = True
-group_by_instance_type = True
-group_by_key_pair = True
-group_by_vpc_id = True
-group_by_security_group = True
-group_by_tag_keys = True
-group_by_tag_none = True
-group_by_route53_names = True
-group_by_rds_engine = False
-group_by_rds_parameter_group = False
-group_by_elasticache_engine = True
-group_by_elasticache_cluster = True
-group_by_elasticache_parameter_group = True
-group_by_elasticache_replication_group = True
-
-# If you only want to include hosts that match a certain regular expression
-# pattern_include = staging-*
-
-# If you want to exclude any hosts that match a certain regular expression
-# pattern_exclude = staging-*
-# Ansible EC2 external inventory script settings
-#
-
-##[ec2]
-##
-### to talk to a private eucalyptus instance uncomment these lines
-### and edit edit eucalyptus_host to be the host name of your cloud controller
-###eucalyptus = True
-###eucalyptus_host = clc.cloud.domain.org
-##
-### AWS regions to make calls to. Set this to 'all' to make request to all regions
-##
-### in AWS and merge the results together. Alternatively, set this to a comma
-### separated list of regions. E.g. 'us-east-1,us-west-1,us-west-2'
-##regions = all
-##regions_exclude = us-gov-west-1,cn-north-1
-##
-### When generating inventory, Ansible needs to know how to address a server.
-### Each EC2 instance has a lot of variables associated with it. Here is the list:
-###   http://docs.pythonboto.org/en/latest/ref/ec2.html#module-boto.ec2.instance
-### Below are 2 variables that are used as the address of a server:
-###   - destination_variable
-###   - vpc_destination_variable
-##
-### This is the normal destination variable to use. If you are running Ansible
-### from outside EC2, then 'public_dns_name' makes the most sense. If you are
-### running Ansible from within EC2, then perhaps you want to use the internal
-### address, and should set this to 'private_dns_name'. The key of an EC2 tag
-##...skipping...
-### pattern_include = staging-*
-##
-### If you want to exclude any hosts that match a certain regular expression
-### pattern_exclude = staging-*
-
-# Instance filters can be used to control which instances are retrieved for
-# inventory. For the full list of possible filters, please read the EC2 API
-# docs: http://docs.aws.amazon.com/AWSEC2/latest/APIReference/ApiReference-query-DescribeInstances.html#query-DescribeInstances-filters
-# Filters are key/value pairs separated by '=', to list multiple filters use
-# a list separated by commas. See examples below.
-
-# Retrieve only instances with (key=value) env=staging tag
-# instance_filters = tag:env=staging
-
-# Retrieve only instances with role=webservers OR role=dbservers tag
-# instance_filters = tag:role=webservers,tag:role=dbservers
-
-# Retrieve only t1.micro instances OR instances with tag env=staging
-# instance_filters = instance-type=t1.micro,tag:env=staging
-
-# You can use wildcards in filter values also. Below will list instances which
-# tag Name value matches webservers1*
-# (ex. webservers15, webservers1a, webservers123 etc)
-# instance_filters = tag:Name=webservers1*
-
-# A boto configuration profile may be used to separate out credentials
-# see http://boto.readthedocs.org/en/latest/boto_config_tut.html
-# boto_profile = some-boto-profile-name
diff --git a/baas-1701-dc7/ec2.py b/baas-1701-dc7/ec2.py
deleted file mode 100755
index f30958a..0000000
--- a/baas-1701-dc7/ec2.py
+++ /dev/null
@@ -1,1385 +0,0 @@
-#!/usr/bin/env python
-
-'''
-EC2 external inventory script
-=================================
-
-Generates inventory that Ansible can understand by making API request to
-AWS EC2 using the Boto library.
-
-NOTE: This script assumes Ansible is being executed where the environment
-variables needed for Boto have already been set:
-    export AWS_ACCESS_KEY_ID='AK123'
-    export AWS_SECRET_ACCESS_KEY='abc123'
-
-This script also assumes there is an ec2.ini file alongside it.  To specify a
-different path to ec2.ini, define the EC2_INI_PATH environment variable:
-
-    export EC2_INI_PATH=/path/to/my_ec2.ini
-
-If you're using eucalyptus you need to set the above variables and
-you need to define:
-
-    export EC2_URL=http://hostname_of_your_cc:port/services/Eucalyptus
-
-If you're using boto profiles (requires boto>=2.24.0) you can choose a profile
-using the --boto-profile command line argument (e.g. ec2.py --boto-profile prod) or using
-the AWS_PROFILE variable:
-
-    AWS_PROFILE=prod ansible-playbook -i ec2.py myplaybook.yml
-
-For more details, see: http://docs.pythonboto.org/en/latest/boto_config_tut.html
-
-When run against a specific host, this script returns the following variables:
- - ec2_ami_launch_index
- - ec2_architecture
- - ec2_association
- - ec2_attachTime
- - ec2_attachment
- - ec2_attachmentId
- - ec2_client_token
- - ec2_deleteOnTermination
- - ec2_description
- - ec2_deviceIndex
- - ec2_dns_name
- - ec2_eventsSet
- - ec2_group_name
- - ec2_hypervisor
- - ec2_id
- - ec2_image_id
- - ec2_instanceState
- - ec2_instance_type
- - ec2_ipOwnerId
- - ec2_ip_address
- - ec2_item
- - ec2_kernel
- - ec2_key_name
- - ec2_launch_time
- - ec2_monitored
- - ec2_monitoring
- - ec2_networkInterfaceId
- - ec2_ownerId
- - ec2_persistent
- - ec2_placement
- - ec2_platform
- - ec2_previous_state
- - ec2_private_dns_name
- - ec2_private_ip_address
- - ec2_publicIp
- - ec2_public_dns_name
- - ec2_ramdisk
- - ec2_reason
- - ec2_region
- - ec2_requester_id
- - ec2_root_device_name
- - ec2_root_device_type
- - ec2_security_group_ids
- - ec2_security_group_names
- - ec2_shutdown_state
- - ec2_sourceDestCheck
- - ec2_spot_instance_request_id
- - ec2_state
- - ec2_state_code
- - ec2_state_reason
- - ec2_status
- - ec2_subnet_id
- - ec2_tenancy
- - ec2_virtualization_type
- - ec2_vpc_id
-
-These variables are pulled out of a boto.ec2.instance object. There is a lack of
-consistency with variable spellings (camelCase and underscores) since this
-just loops through all variables the object exposes. It is preferred to use the
-ones with underscores when multiple exist.
-
-In addition, if an instance has AWS Tags associated with it, each tag is a new
-variable named:
- - ec2_tag_[Key] = [Value]
-
-Security groups are comma-separated in 'ec2_security_group_ids' and
-'ec2_security_group_names'.
-'''
-
-# (c) 2012, Peter Sankauskas
-#
-# This file is part of Ansible,
-#
-# Ansible is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# Ansible is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with Ansible.  If not, see <http://www.gnu.org/licenses/>.
-
-######################################################################
-
-import sys
-import os
-import argparse
-import re
-from time import time
-import boto
-from boto import ec2
-from boto import rds
-from boto import elasticache
-from boto import route53
-import six
-
-from six.moves import configparser
-from collections import defaultdict
-
-try:
-    import json
-except ImportError:
-    import simplejson as json
-
-
-class Ec2Inventory(object):
-
-    def _empty_inventory(self):
-        return {"_meta" : {"hostvars" : {}}}
-
-    def __init__(self):
-        ''' Main execution path '''
-
-        # Inventory grouped by instance IDs, tags, security groups, regions,
-        # and availability zones
-        self.inventory = self._empty_inventory()
-
-        # Index of hostname (address) to instance ID
-        self.index = {}
-
-        # Boto profile to use (if any)
-        self.boto_profile = None
-
-        # Read settings and parse CLI arguments
-        self.parse_cli_args()
-        self.read_settings()
-
-        # Make sure that profile_name is not passed at all if not set
-        # as pre 2.24 boto will fall over otherwise
-        if self.boto_profile:
-            if not hasattr(boto.ec2.EC2Connection, 'profile_name'):
-                self.fail_with_error("boto version must be >= 2.24 to use profile")
-
-        # Cache
-        if self.args.refresh_cache:
-            self.do_api_calls_update_cache()
-        elif not self.is_cache_valid():
-            self.do_api_calls_update_cache()
-
-        # Data to print
-        if self.args.host:
-            data_to_print = self.get_host_info()
-
-        elif self.args.list:
-            # Display list of instances for inventory
-            if self.inventory == self._empty_inventory():
-                data_to_print = self.get_inventory_from_cache()
-            else:
-                data_to_print = self.json_format_dict(self.inventory, True)
-
-        print(data_to_print)
-
-
-    def is_cache_valid(self):
-        ''' Determines if the cache files have expired, or if it is still valid '''
-
-        if os.path.isfile(self.cache_path_cache):
-            mod_time = os.path.getmtime(self.cache_path_cache)
-            current_time = time()
-            if (mod_time + self.cache_max_age) > current_time:
-                if os.path.isfile(self.cache_path_index):
-                    return True
-
-        return False
-
-
-    def read_settings(self):
-        ''' Reads the settings from the ec2.ini file '''
-        if six.PY3:
-            config = configparser.ConfigParser()
-        else:
-            config = configparser.SafeConfigParser()
-        ec2_default_ini_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'ec2.ini')
-        ec2_ini_path = os.path.expanduser(os.path.expandvars(os.environ.get('EC2_INI_PATH', ec2_default_ini_path)))
-        config.read(ec2_ini_path)
-
-        # is eucalyptus?
-        self.eucalyptus_host = None
-        self.eucalyptus = False
-        if config.has_option('ec2', 'eucalyptus'):
-            self.eucalyptus = config.getboolean('ec2', 'eucalyptus')
-        if self.eucalyptus and config.has_option('ec2', 'eucalyptus_host'):
-            self.eucalyptus_host = config.get('ec2', 'eucalyptus_host')
-
-        # Regions
-        self.regions = []
-        configRegions = config.get('ec2', 'regions')
-        configRegions_exclude = config.get('ec2', 'regions_exclude')
-        if (configRegions == 'all'):
-            if self.eucalyptus_host:
-                self.regions.append(boto.connect_euca(host=self.eucalyptus_host).region.name)
-            else:
-                for regionInfo in ec2.regions():
-                    if regionInfo.name not in configRegions_exclude:
-                        self.regions.append(regionInfo.name)
-        else:
-            self.regions = configRegions.split(",")
-
-        # Destination addresses
-        self.destination_variable = config.get('ec2', 'destination_variable')
-        self.vpc_destination_variable = config.get('ec2', 'vpc_destination_variable')
-
-        if config.has_option('ec2', 'hostname_variable'):
-            self.hostname_variable = config.get('ec2', 'hostname_variable')
-        else:
-            self.hostname_variable = None
-
-        if config.has_option('ec2', 'destination_format') and \
-                config.has_option('ec2', 'destination_format_tags'):
-            self.destination_format = config.get('ec2', 'destination_format')
-            self.destination_format_tags = config.get('ec2', 'destination_format_tags').split(',')
-        else:
-            self.destination_format = None
-            self.destination_format_tags = None
-
-        # Route53
-        self.route53_enabled = config.getboolean('ec2', 'route53')
-        self.route53_excluded_zones = []
-        if config.has_option('ec2', 'route53_excluded_zones'):
-            self.route53_excluded_zones.extend(
-                    config.get('ec2', 'route53_excluded_zones', '').split(','))
-
-        # Include RDS instances?
-        self.rds_enabled = True
-        if config.has_option('ec2', 'rds'):
-            self.rds_enabled = config.getboolean('ec2', 'rds')
-
-        # Include ElastiCache instances?
-        self.elasticache_enabled = True
-        if config.has_option('ec2', 'elasticache'):
-            self.elasticache_enabled = config.getboolean('ec2', 'elasticache')
-
-        # Return all EC2 instances?
-        if config.has_option('ec2', 'all_instances'):
-            self.all_instances = config.getboolean('ec2', 'all_instances')
-        else:
-            self.all_instances = False
-
-        # Instance states to be gathered in inventory. Default is 'running'.
-        # Setting 'all_instances' to 'yes' overrides this option.
-        ec2_valid_instance_states = [
-            'pending',
-            'running',
-            'shutting-down',
-            'terminated',
-            'stopping',
-            'stopped'
-        ]
-        self.ec2_instance_states = []
-        if self.all_instances:
-            self.ec2_instance_states = ec2_valid_instance_states
-        elif config.has_option('ec2', 'instance_states'):
-            for instance_state in config.get('ec2', 'instance_states').split(','):
-                instance_state = instance_state.strip()
-                if instance_state not in ec2_valid_instance_states:
-                    continue
-                self.ec2_instance_states.append(instance_state)
-        else:
-            self.ec2_instance_states = ['running']
-
-        # Return all RDS instances? (if RDS is enabled)
-        if config.has_option('ec2', 'all_rds_instances') and self.rds_enabled:
-            self.all_rds_instances = config.getboolean('ec2', 'all_rds_instances')
-        else:
-            self.all_rds_instances = False
-
-        # Return all ElastiCache replication groups? (if ElastiCache is enabled)
-        if config.has_option('ec2', 'all_elasticache_replication_groups') and self.elasticache_enabled:
-            self.all_elasticache_replication_groups = config.getboolean('ec2', 'all_elasticache_replication_groups')
-        else:
-            self.all_elasticache_replication_groups = False
-
-        # Return all ElastiCache clusters? (if ElastiCache is enabled)
-        if config.has_option('ec2', 'all_elasticache_clusters') and self.elasticache_enabled:
-            self.all_elasticache_clusters = config.getboolean('ec2', 'all_elasticache_clusters')
-        else:
-            self.all_elasticache_clusters = False
-
-        # Return all ElastiCache nodes? (if ElastiCache is enabled)
-        if config.has_option('ec2', 'all_elasticache_nodes') and self.elasticache_enabled:
-            self.all_elasticache_nodes = config.getboolean('ec2', 'all_elasticache_nodes')
-        else:
-            self.all_elasticache_nodes = False
-
-        # boto configuration profile (prefer CLI argument)
-        self.boto_profile = self.args.boto_profile
-        if config.has_option('ec2', 'boto_profile') and not self.boto_profile:
-            self.boto_profile = config.get('ec2', 'boto_profile')
-
-        # Cache related
-        cache_dir = os.path.expanduser(config.get('ec2', 'cache_path'))
-        if self.boto_profile:
-            cache_dir = os.path.join(cache_dir, 'profile_' + self.boto_profile)
-        if not os.path.exists(cache_dir):
-            os.makedirs(cache_dir)
-
-        cache_name = 'ansible-ec2'
-        aws_profile = lambda: (self.boto_profile or
-                               os.environ.get('AWS_PROFILE') or
-                               os.environ.get('AWS_ACCESS_KEY_ID'))
-        if aws_profile():
-            cache_name = '%s-%s' % (cache_name, aws_profile())
-        self.cache_path_cache = cache_dir + "/%s.cache" % cache_name
-        self.cache_path_index = cache_dir + "/%s.index" % cache_name
-        self.cache_max_age = config.getint('ec2', 'cache_max_age')
-
-        if config.has_option('ec2', 'expand_csv_tags'):
-            self.expand_csv_tags = config.getboolean('ec2', 'expand_csv_tags')
-        else:
-            self.expand_csv_tags = False
-
-        # Configure nested groups instead of flat namespace.
-        if config.has_option('ec2', 'nested_groups'):
-            self.nested_groups = config.getboolean('ec2', 'nested_groups')
-        else:
-            self.nested_groups = False
-
-        # Replace dash or not in group names
-        if config.has_option('ec2', 'replace_dash_in_groups'):
-            self.replace_dash_in_groups = config.getboolean('ec2', 'replace_dash_in_groups')
-        else:
-            self.replace_dash_in_groups = True
-
-        # Configure which groups should be created.
-        group_by_options = [
-            'group_by_instance_id',
-            'group_by_region',
-            'group_by_availability_zone',
-            'group_by_ami_id',
-            'group_by_instance_type',
-            'group_by_key_pair',
-            'group_by_vpc_id',
-            'group_by_security_group',
-            'group_by_tag_keys',
-            'group_by_tag_none',
-            'group_by_route53_names',
-            'group_by_rds_engine',
-            'group_by_rds_parameter_group',
-            'group_by_elasticache_engine',
-            'group_by_elasticache_cluster',
-            'group_by_elasticache_parameter_group',
-            'group_by_elasticache_replication_group',
-        ]
-        for option in group_by_options:
-            if config.has_option('ec2', option):
-                setattr(self, option, config.getboolean('ec2', option))
-            else:
-                setattr(self, option, True)
-
-        # Do we need to just include hosts that match a pattern?
-        try:
-            pattern_include = config.get('ec2', 'pattern_include')
-            if pattern_include and len(pattern_include) > 0:
-                self.pattern_include = re.compile(pattern_include)
-            else:
-                self.pattern_include = None
-        except configparser.NoOptionError:
-            self.pattern_include = None
-
-        # Do we need to exclude hosts that match a pattern?
-        try:
-            pattern_exclude = config.get('ec2', 'pattern_exclude');
-            if pattern_exclude and len(pattern_exclude) > 0:
-                self.pattern_exclude = re.compile(pattern_exclude)
-            else:
-                self.pattern_exclude = None
-        except configparser.NoOptionError:
-            self.pattern_exclude = None
-
-        # Instance filters (see boto and EC2 API docs). Ignore invalid filters.
-        self.ec2_instance_filters = defaultdict(list)
-        if config.has_option('ec2', 'instance_filters'):
-
-            filters = [f for f in config.get('ec2', 'instance_filters').split(',') if f]
-
-            for instance_filter in filters:
-                instance_filter = instance_filter.strip()
-                if not instance_filter or '=' not in instance_filter:
-                    continue
-                filter_key, filter_value = [x.strip() for x in instance_filter.split('=', 1)]
-                if not filter_key:
-                    continue
-                self.ec2_instance_filters[filter_key].append(filter_value)
-
-    def parse_cli_args(self):
-        ''' Command line argument processing '''
-
-        parser = argparse.ArgumentParser(description='Produce an Ansible Inventory file based on EC2')
-        parser.add_argument('--list', action='store_true', default=True,
-                            help='List instances (default: True)')
-        parser.add_argument('--host', action='store',
-                            help='Get all the variables about a specific instance')
-        parser.add_argument('--refresh-cache', action='store_true', default=False,
-                            help='Force refresh of cache by making API requests to EC2 (default: False - use cache files)')
-        parser.add_argument('--profile', '--boto-profile', action='store', dest='boto_profile',
-                            help='Use boto profile for connections to EC2')
-        self.args = parser.parse_args()
-
-
-    def do_api_calls_update_cache(self):
-        ''' Do API calls to each region, and save data in cache files '''
-
-        if self.route53_enabled:
-            self.get_route53_records()
-
-        for region in self.regions:
-            self.get_instances_by_region(region)
-            if self.rds_enabled:
-                self.get_rds_instances_by_region(region)
-            if self.elasticache_enabled:
-                self.get_elasticache_clusters_by_region(region)
-                self.get_elasticache_replication_groups_by_region(region)
-
-        self.write_to_cache(self.inventory, self.cache_path_cache)
-        self.write_to_cache(self.index, self.cache_path_index)
-
-    def connect(self, region):
-        ''' create connection to api server'''
-        if self.eucalyptus:
-            conn = boto.connect_euca(host=self.eucalyptus_host)
-            conn.APIVersion = '2010-08-31'
-        else:
-            conn = self.connect_to_aws(ec2, region)
-        return conn
-
-    def boto_fix_security_token_in_profile(self, connect_args):
-        ''' monkey patch for boto issue boto/boto#2100 '''
-        profile = 'profile ' + self.boto_profile
-        if boto.config.has_option(profile, 'aws_security_token'):
-            connect_args['security_token'] = boto.config.get(profile, 'aws_security_token')
-        return connect_args
-
-    def connect_to_aws(self, module, region):
-        connect_args = {}
-
-        # only pass the profile name if it's set (as it is not supported by older boto versions)
-        if self.boto_profile:
-            connect_args['profile_name'] = self.boto_profile
-            self.boto_fix_security_token_in_profile(connect_args)
-
-        conn = module.connect_to_region(region, **connect_args)
-        # connect_to_region will fail "silently" by returning None if the region name is wrong or not supported
-        if conn is None:
-            self.fail_with_error("region name: %s likely not supported, or AWS is down.  connection to region failed." % region)
-        return conn
-
-    def get_instances_by_region(self, region):
-        ''' Makes an AWS EC2 API call to the list of instances in a particular
-        region '''
-
-        try:
-            conn = self.connect(region)
-            reservations = []
-            if self.ec2_instance_filters:
-                for filter_key, filter_values in self.ec2_instance_filters.items():
-                    reservations.extend(conn.get_all_instances(filters = { filter_key : filter_values }))
-            else:
-                reservations = conn.get_all_instances()
-
-            for reservation in reservations:
-                for instance in reservation.instances:
-                    self.add_instance(instance, region)
-
-        except boto.exception.BotoServerError as e:
-            if e.error_code == 'AuthFailure':
-                error = self.get_auth_error_message()
-            else:
-                backend = 'Eucalyptus' if self.eucalyptus else 'AWS'
-                error = "Error connecting to %s backend.\n%s" % (backend, e.message)
-            self.fail_with_error(error, 'getting EC2 instances')
-
-    def get_rds_instances_by_region(self, region):
-        ''' Makes an AWS API call to the list of RDS instances in a particular
-        region '''
-
-        try:
-            conn = self.connect_to_aws(rds, region)
-            if conn:
-                marker = None
-                while True:
-                    instances = conn.get_all_dbinstances(marker=marker)
-                    marker = instances.marker
-                    for instance in instances:
-                        self.add_rds_instance(instance, region)
-                    if not marker:
-                        break
-        except boto.exception.BotoServerError as e:
-            error = e.reason
-
-            if e.error_code == 'AuthFailure':
-                error = self.get_auth_error_message()
-            if not e.reason == "Forbidden":
-                error = "Looks like AWS RDS is down:\n%s" % e.message
-            self.fail_with_error(error, 'getting RDS instances')
-
-    def get_elasticache_clusters_by_region(self, region):
-        ''' Makes an AWS API call to the list of ElastiCache clusters (with
-        nodes' info) in a particular region.'''
-
-        # ElastiCache boto module doesn't provide a get_all_intances method,
-        # that's why we need to call describe directly (it would be called by
-        # the shorthand method anyway...)
-        try:
-            conn = self.connect_to_aws(elasticache, region)
-            if conn:
-                # show_cache_node_info = True
-                # because we also want nodes' information
-                response = conn.describe_cache_clusters(None, None, None, True)
-
-        except boto.exception.BotoServerError as e:
-            error = e.reason
-
-            if e.error_code == 'AuthFailure':
-                error = self.get_auth_error_message()
-            if not e.reason == "Forbidden":
-                error = "Looks like AWS ElastiCache is down:\n%s" % e.message
-            self.fail_with_error(error, 'getting ElastiCache clusters')
-
-        try:
-            # Boto also doesn't provide wrapper classes to CacheClusters or
-            # CacheNodes. Because of that wo can't make use of the get_list
-            # method in the AWSQueryConnection. Let's do the work manually
-            clusters = response['DescribeCacheClustersResponse']['DescribeCacheClustersResult']['CacheClusters']
-
-        except KeyError as e:
-            error = "ElastiCache query to AWS failed (unexpected format)."
-            self.fail_with_error(error, 'getting ElastiCache clusters')
-
-        for cluster in clusters:
-            self.add_elasticache_cluster(cluster, region)
-
-    def get_elasticache_replication_groups_by_region(self, region):
-        ''' Makes an AWS API call to the list of ElastiCache replication groups
-        in a particular region.'''
-
-        # ElastiCache boto module doesn't provide a get_all_intances method,
-        # that's why we need to call describe directly (it would be called by
-        # the shorthand method anyway...)
-        try:
-            conn = self.connect_to_aws(elasticache, region)
-            if conn:
-                response = conn.describe_replication_groups()
-
-        except boto.exception.BotoServerError as e:
-            error = e.reason
-
-            if e.error_code == 'AuthFailure':
-                error = self.get_auth_error_message()
-            if not e.reason == "Forbidden":
-                error = "Looks like AWS ElastiCache [Replication Groups] is down:\n%s" % e.message
-            self.fail_with_error(error, 'getting ElastiCache clusters')
-
-        try:
-            # Boto also doesn't provide wrapper classes to ReplicationGroups
-            # Because of that wo can't make use of the get_list method in the
-            # AWSQueryConnection. Let's do the work manually
-            replication_groups = response['DescribeReplicationGroupsResponse']['DescribeReplicationGroupsResult']['ReplicationGroups']
-
-        except KeyError as e:
-            error = "ElastiCache [Replication Groups] query to AWS failed (unexpected format)."
-            self.fail_with_error(error, 'getting ElastiCache clusters')
-
-        for replication_group in replication_groups:
-            self.add_elasticache_replication_group(replication_group, region)
-
-    def get_auth_error_message(self):
-        ''' create an informative error message if there is an issue authenticating'''
-        errors = ["Authentication error retrieving ec2 inventory."]
-        if None in [os.environ.get('AWS_ACCESS_KEY_ID'), os.environ.get('AWS_SECRET_ACCESS_KEY')]:
-            errors.append(' - No AWS_ACCESS_KEY_ID or AWS_SECRET_ACCESS_KEY environment vars found')
-        else:
-            errors.append(' - AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY environment vars found but may not be correct')
-
-        boto_paths = ['/etc/boto.cfg', '~/.boto', '~/.aws/credentials']
-        boto_config_found = list(p for p in boto_paths if os.path.isfile(os.path.expanduser(p)))
-        if len(boto_config_found) > 0:
-            errors.append(" - Boto configs found at '%s', but the credentials contained may not be correct" % ', '.join(boto_config_found))
-        else:
-            errors.append(" - No Boto config found at any expected location '%s'" % ', '.join(boto_paths))
-
-        return '\n'.join(errors)
-
-    def fail_with_error(self, err_msg, err_operation=None):
-        '''log an error to std err for ansible-playbook to consume and exit'''
-        if err_operation:
-            err_msg = 'ERROR: "{err_msg}", while: {err_operation}'.format(
-                    err_msg=err_msg, err_operation=err_operation)
-        sys.stderr.write(err_msg)
-        sys.exit(1)
-
-    def get_instance(self, region, instance_id):
-        conn = self.connect(region)
-
-        reservations = conn.get_all_instances([instance_id])
-        for reservation in reservations:
-            for instance in reservation.instances:
-                return instance
-
-    def add_instance(self, instance, region):
-        ''' Adds an instance to the inventory and index, as long as it is
-        addressable '''
-
-        # Only return instances with desired instance states
-        if instance.state not in self.ec2_instance_states:
-            return
-
-        # Select the best destination address
-        if self.destination_format and self.destination_format_tags:
-            dest = self.destination_format.format(*[ getattr(instance, 'tags').get(tag, '') for tag in self.destination_format_tags ])
-        elif instance.subnet_id:
-            dest = getattr(instance, self.vpc_destination_variable, None)
-            if dest is None:
-                dest = getattr(instance, 'tags').get(self.vpc_destination_variable, None)
-        else:
-            dest = getattr(instance, self.destination_variable, None)
-            if dest is None:
-                dest = getattr(instance, 'tags').get(self.destination_variable, None)
-
-        if not dest:
-            # Skip instances we cannot address (e.g. private VPC subnet)
-            return
-
-        # Set the inventory name
-        hostname = None
-        if self.hostname_variable:
-            if self.hostname_variable.startswith('tag_'):
-                hostname = instance.tags.get(self.hostname_variable[4:], None)
-            else:
-                hostname = getattr(instance, self.hostname_variable)
-
-        # If we can't get a nice hostname, use the destination address
-        if not hostname:
-            hostname = dest
-        else:
-            hostname = self.to_safe(hostname).lower()
-
-        # if we only want to include hosts that match a pattern, skip those that don't
-        if self.pattern_include and not self.pattern_include.match(hostname):
-            return
-
-        # if we need to exclude hosts that match a pattern, skip those
-        if self.pattern_exclude and self.pattern_exclude.match(hostname):
-            return
-
-        # Add to index
-        self.index[hostname] = [region, instance.id]
-
-        # Inventory: Group by instance ID (always a group of 1)
-        if self.group_by_instance_id:
-            self.inventory[instance.id] = [hostname]
-            if self.nested_groups:
-                self.push_group(self.inventory, 'instances', instance.id)
-
-        # Inventory: Group by region
-        if self.group_by_region:
-            self.push(self.inventory, region, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'regions', region)
-
-        # Inventory: Group by availability zone
-        if self.group_by_availability_zone:
-            self.push(self.inventory, instance.placement, hostname)
-            if self.nested_groups:
-                if self.group_by_region:
-                    self.push_group(self.inventory, region, instance.placement)
-                self.push_group(self.inventory, 'zones', instance.placement)
-
-        # Inventory: Group by Amazon Machine Image (AMI) ID
-        if self.group_by_ami_id:
-            ami_id = self.to_safe(instance.image_id)
-            self.push(self.inventory, ami_id, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'images', ami_id)
-
-        # Inventory: Group by instance type
-        if self.group_by_instance_type:
-            type_name = self.to_safe('type_' + instance.instance_type)
-            self.push(self.inventory, type_name, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'types', type_name)
-
-        # Inventory: Group by key pair
-        if self.group_by_key_pair and instance.key_name:
-            key_name = self.to_safe('key_' + instance.key_name)
-            self.push(self.inventory, key_name, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'keys', key_name)
-
-        # Inventory: Group by VPC
-        if self.group_by_vpc_id and instance.vpc_id:
-            vpc_id_name = self.to_safe('vpc_id_' + instance.vpc_id)
-            self.push(self.inventory, vpc_id_name, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'vpcs', vpc_id_name)
-
-        # Inventory: Group by security group
-        if self.group_by_security_group:
-            try:
-                for group in instance.groups:
-                    key = self.to_safe("security_group_" + group.name)
-                    self.push(self.inventory, key, hostname)
-                    if self.nested_groups:
-                        self.push_group(self.inventory, 'security_groups', key)
-            except AttributeError:
-                self.fail_with_error('\n'.join(['Package boto seems a bit older.',
-                                                'Please upgrade boto >= 2.3.0.']))
-
-        # Inventory: Group by tag keys
-        if self.group_by_tag_keys:
-            for k, v in instance.tags.items():
-                if self.expand_csv_tags and v and ',' in v:
-                    values = map(lambda x: x.strip(), v.split(','))
-                else:
-                    values = [v]
-
-                for v in values:
-                    if v:
-                        key = self.to_safe("tag_" + k + "=" + v)
-                    else:
-                        key = self.to_safe("tag_" + k)
-                    self.push(self.inventory, key, hostname)
-                    if self.nested_groups:
-                        self.push_group(self.inventory, 'tags', self.to_safe("tag_" + k))
-                        if v:
-                            self.push_group(self.inventory, self.to_safe("tag_" + k), key)
-
-        # Inventory: Group by Route53 domain names if enabled
-        if self.route53_enabled and self.group_by_route53_names:
-            route53_names = self.get_instance_route53_names(instance)
-            for name in route53_names:
-                self.push(self.inventory, name, hostname)
-                if self.nested_groups:
-                    self.push_group(self.inventory, 'route53', name)
-
-        # Global Tag: instances without tags
-        if self.group_by_tag_none and len(instance.tags) == 0:
-            self.push(self.inventory, 'tag_none', hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'tags', 'tag_none')
-
-        # Global Tag: tag all EC2 instances
-        self.push(self.inventory, 'ec2', hostname)
-
-        self.inventory["_meta"]["hostvars"][hostname] = self.get_host_info_dict_from_instance(instance)
-        self.inventory["_meta"]["hostvars"][hostname]['ansible_ssh_host'] = dest
-
-
-    def add_rds_instance(self, instance, region):
-        ''' Adds an RDS instance to the inventory and index, as long as it is
-        addressable '''
-
-        # Only want available instances unless all_rds_instances is True
-        if not self.all_rds_instances and instance.status != 'available':
-            return
-
-        # Select the best destination address
-        dest = instance.endpoint[0]
-
-        if not dest:
-            # Skip instances we cannot address (e.g. private VPC subnet)
-            return
-
-        # Set the inventory name
-        hostname = None
-        if self.hostname_variable:
-            if self.hostname_variable.startswith('tag_'):
-                hostname = instance.tags.get(self.hostname_variable[4:], None)
-            else:
-                hostname = getattr(instance, self.hostname_variable)
-
-        # If we can't get a nice hostname, use the destination address
-        if not hostname:
-            hostname = dest
-
-        hostname = self.to_safe(hostname).lower()
-
-        # Add to index
-        self.index[hostname] = [region, instance.id]
-
-        # Inventory: Group by instance ID (always a group of 1)
-        if self.group_by_instance_id:
-            self.inventory[instance.id] = [hostname]
-            if self.nested_groups:
-                self.push_group(self.inventory, 'instances', instance.id)
-
-        # Inventory: Group by region
-        if self.group_by_region:
-            self.push(self.inventory, region, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'regions', region)
-
-        # Inventory: Group by availability zone
-        if self.group_by_availability_zone:
-            self.push(self.inventory, instance.availability_zone, hostname)
-            if self.nested_groups:
-                if self.group_by_region:
-                    self.push_group(self.inventory, region, instance.availability_zone)
-                self.push_group(self.inventory, 'zones', instance.availability_zone)
-
-        # Inventory: Group by instance type
-        if self.group_by_instance_type:
-            type_name = self.to_safe('type_' + instance.instance_class)
-            self.push(self.inventory, type_name, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'types', type_name)
-
-        # Inventory: Group by VPC
-        if self.group_by_vpc_id and instance.subnet_group and instance.subnet_group.vpc_id:
-            vpc_id_name = self.to_safe('vpc_id_' + instance.subnet_group.vpc_id)
-            self.push(self.inventory, vpc_id_name, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'vpcs', vpc_id_name)
-
-        # Inventory: Group by security group
-        if self.group_by_security_group:
-            try:
-                if instance.security_group:
-                    key = self.to_safe("security_group_" + instance.security_group.name)
-                    self.push(self.inventory, key, hostname)
-                    if self.nested_groups:
-                        self.push_group(self.inventory, 'security_groups', key)
-
-            except AttributeError:
-                self.fail_with_error('\n'.join(['Package boto seems a bit older.',
-                                                'Please upgrade boto >= 2.3.0.']))
-
-
-        # Inventory: Group by engine
-        if self.group_by_rds_engine:
-            self.push(self.inventory, self.to_safe("rds_" + instance.engine), hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'rds_engines', self.to_safe("rds_" + instance.engine))
-
-        # Inventory: Group by parameter group
-        if self.group_by_rds_parameter_group:
-            self.push(self.inventory, self.to_safe("rds_parameter_group_" + instance.parameter_group.name), hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'rds_parameter_groups', self.to_safe("rds_parameter_group_" + instance.parameter_group.name))
-
-        # Global Tag: all RDS instances
-        self.push(self.inventory, 'rds', hostname)
-
-        self.inventory["_meta"]["hostvars"][hostname] = self.get_host_info_dict_from_instance(instance)
-        self.inventory["_meta"]["hostvars"][hostname]['ansible_ssh_host'] = dest
-
-    def add_elasticache_cluster(self, cluster, region):
-        ''' Adds an ElastiCache cluster to the inventory and index, as long as
-        it's nodes are addressable '''
-
-        # Only want available clusters unless all_elasticache_clusters is True
-        if not self.all_elasticache_clusters and cluster['CacheClusterStatus'] != 'available':
-            return
-
-        # Select the best destination address
-        if 'ConfigurationEndpoint' in cluster and cluster['ConfigurationEndpoint']:
-            # Memcached cluster
-            dest = cluster['ConfigurationEndpoint']['Address']
-            is_redis = False
-        else:
-            # Redis sigle node cluster
-            # Because all Redis clusters are single nodes, we'll merge the
-            # info from the cluster with info about the node
-            dest = cluster['CacheNodes'][0]['Endpoint']['Address']
-            is_redis = True
-
-        if not dest:
-            # Skip clusters we cannot address (e.g. private VPC subnet)
-            return
-
-        # Add to index
-        self.index[dest] = [region, cluster['CacheClusterId']]
-
-        # Inventory: Group by instance ID (always a group of 1)
-        if self.group_by_instance_id:
-            self.inventory[cluster['CacheClusterId']] = [dest]
-            if self.nested_groups:
-                self.push_group(self.inventory, 'instances', cluster['CacheClusterId'])
-
-        # Inventory: Group by region
-        if self.group_by_region and not is_redis:
-            self.push(self.inventory, region, dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'regions', region)
-
-        # Inventory: Group by availability zone
-        if self.group_by_availability_zone and not is_redis:
-            self.push(self.inventory, cluster['PreferredAvailabilityZone'], dest)
-            if self.nested_groups:
-                if self.group_by_region:
-                    self.push_group(self.inventory, region, cluster['PreferredAvailabilityZone'])
-                self.push_group(self.inventory, 'zones', cluster['PreferredAvailabilityZone'])
-
-        # Inventory: Group by node type
-        if self.group_by_instance_type and not is_redis:
-            type_name = self.to_safe('type_' + cluster['CacheNodeType'])
-            self.push(self.inventory, type_name, dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'types', type_name)
-
-        # Inventory: Group by VPC (information not available in the current
-        # AWS API version for ElastiCache)
-
-        # Inventory: Group by security group
-        if self.group_by_security_group and not is_redis:
-
-            # Check for the existence of the 'SecurityGroups' key and also if
-            # this key has some value. When the cluster is not placed in a SG
-            # the query can return None here and cause an error.
-            if 'SecurityGroups' in cluster and cluster['SecurityGroups'] is not None:
-                for security_group in cluster['SecurityGroups']:
-                    key = self.to_safe("security_group_" + security_group['SecurityGroupId'])
-                    self.push(self.inventory, key, dest)
-                    if self.nested_groups:
-                        self.push_group(self.inventory, 'security_groups', key)
-
-        # Inventory: Group by engine
-        if self.group_by_elasticache_engine and not is_redis:
-            self.push(self.inventory, self.to_safe("elasticache_" + cluster['Engine']), dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'elasticache_engines', self.to_safe(cluster['Engine']))
-
-        # Inventory: Group by parameter group
-        if self.group_by_elasticache_parameter_group:
-            self.push(self.inventory, self.to_safe("elasticache_parameter_group_" + cluster['CacheParameterGroup']['CacheParameterGroupName']), dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'elasticache_parameter_groups', self.to_safe(cluster['CacheParameterGroup']['CacheParameterGroupName']))
-
-        # Inventory: Group by replication group
-        if self.group_by_elasticache_replication_group and 'ReplicationGroupId' in cluster and cluster['ReplicationGroupId']:
-            self.push(self.inventory, self.to_safe("elasticache_replication_group_" + cluster['ReplicationGroupId']), dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'elasticache_replication_groups', self.to_safe(cluster['ReplicationGroupId']))
-
-        # Global Tag: all ElastiCache clusters
-        self.push(self.inventory, 'elasticache_clusters', cluster['CacheClusterId'])
-
-        host_info = self.get_host_info_dict_from_describe_dict(cluster)
-
-        self.inventory["_meta"]["hostvars"][dest] = host_info
-
-        # Add the nodes
-        for node in cluster['CacheNodes']:
-            self.add_elasticache_node(node, cluster, region)
-
-    def add_elasticache_node(self, node, cluster, region):
-        ''' Adds an ElastiCache node to the inventory and index, as long as
-        it is addressable '''
-
-        # Only want available nodes unless all_elasticache_nodes is True
-        if not self.all_elasticache_nodes and node['CacheNodeStatus'] != 'available':
-            return
-
-        # Select the best destination address
-        dest = node['Endpoint']['Address']
-
-        if not dest:
-            # Skip nodes we cannot address (e.g. private VPC subnet)
-            return
-
-        node_id = self.to_safe(cluster['CacheClusterId'] + '_' + node['CacheNodeId'])
-
-        # Add to index
-        self.index[dest] = [region, node_id]
-
-        # Inventory: Group by node ID (always a group of 1)
-        if self.group_by_instance_id:
-            self.inventory[node_id] = [dest]
-            if self.nested_groups:
-                self.push_group(self.inventory, 'instances', node_id)
-
-        # Inventory: Group by region
-        if self.group_by_region:
-            self.push(self.inventory, region, dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'regions', region)
-
-        # Inventory: Group by availability zone
-        if self.group_by_availability_zone:
-            self.push(self.inventory, cluster['PreferredAvailabilityZone'], dest)
-            if self.nested_groups:
-                if self.group_by_region:
-                    self.push_group(self.inventory, region, cluster['PreferredAvailabilityZone'])
-                self.push_group(self.inventory, 'zones', cluster['PreferredAvailabilityZone'])
-
-        # Inventory: Group by node type
-        if self.group_by_instance_type:
-            type_name = self.to_safe('type_' + cluster['CacheNodeType'])
-            self.push(self.inventory, type_name, dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'types', type_name)
-
-        # Inventory: Group by VPC (information not available in the current
-        # AWS API version for ElastiCache)
-
-        # Inventory: Group by security group
-        if self.group_by_security_group:
-
-            # Check for the existence of the 'SecurityGroups' key and also if
-            # this key has some value. When the cluster is not placed in a SG
-            # the query can return None here and cause an error.
-            if 'SecurityGroups' in cluster and cluster['SecurityGroups'] is not None:
-                for security_group in cluster['SecurityGroups']:
-                    key = self.to_safe("security_group_" + security_group['SecurityGroupId'])
-                    self.push(self.inventory, key, dest)
-                    if self.nested_groups:
-                        self.push_group(self.inventory, 'security_groups', key)
-
-        # Inventory: Group by engine
-        if self.group_by_elasticache_engine:
-            self.push(self.inventory, self.to_safe("elasticache_" + cluster['Engine']), dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'elasticache_engines', self.to_safe("elasticache_" + cluster['Engine']))
-
-        # Inventory: Group by parameter group (done at cluster level)
-
-        # Inventory: Group by replication group (done at cluster level)
-
-        # Inventory: Group by ElastiCache Cluster
-        if self.group_by_elasticache_cluster:
-            self.push(self.inventory, self.to_safe("elasticache_cluster_" + cluster['CacheClusterId']), dest)
-
-        # Global Tag: all ElastiCache nodes
-        self.push(self.inventory, 'elasticache_nodes', dest)
-
-        host_info = self.get_host_info_dict_from_describe_dict(node)
-
-        if dest in self.inventory["_meta"]["hostvars"]:
-            self.inventory["_meta"]["hostvars"][dest].update(host_info)
-        else:
-            self.inventory["_meta"]["hostvars"][dest] = host_info
-
-    def add_elasticache_replication_group(self, replication_group, region):
-        ''' Adds an ElastiCache replication group to the inventory and index '''
-
-        # Only want available clusters unless all_elasticache_replication_groups is True
-        if not self.all_elasticache_replication_groups and replication_group['Status'] != 'available':
-            return
-
-        # Select the best destination address (PrimaryEndpoint)
-        dest = replication_group['NodeGroups'][0]['PrimaryEndpoint']['Address']
-
-        if not dest:
-            # Skip clusters we cannot address (e.g. private VPC subnet)
-            return
-
-        # Add to index
-        self.index[dest] = [region, replication_group['ReplicationGroupId']]
-
-        # Inventory: Group by ID (always a group of 1)
-        if self.group_by_instance_id:
-            self.inventory[replication_group['ReplicationGroupId']] = [dest]
-            if self.nested_groups:
-                self.push_group(self.inventory, 'instances', replication_group['ReplicationGroupId'])
-
-        # Inventory: Group by region
-        if self.group_by_region:
-            self.push(self.inventory, region, dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'regions', region)
-
-        # Inventory: Group by availability zone (doesn't apply to replication groups)
-
-        # Inventory: Group by node type (doesn't apply to replication groups)
-
-        # Inventory: Group by VPC (information not available in the current
-        # AWS API version for replication groups
-
-        # Inventory: Group by security group (doesn't apply to replication groups)
-        # Check this value in cluster level
-
-        # Inventory: Group by engine (replication groups are always Redis)
-        if self.group_by_elasticache_engine:
-            self.push(self.inventory, 'elasticache_redis', dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'elasticache_engines', 'redis')
-
-        # Global Tag: all ElastiCache clusters
-        self.push(self.inventory, 'elasticache_replication_groups', replication_group['ReplicationGroupId'])
-
-        host_info = self.get_host_info_dict_from_describe_dict(replication_group)
-
-        self.inventory["_meta"]["hostvars"][dest] = host_info
-
-    def get_route53_records(self):
-        ''' Get and store the map of resource records to domain names that
-        point to them. '''
-
-        r53_conn = route53.Route53Connection()
-        all_zones = r53_conn.get_zones()
-
-        route53_zones = [ zone for zone in all_zones if zone.name[:-1]
-                          not in self.route53_excluded_zones ]
-
-        self.route53_records = {}
-
-        for zone in route53_zones:
-            rrsets = r53_conn.get_all_rrsets(zone.id)
-
-            for record_set in rrsets:
-                record_name = record_set.name
-
-                if record_name.endswith('.'):
-                    record_name = record_name[:-1]
-
-                for resource in record_set.resource_records:
-                    self.route53_records.setdefault(resource, set())
-                    self.route53_records[resource].add(record_name)
-
-
-    def get_instance_route53_names(self, instance):
-        ''' Check if an instance is referenced in the records we have from
-        Route53. If it is, return the list of domain names pointing to said
-        instance. If nothing points to it, return an empty list. '''
-
-        instance_attributes = [ 'public_dns_name', 'private_dns_name',
-                                'ip_address', 'private_ip_address' ]
-
-        name_list = set()
-
-        for attrib in instance_attributes:
-            try:
-                value = getattr(instance, attrib)
-            except AttributeError:
-                continue
-
-            if value in self.route53_records:
-                name_list.update(self.route53_records[value])
-
-        return list(name_list)
-
-    def get_host_info_dict_from_instance(self, instance):
-        instance_vars = {}
-        for key in vars(instance):
-            value = getattr(instance, key)
-            key = self.to_safe('ec2_' + key)
-
-            # Handle complex types
-            # state/previous_state changed to properties in boto in https://github.com/boto/boto/commit/a23c379837f698212252720d2af8dec0325c9518
-            if key == 'ec2__state':
-                instance_vars['ec2_state'] = instance.state or ''
-                instance_vars['ec2_state_code'] = instance.state_code
-            elif key == 'ec2__previous_state':
-                instance_vars['ec2_previous_state'] = instance.previous_state or ''
-                instance_vars['ec2_previous_state_code'] = instance.previous_state_code
-            elif type(value) in [int, bool]:
-                instance_vars[key] = value
-            elif isinstance(value, six.string_types):
-                instance_vars[key] = value.strip()
-            elif type(value) == type(None):
-                instance_vars[key] = ''
-            elif key == 'ec2_region':
-                instance_vars[key] = value.name
-            elif key == 'ec2__placement':
-                instance_vars['ec2_placement'] = value.zone
-            elif key == 'ec2_tags':
-                for k, v in value.items():
-                    if self.expand_csv_tags and ',' in v:
-                        v = map(lambda x: x.strip(), v.split(','))
-                    key = self.to_safe('ec2_tag_' + k)
-                    instance_vars[key] = v
-            elif key == 'ec2_groups':
-                group_ids = []
-                group_names = []
-                for group in value:
-                    group_ids.append(group.id)
-                    group_names.append(group.name)
-                instance_vars["ec2_security_group_ids"] = ','.join([str(i) for i in group_ids])
-                instance_vars["ec2_security_group_names"] = ','.join([str(i) for i in group_names])
-            else:
-                pass
-                # TODO Product codes if someone finds them useful
-                #print key
-                #print type(value)
-                #print value
-
-        return instance_vars
-
-    def get_host_info_dict_from_describe_dict(self, describe_dict):
-        ''' Parses the dictionary returned by the API call into a flat list
-            of parameters. This method should be used only when 'describe' is
-            used directly because Boto doesn't provide specific classes. '''
-
-        # I really don't agree with prefixing everything with 'ec2'
-        # because EC2, RDS and ElastiCache are different services.
-        # I'm just following the pattern used until now to not break any
-        # compatibility.
-
-        host_info = {}
-        for key in describe_dict:
-            value = describe_dict[key]
-            key = self.to_safe('ec2_' + self.uncammelize(key))
-
-            # Handle complex types
-
-            # Target: Memcached Cache Clusters
-            if key == 'ec2_configuration_endpoint' and value:
-                host_info['ec2_configuration_endpoint_address'] = value['Address']
-                host_info['ec2_configuration_endpoint_port'] = value['Port']
-
-            # Target: Cache Nodes and Redis Cache Clusters (single node)
-            if key == 'ec2_endpoint' and value:
-                host_info['ec2_endpoint_address'] = value['Address']
-                host_info['ec2_endpoint_port'] = value['Port']
-
-            # Target: Redis Replication Groups
-            if key == 'ec2_node_groups' and value:
-                host_info['ec2_endpoint_address'] = value[0]['PrimaryEndpoint']['Address']
-                host_info['ec2_endpoint_port'] = value[0]['PrimaryEndpoint']['Port']
-                replica_count = 0
-                for node in value[0]['NodeGroupMembers']:
-                    if node['CurrentRole'] == 'primary':
-                        host_info['ec2_primary_cluster_address'] = node['ReadEndpoint']['Address']
-                        host_info['ec2_primary_cluster_port'] = node['ReadEndpoint']['Port']
-                        host_info['ec2_primary_cluster_id'] = node['CacheClusterId']
-                    elif node['CurrentRole'] == 'replica':
-                        host_info['ec2_replica_cluster_address_'+ str(replica_count)] = node['ReadEndpoint']['Address']
-                        host_info['ec2_replica_cluster_port_'+ str(replica_count)] = node['ReadEndpoint']['Port']
-                        host_info['ec2_replica_cluster_id_'+ str(replica_count)] = node['CacheClusterId']
-                        replica_count += 1
-
-            # Target: Redis Replication Groups
-            if key == 'ec2_member_clusters' and value:
-                host_info['ec2_member_clusters'] = ','.join([str(i) for i in value])
-
-            # Target: All Cache Clusters
-            elif key == 'ec2_cache_parameter_group':
-                host_info["ec2_cache_node_ids_to_reboot"] = ','.join([str(i) for i in value['CacheNodeIdsToReboot']])
-                host_info['ec2_cache_parameter_group_name'] = value['CacheParameterGroupName']
-                host_info['ec2_cache_parameter_apply_status'] = value['ParameterApplyStatus']
-
-            # Target: Almost everything
-            elif key == 'ec2_security_groups':
-
-                # Skip if SecurityGroups is None
-                # (it is possible to have the key defined but no value in it).
-                if value is not None:
-                    sg_ids = []
-                    for sg in value:
-                        sg_ids.append(sg['SecurityGroupId'])
-                    host_info["ec2_security_group_ids"] = ','.join([str(i) for i in sg_ids])
-
-            # Target: Everything
-            # Preserve booleans and integers
-            elif type(value) in [int, bool]:
-                host_info[key] = value
-
-            # Target: Everything
-            # Sanitize string values
-            elif isinstance(value, six.string_types):
-                host_info[key] = value.strip()
-
-            # Target: Everything
-            # Replace None by an empty string
-            elif type(value) == type(None):
-                host_info[key] = ''
-
-            else:
-                # Remove non-processed complex types
-                pass
-
-        return host_info
-
-    def get_host_info(self):
-        ''' Get variables about a specific host '''
-
-        if len(self.index) == 0:
-            # Need to load index from cache
-            self.load_index_from_cache()
-
-        if not self.args.host in self.index:
-            # try updating the cache
-            self.do_api_calls_update_cache()
-            if not self.args.host in self.index:
-                # host might not exist anymore
-                return self.json_format_dict({}, True)
-
-        (region, instance_id) = self.index[self.args.host]
-
-        instance = self.get_instance(region, instance_id)
-        return self.json_format_dict(self.get_host_info_dict_from_instance(instance), True)
-
-    def push(self, my_dict, key, element):
-        ''' Push an element onto an array that may not have been defined in
-        the dict '''
-        group_info = my_dict.setdefault(key, [])
-        if isinstance(group_info, dict):
-            host_list = group_info.setdefault('hosts', [])
-            host_list.append(element)
-        else:
-            group_info.append(element)
-
-    def push_group(self, my_dict, key, element):
-        ''' Push a group as a child of another group. '''
-        parent_group = my_dict.setdefault(key, {})
-        if not isinstance(parent_group, dict):
-            parent_group = my_dict[key] = {'hosts': parent_group}
-        child_groups = parent_group.setdefault('children', [])
-        if element not in child_groups:
-            child_groups.append(element)
-
-    def get_inventory_from_cache(self):
-        ''' Reads the inventory from the cache file and returns it as a JSON
-        object '''
-
-        cache = open(self.cache_path_cache, 'r')
-        json_inventory = cache.read()
-        return json_inventory
-
-
-    def load_index_from_cache(self):
-        ''' Reads the index from the cache file sets self.index '''
-
-        cache = open(self.cache_path_index, 'r')
-        json_index = cache.read()
-        self.index = json.loads(json_index)
-
-
-    def write_to_cache(self, data, filename):
-        ''' Writes data in JSON format to a file '''
-
-        json_data = self.json_format_dict(data, True)
-        cache = open(filename, 'w')
-        cache.write(json_data)
-        cache.close()
-
-    def uncammelize(self, key):
-        temp = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', key)
-        return re.sub('([a-z0-9])([A-Z])', r'\1_\2', temp).lower()
-
-    def to_safe(self, word):
-        ''' Converts 'bad' characters in a string to underscores so they can be used as Ansible groups '''
-        regex = "[^A-Za-z0-9\_"
-        if not self.replace_dash_in_groups:
-            regex += "\-"
-        return re.sub(regex + "]", "_", word)
-
-    def json_format_dict(self, data, pretty=False):
-        ''' Converts a dict to a JSON object and dumps it as a formatted
-        string '''
-
-        if pretty:
-            return json.dumps(data, sort_keys=True, indent=2)
-        else:
-            return json.dumps(data)
-
-
-# Run the script
-Ec2Inventory()
diff --git a/baas-1701-dc7/inventory b/baas-1701-dc7/inventory
deleted file mode 100644
index a87db34..0000000
--- a/baas-1701-dc7/inventory
+++ /dev/null
@@ -1,67 +0,0 @@
-[tag_Name_dc7_n11]
-[tag_Name_dc7_n12]
-[tag_Name_dc7_n13]
-[tag_Name_dc7_n14]
-[tag_Name_dc7_n15]
-[tag_Name_dc7_n16]
-[tag_Name_dc7_n17]
-[tag_Name_dc7_n18]
-[tag_Name_dc7_n19]
-[tag_Name_dc7_n20]
-
-[planet:children]
-dc-1
-
-[dc-1:children]
-tag_Name_dc7_n11
-tag_Name_dc7_n12
-tag_Name_dc7_n13
-tag_Name_dc7_n14
-tag_Name_dc7_n15
-tag_Name_dc7_n16
-tag_Name_dc7_n17
-tag_Name_dc7_n18
-tag_Name_dc7_n19
-tag_Name_dc7_n20
-
-[elastic:children]
-dc-1-elastic
-
-[dc-1-elastic:children]
-tag_Name_dc7_n11
-tag_Name_dc7_n12
-tag_Name_dc7_n13
-
-[baas:children]
-dc-1-baas
-
-[dc-1-baas:children]
-tag_Name_dc7_n14
-tag_Name_dc7_n15
-tag_Name_dc7_n16
-
-[portal:children]
-dc-1-portal
-
-[dc-1-portal:children]
-tag_Name_dc7_n17
-
-[ds:children]
-dc-1-ds
-
-[dc-1-ds:children]
-dc-1-cassandra
-
-[cassandra:children]
-dc-1-cassandra
-
-[dc-1-cassandra:children]
-tag_Name_dc7_n18
-tag_Name_dc7_n19
-tag_Name_dc7_n20
-
-[ms:children]
-dc-1-ms
-
-[dc-1-ms:children]
-tag_Name_dc7_n17
diff --git a/edge-1601-aio/ec2.ini b/edge-1601-aio/ec2.ini
deleted file mode 100644
index 36b3921..0000000
--- a/edge-1601-aio/ec2.ini
+++ /dev/null
@@ -1,200 +0,0 @@
-# Ansible EC2 external inventory script settings
-#
-
-[ec2]
-
-# to talk to a private eucalyptus instance uncomment these lines
-# and edit edit eucalyptus_host to be the host name of your cloud controller
-#eucalyptus = True
-#eucalyptus_host = clc.cloud.domain.org
-
-# AWS regions to make calls to. Set this to 'all' to make request to all regions
-# in AWS and merge the results together. Alternatively, set this to a comma
-# separated list of regions. E.g. 'us-east-1,us-west-1,us-west-2'
-regions = all
-regions_exclude = us-gov-west-1,cn-north-1
-
-# When generating inventory, Ansible needs to know how to address a server.
-# Each EC2 instance has a lot of variables associated with it. Here is the list:
-#   http://docs.pythonboto.org/en/latest/ref/ec2.html#module-boto.ec2.instance
-# Below are 2 variables that are used as the address of a server:
-#   - destination_variable
-#   - vpc_destination_variable
-
-# This is the normal destination variable to use. If you are running Ansible
-# from outside EC2, then 'public_dns_name' makes the most sense. If you are
-# running Ansible from within EC2, then perhaps you want to use the internal
-# address, and should set this to 'private_dns_name'. The key of an EC2 tag
-# may optionally be used; however the boto instance variables hold precedence
-# in the event of a collision.
-destination_variable = public_dns_name
-
-# This allows you to override the inventory_name with an ec2 variable, instead
-# of using the destination_variable above. Addressing (aka ansible_ssh_host)
-# will still use destination_variable. Tags should be written as 'tag_TAGNAME'.
-#hostname_variable = tag_Name
-
-# For server inside a VPC, using DNS names may not make sense. When an instance
-# has 'subnet_id' set, this variable is used. If the subnet is public, setting
-# this to 'ip_address' will return the public IP address. For instances in a
-# private subnet, this should be set to 'private_ip_address', and Ansible must
-# be run from within EC2. The key of an EC2 tag may optionally be used; however
-# the boto instance variables hold precedence in the event of a collision.
-# WARNING: - instances that are in the private vpc, _without_ public ip address
-# will not be listed in the inventory until You set:
-# vpc_destination_variable = private_ip_address
-vpc_destination_variable = ip_address
-
-# The following two settings allow flexible ansible host naming based on a
-# python format string and a comma-separated list of ec2 tags.  Note that:
-#
-# 1) If the tags referenced are not present for some instances, empty strings
-#    will be substituted in the format string.
-# 2) This overrides both destination_variable and vpc_destination_variable.
-#
-#destination_format = {0}.{1}.example.com
-#destination_format_tags = Name,environment
-
-# To tag instances on EC2 with the resource records that point to them from
-# Route53, uncomment and set 'route53' to True.
-route53 = False
-
-# To exclude RDS instances from the inventory, uncomment and set to False.
-rds = False
-
-# To exclude ElastiCache instances from the inventory, uncomment and set to False.
-elasticache = False
-
-# Additionally, you can specify the list of zones to exclude looking up in
-# 'route53_excluded_zones' as a comma-separated list.
-# route53_excluded_zones = samplezone1.com, samplezone2.com
-
-# By default, only EC2 instances in the 'running' state are returned. Set
-# 'all_instances' to True to return all instances regardless of state.
-all_instances = True
-
-# By default, only EC2 instances in the 'running' state are returned. Specify
-# EC2 instance states to return as a comma-separated list. This
-# option is overriden when 'all_instances' is True.
-# instance_states = pending, running, shutting-down, terminated, stopping, stopped
-
-# By default, only RDS instances in the 'available' state are returned.  Set
-# 'all_rds_instances' to True return all RDS instances regardless of state.
-all_rds_instances = False
-
-# By default, only ElastiCache clusters and nodes in the 'available' state
-# are returned. Set 'all_elasticache_clusters' and/or 'all_elastic_nodes'
-# to True return all ElastiCache clusters and nodes, regardless of state.
-#
-# Note that all_elasticache_nodes only applies to listed clusters. That means
-# if you set all_elastic_clusters to false, no node will be return from
-# unavailable clusters, regardless of the state and to what you set for
-# all_elasticache_nodes.
-all_elasticache_replication_groups = False
-all_elasticache_clusters = False
-all_elasticache_nodes = False
-
-# API calls to EC2 are slow. For this reason, we cache the results of an API
-# call. Set this to the path you want cache files to be written to. Two files
-# will be written to this directory:
-#   - ansible-ec2.cache
-#   - ansible-ec2.index
-cache_path = ~/.ansible/tmp
-
-# The number of seconds a cache file is considered valid. After this many
-# seconds, a new API call will be made, and the cache file will be updated.
-# To disable the cache, set this value to 0
-cache_max_age = 300
-
-# Organize groups into a nested/hierarchy instead of a flat namespace.
-nested_groups = False
-
-# Replace - tags when creating groups to avoid issues with ansible
-replace_dash_in_groups = True
-
-# If set to true, any tag of the form "a,b,c" is expanded into a list
-# and the results are used to create additional tag_* inventory groups.
-expand_csv_tags = False
-
-# The EC2 inventory output can become very large. To manage its size,
-# configure which groups should be created.
-group_by_instance_id = True
-group_by_region = True
-group_by_availability_zone = True
-group_by_ami_id = True
-group_by_instance_type = True
-group_by_key_pair = True
-group_by_vpc_id = True
-group_by_security_group = True
-group_by_tag_keys = True
-group_by_tag_none = True
-group_by_route53_names = True
-group_by_rds_engine = False
-group_by_rds_parameter_group = False
-group_by_elasticache_engine = True
-group_by_elasticache_cluster = True
-group_by_elasticache_parameter_group = True
-group_by_elasticache_replication_group = True
-
-# If you only want to include hosts that match a certain regular expression
-# pattern_include = staging-*
-
-# If you want to exclude any hosts that match a certain regular expression
-# pattern_exclude = staging-*
-# Ansible EC2 external inventory script settings
-#
-
-##[ec2]
-##
-### to talk to a private eucalyptus instance uncomment these lines
-### and edit edit eucalyptus_host to be the host name of your cloud controller
-###eucalyptus = True
-###eucalyptus_host = clc.cloud.domain.org
-##
-### AWS regions to make calls to. Set this to 'all' to make request to all regions
-##
-### in AWS and merge the results together. Alternatively, set this to a comma
-### separated list of regions. E.g. 'us-east-1,us-west-1,us-west-2'
-##regions = all
-##regions_exclude = us-gov-west-1,cn-north-1
-##
-### When generating inventory, Ansible needs to know how to address a server.
-### Each EC2 instance has a lot of variables associated with it. Here is the list:
-###   http://docs.pythonboto.org/en/latest/ref/ec2.html#module-boto.ec2.instance
-### Below are 2 variables that are used as the address of a server:
-###   - destination_variable
-###   - vpc_destination_variable
-##
-### This is the normal destination variable to use. If you are running Ansible
-### from outside EC2, then 'public_dns_name' makes the most sense. If you are
-### running Ansible from within EC2, then perhaps you want to use the internal
-### address, and should set this to 'private_dns_name'. The key of an EC2 tag
-##...skipping...
-### pattern_include = staging-*
-##
-### If you want to exclude any hosts that match a certain regular expression
-### pattern_exclude = staging-*
-
-# Instance filters can be used to control which instances are retrieved for
-# inventory. For the full list of possible filters, please read the EC2 API
-# docs: http://docs.aws.amazon.com/AWSEC2/latest/APIReference/ApiReference-query-DescribeInstances.html#query-DescribeInstances-filters
-# Filters are key/value pairs separated by '=', to list multiple filters use
-# a list separated by commas. See examples below.
-
-# Retrieve only instances with (key=value) env=staging tag
-# instance_filters = tag:env=staging
-
-# Retrieve only instances with role=webservers OR role=dbservers tag
-# instance_filters = tag:role=webservers,tag:role=dbservers
-
-# Retrieve only t1.micro instances OR instances with tag env=staging
-# instance_filters = instance-type=t1.micro,tag:env=staging
-
-# You can use wildcards in filter values also. Below will list instances which
-# tag Name value matches webservers1*
-# (ex. webservers15, webservers1a, webservers123 etc)
-# instance_filters = tag:Name=webservers1*
-
-# A boto configuration profile may be used to separate out credentials
-# see http://boto.readthedocs.org/en/latest/boto_config_tut.html
-# boto_profile = some-boto-profile-name
diff --git a/edge-1601-aio/ec2.py b/edge-1601-aio/ec2.py
deleted file mode 100755
index f30958a..0000000
--- a/edge-1601-aio/ec2.py
+++ /dev/null
@@ -1,1385 +0,0 @@
-#!/usr/bin/env python
-
-'''
-EC2 external inventory script
-=================================
-
-Generates inventory that Ansible can understand by making API request to
-AWS EC2 using the Boto library.
-
-NOTE: This script assumes Ansible is being executed where the environment
-variables needed for Boto have already been set:
-    export AWS_ACCESS_KEY_ID='AK123'
-    export AWS_SECRET_ACCESS_KEY='abc123'
-
-This script also assumes there is an ec2.ini file alongside it.  To specify a
-different path to ec2.ini, define the EC2_INI_PATH environment variable:
-
-    export EC2_INI_PATH=/path/to/my_ec2.ini
-
-If you're using eucalyptus you need to set the above variables and
-you need to define:
-
-    export EC2_URL=http://hostname_of_your_cc:port/services/Eucalyptus
-
-If you're using boto profiles (requires boto>=2.24.0) you can choose a profile
-using the --boto-profile command line argument (e.g. ec2.py --boto-profile prod) or using
-the AWS_PROFILE variable:
-
-    AWS_PROFILE=prod ansible-playbook -i ec2.py myplaybook.yml
-
-For more details, see: http://docs.pythonboto.org/en/latest/boto_config_tut.html
-
-When run against a specific host, this script returns the following variables:
- - ec2_ami_launch_index
- - ec2_architecture
- - ec2_association
- - ec2_attachTime
- - ec2_attachment
- - ec2_attachmentId
- - ec2_client_token
- - ec2_deleteOnTermination
- - ec2_description
- - ec2_deviceIndex
- - ec2_dns_name
- - ec2_eventsSet
- - ec2_group_name
- - ec2_hypervisor
- - ec2_id
- - ec2_image_id
- - ec2_instanceState
- - ec2_instance_type
- - ec2_ipOwnerId
- - ec2_ip_address
- - ec2_item
- - ec2_kernel
- - ec2_key_name
- - ec2_launch_time
- - ec2_monitored
- - ec2_monitoring
- - ec2_networkInterfaceId
- - ec2_ownerId
- - ec2_persistent
- - ec2_placement
- - ec2_platform
- - ec2_previous_state
- - ec2_private_dns_name
- - ec2_private_ip_address
- - ec2_publicIp
- - ec2_public_dns_name
- - ec2_ramdisk
- - ec2_reason
- - ec2_region
- - ec2_requester_id
- - ec2_root_device_name
- - ec2_root_device_type
- - ec2_security_group_ids
- - ec2_security_group_names
- - ec2_shutdown_state
- - ec2_sourceDestCheck
- - ec2_spot_instance_request_id
- - ec2_state
- - ec2_state_code
- - ec2_state_reason
- - ec2_status
- - ec2_subnet_id
- - ec2_tenancy
- - ec2_virtualization_type
- - ec2_vpc_id
-
-These variables are pulled out of a boto.ec2.instance object. There is a lack of
-consistency with variable spellings (camelCase and underscores) since this
-just loops through all variables the object exposes. It is preferred to use the
-ones with underscores when multiple exist.
-
-In addition, if an instance has AWS Tags associated with it, each tag is a new
-variable named:
- - ec2_tag_[Key] = [Value]
-
-Security groups are comma-separated in 'ec2_security_group_ids' and
-'ec2_security_group_names'.
-'''
-
-# (c) 2012, Peter Sankauskas
-#
-# This file is part of Ansible,
-#
-# Ansible is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# Ansible is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with Ansible.  If not, see <http://www.gnu.org/licenses/>.
-
-######################################################################
-
-import sys
-import os
-import argparse
-import re
-from time import time
-import boto
-from boto import ec2
-from boto import rds
-from boto import elasticache
-from boto import route53
-import six
-
-from six.moves import configparser
-from collections import defaultdict
-
-try:
-    import json
-except ImportError:
-    import simplejson as json
-
-
-class Ec2Inventory(object):
-
-    def _empty_inventory(self):
-        return {"_meta" : {"hostvars" : {}}}
-
-    def __init__(self):
-        ''' Main execution path '''
-
-        # Inventory grouped by instance IDs, tags, security groups, regions,
-        # and availability zones
-        self.inventory = self._empty_inventory()
-
-        # Index of hostname (address) to instance ID
-        self.index = {}
-
-        # Boto profile to use (if any)
-        self.boto_profile = None
-
-        # Read settings and parse CLI arguments
-        self.parse_cli_args()
-        self.read_settings()
-
-        # Make sure that profile_name is not passed at all if not set
-        # as pre 2.24 boto will fall over otherwise
-        if self.boto_profile:
-            if not hasattr(boto.ec2.EC2Connection, 'profile_name'):
-                self.fail_with_error("boto version must be >= 2.24 to use profile")
-
-        # Cache
-        if self.args.refresh_cache:
-            self.do_api_calls_update_cache()
-        elif not self.is_cache_valid():
-            self.do_api_calls_update_cache()
-
-        # Data to print
-        if self.args.host:
-            data_to_print = self.get_host_info()
-
-        elif self.args.list:
-            # Display list of instances for inventory
-            if self.inventory == self._empty_inventory():
-                data_to_print = self.get_inventory_from_cache()
-            else:
-                data_to_print = self.json_format_dict(self.inventory, True)
-
-        print(data_to_print)
-
-
-    def is_cache_valid(self):
-        ''' Determines if the cache files have expired, or if it is still valid '''
-
-        if os.path.isfile(self.cache_path_cache):
-            mod_time = os.path.getmtime(self.cache_path_cache)
-            current_time = time()
-            if (mod_time + self.cache_max_age) > current_time:
-                if os.path.isfile(self.cache_path_index):
-                    return True
-
-        return False
-
-
-    def read_settings(self):
-        ''' Reads the settings from the ec2.ini file '''
-        if six.PY3:
-            config = configparser.ConfigParser()
-        else:
-            config = configparser.SafeConfigParser()
-        ec2_default_ini_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'ec2.ini')
-        ec2_ini_path = os.path.expanduser(os.path.expandvars(os.environ.get('EC2_INI_PATH', ec2_default_ini_path)))
-        config.read(ec2_ini_path)
-
-        # is eucalyptus?
-        self.eucalyptus_host = None
-        self.eucalyptus = False
-        if config.has_option('ec2', 'eucalyptus'):
-            self.eucalyptus = config.getboolean('ec2', 'eucalyptus')
-        if self.eucalyptus and config.has_option('ec2', 'eucalyptus_host'):
-            self.eucalyptus_host = config.get('ec2', 'eucalyptus_host')
-
-        # Regions
-        self.regions = []
-        configRegions = config.get('ec2', 'regions')
-        configRegions_exclude = config.get('ec2', 'regions_exclude')
-        if (configRegions == 'all'):
-            if self.eucalyptus_host:
-                self.regions.append(boto.connect_euca(host=self.eucalyptus_host).region.name)
-            else:
-                for regionInfo in ec2.regions():
-                    if regionInfo.name not in configRegions_exclude:
-                        self.regions.append(regionInfo.name)
-        else:
-            self.regions = configRegions.split(",")
-
-        # Destination addresses
-        self.destination_variable = config.get('ec2', 'destination_variable')
-        self.vpc_destination_variable = config.get('ec2', 'vpc_destination_variable')
-
-        if config.has_option('ec2', 'hostname_variable'):
-            self.hostname_variable = config.get('ec2', 'hostname_variable')
-        else:
-            self.hostname_variable = None
-
-        if config.has_option('ec2', 'destination_format') and \
-                config.has_option('ec2', 'destination_format_tags'):
-            self.destination_format = config.get('ec2', 'destination_format')
-            self.destination_format_tags = config.get('ec2', 'destination_format_tags').split(',')
-        else:
-            self.destination_format = None
-            self.destination_format_tags = None
-
-        # Route53
-        self.route53_enabled = config.getboolean('ec2', 'route53')
-        self.route53_excluded_zones = []
-        if config.has_option('ec2', 'route53_excluded_zones'):
-            self.route53_excluded_zones.extend(
-                    config.get('ec2', 'route53_excluded_zones', '').split(','))
-
-        # Include RDS instances?
-        self.rds_enabled = True
-        if config.has_option('ec2', 'rds'):
-            self.rds_enabled = config.getboolean('ec2', 'rds')
-
-        # Include ElastiCache instances?
-        self.elasticache_enabled = True
-        if config.has_option('ec2', 'elasticache'):
-            self.elasticache_enabled = config.getboolean('ec2', 'elasticache')
-
-        # Return all EC2 instances?
-        if config.has_option('ec2', 'all_instances'):
-            self.all_instances = config.getboolean('ec2', 'all_instances')
-        else:
-            self.all_instances = False
-
-        # Instance states to be gathered in inventory. Default is 'running'.
-        # Setting 'all_instances' to 'yes' overrides this option.
-        ec2_valid_instance_states = [
-            'pending',
-            'running',
-            'shutting-down',
-            'terminated',
-            'stopping',
-            'stopped'
-        ]
-        self.ec2_instance_states = []
-        if self.all_instances:
-            self.ec2_instance_states = ec2_valid_instance_states
-        elif config.has_option('ec2', 'instance_states'):
-            for instance_state in config.get('ec2', 'instance_states').split(','):
-                instance_state = instance_state.strip()
-                if instance_state not in ec2_valid_instance_states:
-                    continue
-                self.ec2_instance_states.append(instance_state)
-        else:
-            self.ec2_instance_states = ['running']
-
-        # Return all RDS instances? (if RDS is enabled)
-        if config.has_option('ec2', 'all_rds_instances') and self.rds_enabled:
-            self.all_rds_instances = config.getboolean('ec2', 'all_rds_instances')
-        else:
-            self.all_rds_instances = False
-
-        # Return all ElastiCache replication groups? (if ElastiCache is enabled)
-        if config.has_option('ec2', 'all_elasticache_replication_groups') and self.elasticache_enabled:
-            self.all_elasticache_replication_groups = config.getboolean('ec2', 'all_elasticache_replication_groups')
-        else:
-            self.all_elasticache_replication_groups = False
-
-        # Return all ElastiCache clusters? (if ElastiCache is enabled)
-        if config.has_option('ec2', 'all_elasticache_clusters') and self.elasticache_enabled:
-            self.all_elasticache_clusters = config.getboolean('ec2', 'all_elasticache_clusters')
-        else:
-            self.all_elasticache_clusters = False
-
-        # Return all ElastiCache nodes? (if ElastiCache is enabled)
-        if config.has_option('ec2', 'all_elasticache_nodes') and self.elasticache_enabled:
-            self.all_elasticache_nodes = config.getboolean('ec2', 'all_elasticache_nodes')
-        else:
-            self.all_elasticache_nodes = False
-
-        # boto configuration profile (prefer CLI argument)
-        self.boto_profile = self.args.boto_profile
-        if config.has_option('ec2', 'boto_profile') and not self.boto_profile:
-            self.boto_profile = config.get('ec2', 'boto_profile')
-
-        # Cache related
-        cache_dir = os.path.expanduser(config.get('ec2', 'cache_path'))
-        if self.boto_profile:
-            cache_dir = os.path.join(cache_dir, 'profile_' + self.boto_profile)
-        if not os.path.exists(cache_dir):
-            os.makedirs(cache_dir)
-
-        cache_name = 'ansible-ec2'
-        aws_profile = lambda: (self.boto_profile or
-                               os.environ.get('AWS_PROFILE') or
-                               os.environ.get('AWS_ACCESS_KEY_ID'))
-        if aws_profile():
-            cache_name = '%s-%s' % (cache_name, aws_profile())
-        self.cache_path_cache = cache_dir + "/%s.cache" % cache_name
-        self.cache_path_index = cache_dir + "/%s.index" % cache_name
-        self.cache_max_age = config.getint('ec2', 'cache_max_age')
-
-        if config.has_option('ec2', 'expand_csv_tags'):
-            self.expand_csv_tags = config.getboolean('ec2', 'expand_csv_tags')
-        else:
-            self.expand_csv_tags = False
-
-        # Configure nested groups instead of flat namespace.
-        if config.has_option('ec2', 'nested_groups'):
-            self.nested_groups = config.getboolean('ec2', 'nested_groups')
-        else:
-            self.nested_groups = False
-
-        # Replace dash or not in group names
-        if config.has_option('ec2', 'replace_dash_in_groups'):
-            self.replace_dash_in_groups = config.getboolean('ec2', 'replace_dash_in_groups')
-        else:
-            self.replace_dash_in_groups = True
-
-        # Configure which groups should be created.
-        group_by_options = [
-            'group_by_instance_id',
-            'group_by_region',
-            'group_by_availability_zone',
-            'group_by_ami_id',
-            'group_by_instance_type',
-            'group_by_key_pair',
-            'group_by_vpc_id',
-            'group_by_security_group',
-            'group_by_tag_keys',
-            'group_by_tag_none',
-            'group_by_route53_names',
-            'group_by_rds_engine',
-            'group_by_rds_parameter_group',
-            'group_by_elasticache_engine',
-            'group_by_elasticache_cluster',
-            'group_by_elasticache_parameter_group',
-            'group_by_elasticache_replication_group',
-        ]
-        for option in group_by_options:
-            if config.has_option('ec2', option):
-                setattr(self, option, config.getboolean('ec2', option))
-            else:
-                setattr(self, option, True)
-
-        # Do we need to just include hosts that match a pattern?
-        try:
-            pattern_include = config.get('ec2', 'pattern_include')
-            if pattern_include and len(pattern_include) > 0:
-                self.pattern_include = re.compile(pattern_include)
-            else:
-                self.pattern_include = None
-        except configparser.NoOptionError:
-            self.pattern_include = None
-
-        # Do we need to exclude hosts that match a pattern?
-        try:
-            pattern_exclude = config.get('ec2', 'pattern_exclude');
-            if pattern_exclude and len(pattern_exclude) > 0:
-                self.pattern_exclude = re.compile(pattern_exclude)
-            else:
-                self.pattern_exclude = None
-        except configparser.NoOptionError:
-            self.pattern_exclude = None
-
-        # Instance filters (see boto and EC2 API docs). Ignore invalid filters.
-        self.ec2_instance_filters = defaultdict(list)
-        if config.has_option('ec2', 'instance_filters'):
-
-            filters = [f for f in config.get('ec2', 'instance_filters').split(',') if f]
-
-            for instance_filter in filters:
-                instance_filter = instance_filter.strip()
-                if not instance_filter or '=' not in instance_filter:
-                    continue
-                filter_key, filter_value = [x.strip() for x in instance_filter.split('=', 1)]
-                if not filter_key:
-                    continue
-                self.ec2_instance_filters[filter_key].append(filter_value)
-
-    def parse_cli_args(self):
-        ''' Command line argument processing '''
-
-        parser = argparse.ArgumentParser(description='Produce an Ansible Inventory file based on EC2')
-        parser.add_argument('--list', action='store_true', default=True,
-                            help='List instances (default: True)')
-        parser.add_argument('--host', action='store',
-                            help='Get all the variables about a specific instance')
-        parser.add_argument('--refresh-cache', action='store_true', default=False,
-                            help='Force refresh of cache by making API requests to EC2 (default: False - use cache files)')
-        parser.add_argument('--profile', '--boto-profile', action='store', dest='boto_profile',
-                            help='Use boto profile for connections to EC2')
-        self.args = parser.parse_args()
-
-
-    def do_api_calls_update_cache(self):
-        ''' Do API calls to each region, and save data in cache files '''
-
-        if self.route53_enabled:
-            self.get_route53_records()
-
-        for region in self.regions:
-            self.get_instances_by_region(region)
-            if self.rds_enabled:
-                self.get_rds_instances_by_region(region)
-            if self.elasticache_enabled:
-                self.get_elasticache_clusters_by_region(region)
-                self.get_elasticache_replication_groups_by_region(region)
-
-        self.write_to_cache(self.inventory, self.cache_path_cache)
-        self.write_to_cache(self.index, self.cache_path_index)
-
-    def connect(self, region):
-        ''' create connection to api server'''
-        if self.eucalyptus:
-            conn = boto.connect_euca(host=self.eucalyptus_host)
-            conn.APIVersion = '2010-08-31'
-        else:
-            conn = self.connect_to_aws(ec2, region)
-        return conn
-
-    def boto_fix_security_token_in_profile(self, connect_args):
-        ''' monkey patch for boto issue boto/boto#2100 '''
-        profile = 'profile ' + self.boto_profile
-        if boto.config.has_option(profile, 'aws_security_token'):
-            connect_args['security_token'] = boto.config.get(profile, 'aws_security_token')
-        return connect_args
-
-    def connect_to_aws(self, module, region):
-        connect_args = {}
-
-        # only pass the profile name if it's set (as it is not supported by older boto versions)
-        if self.boto_profile:
-            connect_args['profile_name'] = self.boto_profile
-            self.boto_fix_security_token_in_profile(connect_args)
-
-        conn = module.connect_to_region(region, **connect_args)
-        # connect_to_region will fail "silently" by returning None if the region name is wrong or not supported
-        if conn is None:
-            self.fail_with_error("region name: %s likely not supported, or AWS is down.  connection to region failed." % region)
-        return conn
-
-    def get_instances_by_region(self, region):
-        ''' Makes an AWS EC2 API call to the list of instances in a particular
-        region '''
-
-        try:
-            conn = self.connect(region)
-            reservations = []
-            if self.ec2_instance_filters:
-                for filter_key, filter_values in self.ec2_instance_filters.items():
-                    reservations.extend(conn.get_all_instances(filters = { filter_key : filter_values }))
-            else:
-                reservations = conn.get_all_instances()
-
-            for reservation in reservations:
-                for instance in reservation.instances:
-                    self.add_instance(instance, region)
-
-        except boto.exception.BotoServerError as e:
-            if e.error_code == 'AuthFailure':
-                error = self.get_auth_error_message()
-            else:
-                backend = 'Eucalyptus' if self.eucalyptus else 'AWS'
-                error = "Error connecting to %s backend.\n%s" % (backend, e.message)
-            self.fail_with_error(error, 'getting EC2 instances')
-
-    def get_rds_instances_by_region(self, region):
-        ''' Makes an AWS API call to the list of RDS instances in a particular
-        region '''
-
-        try:
-            conn = self.connect_to_aws(rds, region)
-            if conn:
-                marker = None
-                while True:
-                    instances = conn.get_all_dbinstances(marker=marker)
-                    marker = instances.marker
-                    for instance in instances:
-                        self.add_rds_instance(instance, region)
-                    if not marker:
-                        break
-        except boto.exception.BotoServerError as e:
-            error = e.reason
-
-            if e.error_code == 'AuthFailure':
-                error = self.get_auth_error_message()
-            if not e.reason == "Forbidden":
-                error = "Looks like AWS RDS is down:\n%s" % e.message
-            self.fail_with_error(error, 'getting RDS instances')
-
-    def get_elasticache_clusters_by_region(self, region):
-        ''' Makes an AWS API call to the list of ElastiCache clusters (with
-        nodes' info) in a particular region.'''
-
-        # ElastiCache boto module doesn't provide a get_all_intances method,
-        # that's why we need to call describe directly (it would be called by
-        # the shorthand method anyway...)
-        try:
-            conn = self.connect_to_aws(elasticache, region)
-            if conn:
-                # show_cache_node_info = True
-                # because we also want nodes' information
-                response = conn.describe_cache_clusters(None, None, None, True)
-
-        except boto.exception.BotoServerError as e:
-            error = e.reason
-
-            if e.error_code == 'AuthFailure':
-                error = self.get_auth_error_message()
-            if not e.reason == "Forbidden":
-                error = "Looks like AWS ElastiCache is down:\n%s" % e.message
-            self.fail_with_error(error, 'getting ElastiCache clusters')
-
-        try:
-            # Boto also doesn't provide wrapper classes to CacheClusters or
-            # CacheNodes. Because of that wo can't make use of the get_list
-            # method in the AWSQueryConnection. Let's do the work manually
-            clusters = response['DescribeCacheClustersResponse']['DescribeCacheClustersResult']['CacheClusters']
-
-        except KeyError as e:
-            error = "ElastiCache query to AWS failed (unexpected format)."
-            self.fail_with_error(error, 'getting ElastiCache clusters')
-
-        for cluster in clusters:
-            self.add_elasticache_cluster(cluster, region)
-
-    def get_elasticache_replication_groups_by_region(self, region):
-        ''' Makes an AWS API call to the list of ElastiCache replication groups
-        in a particular region.'''
-
-        # ElastiCache boto module doesn't provide a get_all_intances method,
-        # that's why we need to call describe directly (it would be called by
-        # the shorthand method anyway...)
-        try:
-            conn = self.connect_to_aws(elasticache, region)
-            if conn:
-                response = conn.describe_replication_groups()
-
-        except boto.exception.BotoServerError as e:
-            error = e.reason
-
-            if e.error_code == 'AuthFailure':
-                error = self.get_auth_error_message()
-            if not e.reason == "Forbidden":
-                error = "Looks like AWS ElastiCache [Replication Groups] is down:\n%s" % e.message
-            self.fail_with_error(error, 'getting ElastiCache clusters')
-
-        try:
-            # Boto also doesn't provide wrapper classes to ReplicationGroups
-            # Because of that wo can't make use of the get_list method in the
-            # AWSQueryConnection. Let's do the work manually
-            replication_groups = response['DescribeReplicationGroupsResponse']['DescribeReplicationGroupsResult']['ReplicationGroups']
-
-        except KeyError as e:
-            error = "ElastiCache [Replication Groups] query to AWS failed (unexpected format)."
-            self.fail_with_error(error, 'getting ElastiCache clusters')
-
-        for replication_group in replication_groups:
-            self.add_elasticache_replication_group(replication_group, region)
-
-    def get_auth_error_message(self):
-        ''' create an informative error message if there is an issue authenticating'''
-        errors = ["Authentication error retrieving ec2 inventory."]
-        if None in [os.environ.get('AWS_ACCESS_KEY_ID'), os.environ.get('AWS_SECRET_ACCESS_KEY')]:
-            errors.append(' - No AWS_ACCESS_KEY_ID or AWS_SECRET_ACCESS_KEY environment vars found')
-        else:
-            errors.append(' - AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY environment vars found but may not be correct')
-
-        boto_paths = ['/etc/boto.cfg', '~/.boto', '~/.aws/credentials']
-        boto_config_found = list(p for p in boto_paths if os.path.isfile(os.path.expanduser(p)))
-        if len(boto_config_found) > 0:
-            errors.append(" - Boto configs found at '%s', but the credentials contained may not be correct" % ', '.join(boto_config_found))
-        else:
-            errors.append(" - No Boto config found at any expected location '%s'" % ', '.join(boto_paths))
-
-        return '\n'.join(errors)
-
-    def fail_with_error(self, err_msg, err_operation=None):
-        '''log an error to std err for ansible-playbook to consume and exit'''
-        if err_operation:
-            err_msg = 'ERROR: "{err_msg}", while: {err_operation}'.format(
-                    err_msg=err_msg, err_operation=err_operation)
-        sys.stderr.write(err_msg)
-        sys.exit(1)
-
-    def get_instance(self, region, instance_id):
-        conn = self.connect(region)
-
-        reservations = conn.get_all_instances([instance_id])
-        for reservation in reservations:
-            for instance in reservation.instances:
-                return instance
-
-    def add_instance(self, instance, region):
-        ''' Adds an instance to the inventory and index, as long as it is
-        addressable '''
-
-        # Only return instances with desired instance states
-        if instance.state not in self.ec2_instance_states:
-            return
-
-        # Select the best destination address
-        if self.destination_format and self.destination_format_tags:
-            dest = self.destination_format.format(*[ getattr(instance, 'tags').get(tag, '') for tag in self.destination_format_tags ])
-        elif instance.subnet_id:
-            dest = getattr(instance, self.vpc_destination_variable, None)
-            if dest is None:
-                dest = getattr(instance, 'tags').get(self.vpc_destination_variable, None)
-        else:
-            dest = getattr(instance, self.destination_variable, None)
-            if dest is None:
-                dest = getattr(instance, 'tags').get(self.destination_variable, None)
-
-        if not dest:
-            # Skip instances we cannot address (e.g. private VPC subnet)
-            return
-
-        # Set the inventory name
-        hostname = None
-        if self.hostname_variable:
-            if self.hostname_variable.startswith('tag_'):
-                hostname = instance.tags.get(self.hostname_variable[4:], None)
-            else:
-                hostname = getattr(instance, self.hostname_variable)
-
-        # If we can't get a nice hostname, use the destination address
-        if not hostname:
-            hostname = dest
-        else:
-            hostname = self.to_safe(hostname).lower()
-
-        # if we only want to include hosts that match a pattern, skip those that don't
-        if self.pattern_include and not self.pattern_include.match(hostname):
-            return
-
-        # if we need to exclude hosts that match a pattern, skip those
-        if self.pattern_exclude and self.pattern_exclude.match(hostname):
-            return
-
-        # Add to index
-        self.index[hostname] = [region, instance.id]
-
-        # Inventory: Group by instance ID (always a group of 1)
-        if self.group_by_instance_id:
-            self.inventory[instance.id] = [hostname]
-            if self.nested_groups:
-                self.push_group(self.inventory, 'instances', instance.id)
-
-        # Inventory: Group by region
-        if self.group_by_region:
-            self.push(self.inventory, region, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'regions', region)
-
-        # Inventory: Group by availability zone
-        if self.group_by_availability_zone:
-            self.push(self.inventory, instance.placement, hostname)
-            if self.nested_groups:
-                if self.group_by_region:
-                    self.push_group(self.inventory, region, instance.placement)
-                self.push_group(self.inventory, 'zones', instance.placement)
-
-        # Inventory: Group by Amazon Machine Image (AMI) ID
-        if self.group_by_ami_id:
-            ami_id = self.to_safe(instance.image_id)
-            self.push(self.inventory, ami_id, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'images', ami_id)
-
-        # Inventory: Group by instance type
-        if self.group_by_instance_type:
-            type_name = self.to_safe('type_' + instance.instance_type)
-            self.push(self.inventory, type_name, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'types', type_name)
-
-        # Inventory: Group by key pair
-        if self.group_by_key_pair and instance.key_name:
-            key_name = self.to_safe('key_' + instance.key_name)
-            self.push(self.inventory, key_name, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'keys', key_name)
-
-        # Inventory: Group by VPC
-        if self.group_by_vpc_id and instance.vpc_id:
-            vpc_id_name = self.to_safe('vpc_id_' + instance.vpc_id)
-            self.push(self.inventory, vpc_id_name, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'vpcs', vpc_id_name)
-
-        # Inventory: Group by security group
-        if self.group_by_security_group:
-            try:
-                for group in instance.groups:
-                    key = self.to_safe("security_group_" + group.name)
-                    self.push(self.inventory, key, hostname)
-                    if self.nested_groups:
-                        self.push_group(self.inventory, 'security_groups', key)
-            except AttributeError:
-                self.fail_with_error('\n'.join(['Package boto seems a bit older.',
-                                                'Please upgrade boto >= 2.3.0.']))
-
-        # Inventory: Group by tag keys
-        if self.group_by_tag_keys:
-            for k, v in instance.tags.items():
-                if self.expand_csv_tags and v and ',' in v:
-                    values = map(lambda x: x.strip(), v.split(','))
-                else:
-                    values = [v]
-
-                for v in values:
-                    if v:
-                        key = self.to_safe("tag_" + k + "=" + v)
-                    else:
-                        key = self.to_safe("tag_" + k)
-                    self.push(self.inventory, key, hostname)
-                    if self.nested_groups:
-                        self.push_group(self.inventory, 'tags', self.to_safe("tag_" + k))
-                        if v:
-                            self.push_group(self.inventory, self.to_safe("tag_" + k), key)
-
-        # Inventory: Group by Route53 domain names if enabled
-        if self.route53_enabled and self.group_by_route53_names:
-            route53_names = self.get_instance_route53_names(instance)
-            for name in route53_names:
-                self.push(self.inventory, name, hostname)
-                if self.nested_groups:
-                    self.push_group(self.inventory, 'route53', name)
-
-        # Global Tag: instances without tags
-        if self.group_by_tag_none and len(instance.tags) == 0:
-            self.push(self.inventory, 'tag_none', hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'tags', 'tag_none')
-
-        # Global Tag: tag all EC2 instances
-        self.push(self.inventory, 'ec2', hostname)
-
-        self.inventory["_meta"]["hostvars"][hostname] = self.get_host_info_dict_from_instance(instance)
-        self.inventory["_meta"]["hostvars"][hostname]['ansible_ssh_host'] = dest
-
-
-    def add_rds_instance(self, instance, region):
-        ''' Adds an RDS instance to the inventory and index, as long as it is
-        addressable '''
-
-        # Only want available instances unless all_rds_instances is True
-        if not self.all_rds_instances and instance.status != 'available':
-            return
-
-        # Select the best destination address
-        dest = instance.endpoint[0]
-
-        if not dest:
-            # Skip instances we cannot address (e.g. private VPC subnet)
-            return
-
-        # Set the inventory name
-        hostname = None
-        if self.hostname_variable:
-            if self.hostname_variable.startswith('tag_'):
-                hostname = instance.tags.get(self.hostname_variable[4:], None)
-            else:
-                hostname = getattr(instance, self.hostname_variable)
-
-        # If we can't get a nice hostname, use the destination address
-        if not hostname:
-            hostname = dest
-
-        hostname = self.to_safe(hostname).lower()
-
-        # Add to index
-        self.index[hostname] = [region, instance.id]
-
-        # Inventory: Group by instance ID (always a group of 1)
-        if self.group_by_instance_id:
-            self.inventory[instance.id] = [hostname]
-            if self.nested_groups:
-                self.push_group(self.inventory, 'instances', instance.id)
-
-        # Inventory: Group by region
-        if self.group_by_region:
-            self.push(self.inventory, region, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'regions', region)
-
-        # Inventory: Group by availability zone
-        if self.group_by_availability_zone:
-            self.push(self.inventory, instance.availability_zone, hostname)
-            if self.nested_groups:
-                if self.group_by_region:
-                    self.push_group(self.inventory, region, instance.availability_zone)
-                self.push_group(self.inventory, 'zones', instance.availability_zone)
-
-        # Inventory: Group by instance type
-        if self.group_by_instance_type:
-            type_name = self.to_safe('type_' + instance.instance_class)
-            self.push(self.inventory, type_name, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'types', type_name)
-
-        # Inventory: Group by VPC
-        if self.group_by_vpc_id and instance.subnet_group and instance.subnet_group.vpc_id:
-            vpc_id_name = self.to_safe('vpc_id_' + instance.subnet_group.vpc_id)
-            self.push(self.inventory, vpc_id_name, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'vpcs', vpc_id_name)
-
-        # Inventory: Group by security group
-        if self.group_by_security_group:
-            try:
-                if instance.security_group:
-                    key = self.to_safe("security_group_" + instance.security_group.name)
-                    self.push(self.inventory, key, hostname)
-                    if self.nested_groups:
-                        self.push_group(self.inventory, 'security_groups', key)
-
-            except AttributeError:
-                self.fail_with_error('\n'.join(['Package boto seems a bit older.',
-                                                'Please upgrade boto >= 2.3.0.']))
-
-
-        # Inventory: Group by engine
-        if self.group_by_rds_engine:
-            self.push(self.inventory, self.to_safe("rds_" + instance.engine), hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'rds_engines', self.to_safe("rds_" + instance.engine))
-
-        # Inventory: Group by parameter group
-        if self.group_by_rds_parameter_group:
-            self.push(self.inventory, self.to_safe("rds_parameter_group_" + instance.parameter_group.name), hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'rds_parameter_groups', self.to_safe("rds_parameter_group_" + instance.parameter_group.name))
-
-        # Global Tag: all RDS instances
-        self.push(self.inventory, 'rds', hostname)
-
-        self.inventory["_meta"]["hostvars"][hostname] = self.get_host_info_dict_from_instance(instance)
-        self.inventory["_meta"]["hostvars"][hostname]['ansible_ssh_host'] = dest
-
-    def add_elasticache_cluster(self, cluster, region):
-        ''' Adds an ElastiCache cluster to the inventory and index, as long as
-        it's nodes are addressable '''
-
-        # Only want available clusters unless all_elasticache_clusters is True
-        if not self.all_elasticache_clusters and cluster['CacheClusterStatus'] != 'available':
-            return
-
-        # Select the best destination address
-        if 'ConfigurationEndpoint' in cluster and cluster['ConfigurationEndpoint']:
-            # Memcached cluster
-            dest = cluster['ConfigurationEndpoint']['Address']
-            is_redis = False
-        else:
-            # Redis sigle node cluster
-            # Because all Redis clusters are single nodes, we'll merge the
-            # info from the cluster with info about the node
-            dest = cluster['CacheNodes'][0]['Endpoint']['Address']
-            is_redis = True
-
-        if not dest:
-            # Skip clusters we cannot address (e.g. private VPC subnet)
-            return
-
-        # Add to index
-        self.index[dest] = [region, cluster['CacheClusterId']]
-
-        # Inventory: Group by instance ID (always a group of 1)
-        if self.group_by_instance_id:
-            self.inventory[cluster['CacheClusterId']] = [dest]
-            if self.nested_groups:
-                self.push_group(self.inventory, 'instances', cluster['CacheClusterId'])
-
-        # Inventory: Group by region
-        if self.group_by_region and not is_redis:
-            self.push(self.inventory, region, dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'regions', region)
-
-        # Inventory: Group by availability zone
-        if self.group_by_availability_zone and not is_redis:
-            self.push(self.inventory, cluster['PreferredAvailabilityZone'], dest)
-            if self.nested_groups:
-                if self.group_by_region:
-                    self.push_group(self.inventory, region, cluster['PreferredAvailabilityZone'])
-                self.push_group(self.inventory, 'zones', cluster['PreferredAvailabilityZone'])
-
-        # Inventory: Group by node type
-        if self.group_by_instance_type and not is_redis:
-            type_name = self.to_safe('type_' + cluster['CacheNodeType'])
-            self.push(self.inventory, type_name, dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'types', type_name)
-
-        # Inventory: Group by VPC (information not available in the current
-        # AWS API version for ElastiCache)
-
-        # Inventory: Group by security group
-        if self.group_by_security_group and not is_redis:
-
-            # Check for the existence of the 'SecurityGroups' key and also if
-            # this key has some value. When the cluster is not placed in a SG
-            # the query can return None here and cause an error.
-            if 'SecurityGroups' in cluster and cluster['SecurityGroups'] is not None:
-                for security_group in cluster['SecurityGroups']:
-                    key = self.to_safe("security_group_" + security_group['SecurityGroupId'])
-                    self.push(self.inventory, key, dest)
-                    if self.nested_groups:
-                        self.push_group(self.inventory, 'security_groups', key)
-
-        # Inventory: Group by engine
-        if self.group_by_elasticache_engine and not is_redis:
-            self.push(self.inventory, self.to_safe("elasticache_" + cluster['Engine']), dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'elasticache_engines', self.to_safe(cluster['Engine']))
-
-        # Inventory: Group by parameter group
-        if self.group_by_elasticache_parameter_group:
-            self.push(self.inventory, self.to_safe("elasticache_parameter_group_" + cluster['CacheParameterGroup']['CacheParameterGroupName']), dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'elasticache_parameter_groups', self.to_safe(cluster['CacheParameterGroup']['CacheParameterGroupName']))
-
-        # Inventory: Group by replication group
-        if self.group_by_elasticache_replication_group and 'ReplicationGroupId' in cluster and cluster['ReplicationGroupId']:
-            self.push(self.inventory, self.to_safe("elasticache_replication_group_" + cluster['ReplicationGroupId']), dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'elasticache_replication_groups', self.to_safe(cluster['ReplicationGroupId']))
-
-        # Global Tag: all ElastiCache clusters
-        self.push(self.inventory, 'elasticache_clusters', cluster['CacheClusterId'])
-
-        host_info = self.get_host_info_dict_from_describe_dict(cluster)
-
-        self.inventory["_meta"]["hostvars"][dest] = host_info
-
-        # Add the nodes
-        for node in cluster['CacheNodes']:
-            self.add_elasticache_node(node, cluster, region)
-
-    def add_elasticache_node(self, node, cluster, region):
-        ''' Adds an ElastiCache node to the inventory and index, as long as
-        it is addressable '''
-
-        # Only want available nodes unless all_elasticache_nodes is True
-        if not self.all_elasticache_nodes and node['CacheNodeStatus'] != 'available':
-            return
-
-        # Select the best destination address
-        dest = node['Endpoint']['Address']
-
-        if not dest:
-            # Skip nodes we cannot address (e.g. private VPC subnet)
-            return
-
-        node_id = self.to_safe(cluster['CacheClusterId'] + '_' + node['CacheNodeId'])
-
-        # Add to index
-        self.index[dest] = [region, node_id]
-
-        # Inventory: Group by node ID (always a group of 1)
-        if self.group_by_instance_id:
-            self.inventory[node_id] = [dest]
-            if self.nested_groups:
-                self.push_group(self.inventory, 'instances', node_id)
-
-        # Inventory: Group by region
-        if self.group_by_region:
-            self.push(self.inventory, region, dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'regions', region)
-
-        # Inventory: Group by availability zone
-        if self.group_by_availability_zone:
-            self.push(self.inventory, cluster['PreferredAvailabilityZone'], dest)
-            if self.nested_groups:
-                if self.group_by_region:
-                    self.push_group(self.inventory, region, cluster['PreferredAvailabilityZone'])
-                self.push_group(self.inventory, 'zones', cluster['PreferredAvailabilityZone'])
-
-        # Inventory: Group by node type
-        if self.group_by_instance_type:
-            type_name = self.to_safe('type_' + cluster['CacheNodeType'])
-            self.push(self.inventory, type_name, dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'types', type_name)
-
-        # Inventory: Group by VPC (information not available in the current
-        # AWS API version for ElastiCache)
-
-        # Inventory: Group by security group
-        if self.group_by_security_group:
-
-            # Check for the existence of the 'SecurityGroups' key and also if
-            # this key has some value. When the cluster is not placed in a SG
-            # the query can return None here and cause an error.
-            if 'SecurityGroups' in cluster and cluster['SecurityGroups'] is not None:
-                for security_group in cluster['SecurityGroups']:
-                    key = self.to_safe("security_group_" + security_group['SecurityGroupId'])
-                    self.push(self.inventory, key, dest)
-                    if self.nested_groups:
-                        self.push_group(self.inventory, 'security_groups', key)
-
-        # Inventory: Group by engine
-        if self.group_by_elasticache_engine:
-            self.push(self.inventory, self.to_safe("elasticache_" + cluster['Engine']), dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'elasticache_engines', self.to_safe("elasticache_" + cluster['Engine']))
-
-        # Inventory: Group by parameter group (done at cluster level)
-
-        # Inventory: Group by replication group (done at cluster level)
-
-        # Inventory: Group by ElastiCache Cluster
-        if self.group_by_elasticache_cluster:
-            self.push(self.inventory, self.to_safe("elasticache_cluster_" + cluster['CacheClusterId']), dest)
-
-        # Global Tag: all ElastiCache nodes
-        self.push(self.inventory, 'elasticache_nodes', dest)
-
-        host_info = self.get_host_info_dict_from_describe_dict(node)
-
-        if dest in self.inventory["_meta"]["hostvars"]:
-            self.inventory["_meta"]["hostvars"][dest].update(host_info)
-        else:
-            self.inventory["_meta"]["hostvars"][dest] = host_info
-
-    def add_elasticache_replication_group(self, replication_group, region):
-        ''' Adds an ElastiCache replication group to the inventory and index '''
-
-        # Only want available clusters unless all_elasticache_replication_groups is True
-        if not self.all_elasticache_replication_groups and replication_group['Status'] != 'available':
-            return
-
-        # Select the best destination address (PrimaryEndpoint)
-        dest = replication_group['NodeGroups'][0]['PrimaryEndpoint']['Address']
-
-        if not dest:
-            # Skip clusters we cannot address (e.g. private VPC subnet)
-            return
-
-        # Add to index
-        self.index[dest] = [region, replication_group['ReplicationGroupId']]
-
-        # Inventory: Group by ID (always a group of 1)
-        if self.group_by_instance_id:
-            self.inventory[replication_group['ReplicationGroupId']] = [dest]
-            if self.nested_groups:
-                self.push_group(self.inventory, 'instances', replication_group['ReplicationGroupId'])
-
-        # Inventory: Group by region
-        if self.group_by_region:
-            self.push(self.inventory, region, dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'regions', region)
-
-        # Inventory: Group by availability zone (doesn't apply to replication groups)
-
-        # Inventory: Group by node type (doesn't apply to replication groups)
-
-        # Inventory: Group by VPC (information not available in the current
-        # AWS API version for replication groups
-
-        # Inventory: Group by security group (doesn't apply to replication groups)
-        # Check this value in cluster level
-
-        # Inventory: Group by engine (replication groups are always Redis)
-        if self.group_by_elasticache_engine:
-            self.push(self.inventory, 'elasticache_redis', dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'elasticache_engines', 'redis')
-
-        # Global Tag: all ElastiCache clusters
-        self.push(self.inventory, 'elasticache_replication_groups', replication_group['ReplicationGroupId'])
-
-        host_info = self.get_host_info_dict_from_describe_dict(replication_group)
-
-        self.inventory["_meta"]["hostvars"][dest] = host_info
-
-    def get_route53_records(self):
-        ''' Get and store the map of resource records to domain names that
-        point to them. '''
-
-        r53_conn = route53.Route53Connection()
-        all_zones = r53_conn.get_zones()
-
-        route53_zones = [ zone for zone in all_zones if zone.name[:-1]
-                          not in self.route53_excluded_zones ]
-
-        self.route53_records = {}
-
-        for zone in route53_zones:
-            rrsets = r53_conn.get_all_rrsets(zone.id)
-
-            for record_set in rrsets:
-                record_name = record_set.name
-
-                if record_name.endswith('.'):
-                    record_name = record_name[:-1]
-
-                for resource in record_set.resource_records:
-                    self.route53_records.setdefault(resource, set())
-                    self.route53_records[resource].add(record_name)
-
-
-    def get_instance_route53_names(self, instance):
-        ''' Check if an instance is referenced in the records we have from
-        Route53. If it is, return the list of domain names pointing to said
-        instance. If nothing points to it, return an empty list. '''
-
-        instance_attributes = [ 'public_dns_name', 'private_dns_name',
-                                'ip_address', 'private_ip_address' ]
-
-        name_list = set()
-
-        for attrib in instance_attributes:
-            try:
-                value = getattr(instance, attrib)
-            except AttributeError:
-                continue
-
-            if value in self.route53_records:
-                name_list.update(self.route53_records[value])
-
-        return list(name_list)
-
-    def get_host_info_dict_from_instance(self, instance):
-        instance_vars = {}
-        for key in vars(instance):
-            value = getattr(instance, key)
-            key = self.to_safe('ec2_' + key)
-
-            # Handle complex types
-            # state/previous_state changed to properties in boto in https://github.com/boto/boto/commit/a23c379837f698212252720d2af8dec0325c9518
-            if key == 'ec2__state':
-                instance_vars['ec2_state'] = instance.state or ''
-                instance_vars['ec2_state_code'] = instance.state_code
-            elif key == 'ec2__previous_state':
-                instance_vars['ec2_previous_state'] = instance.previous_state or ''
-                instance_vars['ec2_previous_state_code'] = instance.previous_state_code
-            elif type(value) in [int, bool]:
-                instance_vars[key] = value
-            elif isinstance(value, six.string_types):
-                instance_vars[key] = value.strip()
-            elif type(value) == type(None):
-                instance_vars[key] = ''
-            elif key == 'ec2_region':
-                instance_vars[key] = value.name
-            elif key == 'ec2__placement':
-                instance_vars['ec2_placement'] = value.zone
-            elif key == 'ec2_tags':
-                for k, v in value.items():
-                    if self.expand_csv_tags and ',' in v:
-                        v = map(lambda x: x.strip(), v.split(','))
-                    key = self.to_safe('ec2_tag_' + k)
-                    instance_vars[key] = v
-            elif key == 'ec2_groups':
-                group_ids = []
-                group_names = []
-                for group in value:
-                    group_ids.append(group.id)
-                    group_names.append(group.name)
-                instance_vars["ec2_security_group_ids"] = ','.join([str(i) for i in group_ids])
-                instance_vars["ec2_security_group_names"] = ','.join([str(i) for i in group_names])
-            else:
-                pass
-                # TODO Product codes if someone finds them useful
-                #print key
-                #print type(value)
-                #print value
-
-        return instance_vars
-
-    def get_host_info_dict_from_describe_dict(self, describe_dict):
-        ''' Parses the dictionary returned by the API call into a flat list
-            of parameters. This method should be used only when 'describe' is
-            used directly because Boto doesn't provide specific classes. '''
-
-        # I really don't agree with prefixing everything with 'ec2'
-        # because EC2, RDS and ElastiCache are different services.
-        # I'm just following the pattern used until now to not break any
-        # compatibility.
-
-        host_info = {}
-        for key in describe_dict:
-            value = describe_dict[key]
-            key = self.to_safe('ec2_' + self.uncammelize(key))
-
-            # Handle complex types
-
-            # Target: Memcached Cache Clusters
-            if key == 'ec2_configuration_endpoint' and value:
-                host_info['ec2_configuration_endpoint_address'] = value['Address']
-                host_info['ec2_configuration_endpoint_port'] = value['Port']
-
-            # Target: Cache Nodes and Redis Cache Clusters (single node)
-            if key == 'ec2_endpoint' and value:
-                host_info['ec2_endpoint_address'] = value['Address']
-                host_info['ec2_endpoint_port'] = value['Port']
-
-            # Target: Redis Replication Groups
-            if key == 'ec2_node_groups' and value:
-                host_info['ec2_endpoint_address'] = value[0]['PrimaryEndpoint']['Address']
-                host_info['ec2_endpoint_port'] = value[0]['PrimaryEndpoint']['Port']
-                replica_count = 0
-                for node in value[0]['NodeGroupMembers']:
-                    if node['CurrentRole'] == 'primary':
-                        host_info['ec2_primary_cluster_address'] = node['ReadEndpoint']['Address']
-                        host_info['ec2_primary_cluster_port'] = node['ReadEndpoint']['Port']
-                        host_info['ec2_primary_cluster_id'] = node['CacheClusterId']
-                    elif node['CurrentRole'] == 'replica':
-                        host_info['ec2_replica_cluster_address_'+ str(replica_count)] = node['ReadEndpoint']['Address']
-                        host_info['ec2_replica_cluster_port_'+ str(replica_count)] = node['ReadEndpoint']['Port']
-                        host_info['ec2_replica_cluster_id_'+ str(replica_count)] = node['CacheClusterId']
-                        replica_count += 1
-
-            # Target: Redis Replication Groups
-            if key == 'ec2_member_clusters' and value:
-                host_info['ec2_member_clusters'] = ','.join([str(i) for i in value])
-
-            # Target: All Cache Clusters
-            elif key == 'ec2_cache_parameter_group':
-                host_info["ec2_cache_node_ids_to_reboot"] = ','.join([str(i) for i in value['CacheNodeIdsToReboot']])
-                host_info['ec2_cache_parameter_group_name'] = value['CacheParameterGroupName']
-                host_info['ec2_cache_parameter_apply_status'] = value['ParameterApplyStatus']
-
-            # Target: Almost everything
-            elif key == 'ec2_security_groups':
-
-                # Skip if SecurityGroups is None
-                # (it is possible to have the key defined but no value in it).
-                if value is not None:
-                    sg_ids = []
-                    for sg in value:
-                        sg_ids.append(sg['SecurityGroupId'])
-                    host_info["ec2_security_group_ids"] = ','.join([str(i) for i in sg_ids])
-
-            # Target: Everything
-            # Preserve booleans and integers
-            elif type(value) in [int, bool]:
-                host_info[key] = value
-
-            # Target: Everything
-            # Sanitize string values
-            elif isinstance(value, six.string_types):
-                host_info[key] = value.strip()
-
-            # Target: Everything
-            # Replace None by an empty string
-            elif type(value) == type(None):
-                host_info[key] = ''
-
-            else:
-                # Remove non-processed complex types
-                pass
-
-        return host_info
-
-    def get_host_info(self):
-        ''' Get variables about a specific host '''
-
-        if len(self.index) == 0:
-            # Need to load index from cache
-            self.load_index_from_cache()
-
-        if not self.args.host in self.index:
-            # try updating the cache
-            self.do_api_calls_update_cache()
-            if not self.args.host in self.index:
-                # host might not exist anymore
-                return self.json_format_dict({}, True)
-
-        (region, instance_id) = self.index[self.args.host]
-
-        instance = self.get_instance(region, instance_id)
-        return self.json_format_dict(self.get_host_info_dict_from_instance(instance), True)
-
-    def push(self, my_dict, key, element):
-        ''' Push an element onto an array that may not have been defined in
-        the dict '''
-        group_info = my_dict.setdefault(key, [])
-        if isinstance(group_info, dict):
-            host_list = group_info.setdefault('hosts', [])
-            host_list.append(element)
-        else:
-            group_info.append(element)
-
-    def push_group(self, my_dict, key, element):
-        ''' Push a group as a child of another group. '''
-        parent_group = my_dict.setdefault(key, {})
-        if not isinstance(parent_group, dict):
-            parent_group = my_dict[key] = {'hosts': parent_group}
-        child_groups = parent_group.setdefault('children', [])
-        if element not in child_groups:
-            child_groups.append(element)
-
-    def get_inventory_from_cache(self):
-        ''' Reads the inventory from the cache file and returns it as a JSON
-        object '''
-
-        cache = open(self.cache_path_cache, 'r')
-        json_inventory = cache.read()
-        return json_inventory
-
-
-    def load_index_from_cache(self):
-        ''' Reads the index from the cache file sets self.index '''
-
-        cache = open(self.cache_path_index, 'r')
-        json_index = cache.read()
-        self.index = json.loads(json_index)
-
-
-    def write_to_cache(self, data, filename):
-        ''' Writes data in JSON format to a file '''
-
-        json_data = self.json_format_dict(data, True)
-        cache = open(filename, 'w')
-        cache.write(json_data)
-        cache.close()
-
-    def uncammelize(self, key):
-        temp = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', key)
-        return re.sub('([a-z0-9])([A-Z])', r'\1_\2', temp).lower()
-
-    def to_safe(self, word):
-        ''' Converts 'bad' characters in a string to underscores so they can be used as Ansible groups '''
-        regex = "[^A-Za-z0-9\_"
-        if not self.replace_dash_in_groups:
-            regex += "\-"
-        return re.sub(regex + "]", "_", word)
-
-    def json_format_dict(self, data, pretty=False):
-        ''' Converts a dict to a JSON object and dumps it as a formatted
-        string '''
-
-        if pretty:
-            return json.dumps(data, sort_keys=True, indent=2)
-        else:
-            return json.dumps(data)
-
-
-# Run the script
-Ec2Inventory()
diff --git a/edge-1601-cassandra-replication-factor-lab/inventory-dc1 b/edge-1601-cassandra-replication-factor-lab/inventory-dc1
deleted file mode 100644
index 1d95871..0000000
--- a/edge-1601-cassandra-replication-factor-lab/inventory-dc1
+++ /dev/null
@@ -1,160 +0,0 @@
-[tag_Name_dc1_n1]
-54.172.3.199
-
-[tag_Name_dc1_n2]
-52.206.192.26
-
-[tag_Name_dc1_n3]
-54.227.166.177
-
-[tag_Name_dc1_n4]
-54.89.173.227
-
-[tag_Name_dc1_n5]
-54.88.227.64
-
-[tag_Name_dc1_n6]
-54.165.100.53
-
-[tag_Name_dc1_n7]
-54.172.208.7
-
-[tag_Name_dc1_n8]
-54.172.166.239
-
-[tag_Name_dc1_n9]
-54.209.169.95
-
-[tag_Name_dc1_n10]
-52.90.24.114
-
-[tag_Name_dc1_n11]
-52.91.219.87
-
-[tag_Name_dc1_n12]
-54.144.242.20
-
-[tag_Name_dc1_n13]
-54.197.27.231
-
-[tag_Name_dc1_n14]
-54.225.54.117
-
-[tag_Name_dc1_n15]
-54.146.29.98
-
-[tag_Name_dc1_n16]
-54.227.180.97
-
-[tag_Name_dc1_n17]
-54.174.221.137
-
-[tag_Name_dc1_n18]
-54.227.183.30
-
-[tag_Name_dc1_n19]
-54.235.54.24
-
-[tag_Name_dc1_n20]
-54.86.64.45
-
-[tag_Name_dc1_n21]
-52.23.172.34
-
-[planet:children]
-dc-1
-
-[dc-1:children]
-tag_Name_dc1_n1
-tag_Name_dc1_n2
-tag_Name_dc1_n3
-tag_Name_dc1_n4
-tag_Name_dc1_n5
-tag_Name_dc1_n6
-tag_Name_dc1_n7
-tag_Name_dc1_n8
-tag_Name_dc1_n9
-tag_Name_dc1_n10
-tag_Name_dc1_n11
-tag_Name_dc1_n12
-tag_Name_dc1_n13
-tag_Name_dc1_n14
-tag_Name_dc1_n15
-tag_Name_dc1_n16
-tag_Name_dc1_n17
-tag_Name_dc1_n18
-tag_Name_dc1_n19
-tag_Name_dc1_n20
-tag_Name_dc1_n21
-
-[ds:children]
-dc-1-ds
-
-[dc-1-ds:children]
-tag_Name_dc1_n3
-tag_Name_dc1_n4
-tag_Name_dc1_n5
-tag_Name_dc1_n6
-tag_Name_dc1_n7
-tag_Name_dc1_n8
-tag_Name_dc1_n9
-tag_Name_dc1_n10
-
-[ms:children]
-dc-1-ms
-
-[dc-1-ms:children]
-tag_Name_dc1_n1
-tag_Name_dc1_n2
-
-[ui:children]
-dc-1-ui
-
-[dc-1-ui:children]
-tag_Name_dc1_n1
-tag_Name_dc1_n2
-
-[ldap:children]
-dc-1-ldap
-
-[dc-1-ldap:children]
-tag_Name_dc1_n1
-tag_Name_dc1_n2
-
-[rmp:children]
-dc-1-rmp
-
-[dc-1-rmp:children]
-tag_Name_dc1_n11
-tag_Name_dc1_n12
-tag_Name_dc1_n13
-tag_Name_dc1_n14
-tag_Name_dc1_n15
-tag_Name_dc1_n16
-tag_Name_dc1_n17
-
-[qpid:children]
-dc-1-qpid
-
-[dc-1-qpid:children]
-tag_Name_dc1_n18
-tag_Name_dc1_n19
-
-[pg:children]
-dc-1-pg
-
-[dc-1-pg:children]
-dc-1-pgmaster
-dc-1-pgstandby
-
-[pgmaster:children]
-dc-1-pgmaster
-
-[dc-1-pgmaster:children]
-tag_Name_dc1_n20
-
-[pgstandby:children]
-dc-1-pgstandby
-
-[dc-1-pgstandby:children]
-tag_Name_dc1_n21
diff --git a/edge-1601-cassandra-replication-factor-lab/inventory-dc2 b/edge-1601-cassandra-replication-factor-lab/inventory-dc2
deleted file mode 100644
index b8f96fd..0000000
--- a/edge-1601-cassandra-replication-factor-lab/inventory-dc2
+++ /dev/null
@@ -1,161 +0,0 @@
-
-[tag_Name_dc2_n1]
-54.164.60.87
-
-[tag_Name_dc2_n2]
-54.89.192.72
-
-[tag_Name_dc2_n3]
-107.21.21.110
-
-[tag_Name_dc2_n4]
-52.207.226.72
-
-[tag_Name_dc2_n5]
-54.87.145.51
-
-[tag_Name_dc2_n6]
-54.165.167.56
-
-[tag_Name_dc2_n7]
-54.198.137.84
-
-[tag_Name_dc2_n8]
-54.224.112.82
-
-[tag_Name_dc2_n9]
-54.85.58.122
-
-[tag_Name_dc2_n10]
-107.22.137.210
-
-[tag_Name_dc2_n11]
-54.198.195.14
-
-[tag_Name_dc2_n12]
-52.201.252.231
-
-[tag_Name_dc2_n13]
-54.86.147.123
-
-[tag_Name_dc2_n14]
-54.173.159.240
-
-[tag_Name_dc2_n15]
-54.164.126.156
-
-[tag_Name_dc2_n16]
-54.175.40.154
-
-[tag_Name_dc2_n17]
-54.82.169.123
-
-[tag_Name_dc2_n18]
-52.201.248.63
-
-[tag_Name_dc2_n19]
-54.157.238.96
-
-[tag_Name_dc2_n20]
-54.164.102.91
-
-[tag_Name_dc2_n21]
-54.172.205.234
-
-[planet:children]
-dc-2
-
-[dc-2:children]
-tag_Name_dc2_n1
-tag_Name_dc2_n2
-tag_Name_dc2_n3
-tag_Name_dc2_n4
-tag_Name_dc2_n5
-tag_Name_dc2_n6
-tag_Name_dc2_n7
-tag_Name_dc2_n8
-tag_Name_dc2_n9
-tag_Name_dc2_n10
-tag_Name_dc2_n11
-tag_Name_dc2_n12
-tag_Name_dc2_n13
-tag_Name_dc2_n14
-tag_Name_dc2_n15
-tag_Name_dc2_n16
-tag_Name_dc2_n17
-tag_Name_dc2_n18
-tag_Name_dc2_n19
-tag_Name_dc2_n20
-tag_Name_dc2_n21
-
-[ds:children]
-dc-2-ds
-
-[dc-2-ds:children]
-tag_Name_dc2_n3
-tag_Name_dc2_n4
-tag_Name_dc2_n5
-tag_Name_dc2_n6
-tag_Name_dc2_n7
-tag_Name_dc2_n8
-tag_Name_dc2_n9
-tag_Name_dc2_n10
-
-[ms:children]
-dc-2-ms
-
-[dc-2-ms:children]
-tag_Name_dc2_n1
-tag_Name_dc2_n2
-
-[ui:children]
-dc-2-ui
-
-[dc-2-ui:children]
-tag_Name_dc2_n1
-tag_Name_dc2_n2
-
-[ldap:children]
-dc-2-ldap
-
-[dc-2-ldap:children]
-tag_Name_dc2_n1
-tag_Name_dc2_n2
-
-[rmp:children]
-dc-2-rmp
-
-[dc-2-rmp:children]
-tag_Name_dc2_n11
-tag_Name_dc2_n12
-tag_Name_dc2_n13
-tag_Name_dc2_n14
-tag_Name_dc2_n15
-tag_Name_dc2_n16
-tag_Name_dc2_n17
-
-[qpid:children]
-dc-2-qpid
-
-[dc-2-qpid:children]
-tag_Name_dc2_n18
-tag_Name_dc2_n19
-
-[pg:children]
-dc-2-pg
-
-[dc-2-pg:children]
-dc-2-pgmaster
-dc-2-pgstandby
-
-[pgmaster:children]
-dc-2-pgmaster
-
-[dc-2-pgmaster:children]
-tag_Name_dc2_n20
-
-[pgstandby:children]
-dc-2-pgstandby
-
-[dc-2-pgstandby:children]
-tag_Name_dc2_n21
diff --git a/edge-1601-dc1-dc2/ec2.ini b/edge-1601-dc1-dc2/ec2.ini
deleted file mode 100644
index 36b3921..0000000
--- a/edge-1601-dc1-dc2/ec2.ini
+++ /dev/null
@@ -1,200 +0,0 @@
-# Ansible EC2 external inventory script settings
-#
-
-[ec2]
-
-# to talk to a private eucalyptus instance uncomment these lines
-# and edit edit eucalyptus_host to be the host name of your cloud controller
-#eucalyptus = True
-#eucalyptus_host = clc.cloud.domain.org
-
-# AWS regions to make calls to. Set this to 'all' to make request to all regions
-# in AWS and merge the results together. Alternatively, set this to a comma
-# separated list of regions. E.g. 'us-east-1,us-west-1,us-west-2'
-regions = all
-regions_exclude = us-gov-west-1,cn-north-1
-
-# When generating inventory, Ansible needs to know how to address a server.
-# Each EC2 instance has a lot of variables associated with it. Here is the list:
-#   http://docs.pythonboto.org/en/latest/ref/ec2.html#module-boto.ec2.instance
-# Below are 2 variables that are used as the address of a server:
-#   - destination_variable
-#   - vpc_destination_variable
-
-# This is the normal destination variable to use. If you are running Ansible
-# from outside EC2, then 'public_dns_name' makes the most sense. If you are
-# running Ansible from within EC2, then perhaps you want to use the internal
-# address, and should set this to 'private_dns_name'. The key of an EC2 tag
-# may optionally be used; however the boto instance variables hold precedence
-# in the event of a collision.
-destination_variable = public_dns_name
-
-# This allows you to override the inventory_name with an ec2 variable, instead
-# of using the destination_variable above. Addressing (aka ansible_ssh_host)
-# will still use destination_variable. Tags should be written as 'tag_TAGNAME'.
-#hostname_variable = tag_Name
-
-# For server inside a VPC, using DNS names may not make sense. When an instance
-# has 'subnet_id' set, this variable is used. If the subnet is public, setting
-# this to 'ip_address' will return the public IP address. For instances in a
-# private subnet, this should be set to 'private_ip_address', and Ansible must
-# be run from within EC2. The key of an EC2 tag may optionally be used; however
-# the boto instance variables hold precedence in the event of a collision.
-# WARNING: - instances that are in the private vpc, _without_ public ip address
-# will not be listed in the inventory until You set:
-# vpc_destination_variable = private_ip_address
-vpc_destination_variable = ip_address
-
-# The following two settings allow flexible ansible host naming based on a
-# python format string and a comma-separated list of ec2 tags.  Note that:
-#
-# 1) If the tags referenced are not present for some instances, empty strings
-#    will be substituted in the format string.
-# 2) This overrides both destination_variable and vpc_destination_variable.
-#
-#destination_format = {0}.{1}.example.com
-#destination_format_tags = Name,environment
-
-# To tag instances on EC2 with the resource records that point to them from
-# Route53, uncomment and set 'route53' to True.
-route53 = False
-
-# To exclude RDS instances from the inventory, uncomment and set to False.
-rds = False
-
-# To exclude ElastiCache instances from the inventory, uncomment and set to False.
-elasticache = False
-
-# Additionally, you can specify the list of zones to exclude looking up in
-# 'route53_excluded_zones' as a comma-separated list.
-# route53_excluded_zones = samplezone1.com, samplezone2.com
-
-# By default, only EC2 instances in the 'running' state are returned. Set
-# 'all_instances' to True to return all instances regardless of state.
-all_instances = True
-
-# By default, only EC2 instances in the 'running' state are returned. Specify
-# EC2 instance states to return as a comma-separated list. This
-# option is overriden when 'all_instances' is True.
-# instance_states = pending, running, shutting-down, terminated, stopping, stopped
-
-# By default, only RDS instances in the 'available' state are returned.  Set
-# 'all_rds_instances' to True return all RDS instances regardless of state.
-all_rds_instances = False
-
-# By default, only ElastiCache clusters and nodes in the 'available' state
-# are returned. Set 'all_elasticache_clusters' and/or 'all_elastic_nodes'
-# to True return all ElastiCache clusters and nodes, regardless of state.
-#
-# Note that all_elasticache_nodes only applies to listed clusters. That means
-# if you set all_elastic_clusters to false, no node will be return from
-# unavailable clusters, regardless of the state and to what you set for
-# all_elasticache_nodes.
-all_elasticache_replication_groups = False
-all_elasticache_clusters = False
-all_elasticache_nodes = False
-
-# API calls to EC2 are slow. For this reason, we cache the results of an API
-# call. Set this to the path you want cache files to be written to. Two files
-# will be written to this directory:
-#   - ansible-ec2.cache
-#   - ansible-ec2.index
-cache_path = ~/.ansible/tmp
-
-# The number of seconds a cache file is considered valid. After this many
-# seconds, a new API call will be made, and the cache file will be updated.
-# To disable the cache, set this value to 0
-cache_max_age = 300
-
-# Organize groups into a nested/hierarchy instead of a flat namespace.
-nested_groups = False
-
-# Replace - tags when creating groups to avoid issues with ansible
-replace_dash_in_groups = True
-
-# If set to true, any tag of the form "a,b,c" is expanded into a list
-# and the results are used to create additional tag_* inventory groups.
-expand_csv_tags = False
-
-# The EC2 inventory output can become very large. To manage its size,
-# configure which groups should be created.
-group_by_instance_id = True
-group_by_region = True
-group_by_availability_zone = True
-group_by_ami_id = True
-group_by_instance_type = True
-group_by_key_pair = True
-group_by_vpc_id = True
-group_by_security_group = True
-group_by_tag_keys = True
-group_by_tag_none = True
-group_by_route53_names = True
-group_by_rds_engine = False
-group_by_rds_parameter_group = False
-group_by_elasticache_engine = True
-group_by_elasticache_cluster = True
-group_by_elasticache_parameter_group = True
-group_by_elasticache_replication_group = True
-
-# If you only want to include hosts that match a certain regular expression
-# pattern_include = staging-*
-
-# If you want to exclude any hosts that match a certain regular expression
-# pattern_exclude = staging-*
-# Ansible EC2 external inventory script settings
-#
-
-##[ec2]
-##
-### to talk to a private eucalyptus instance uncomment these lines
-### and edit edit eucalyptus_host to be the host name of your cloud controller
-###eucalyptus = True
-###eucalyptus_host = clc.cloud.domain.org
-##
-### AWS regions to make calls to. Set this to 'all' to make request to all regions
-##
-### in AWS and merge the results together. Alternatively, set this to a comma
-### separated list of regions. E.g. 'us-east-1,us-west-1,us-west-2'
-##regions = all
-##regions_exclude = us-gov-west-1,cn-north-1
-##
-### When generating inventory, Ansible needs to know how to address a server.
-### Each EC2 instance has a lot of variables associated with it. Here is the list:
-###   http://docs.pythonboto.org/en/latest/ref/ec2.html#module-boto.ec2.instance
-### Below are 2 variables that are used as the address of a server:
-###   - destination_variable
-###   - vpc_destination_variable
-##
-### This is the normal destination variable to use. If you are running Ansible
-### from outside EC2, then 'public_dns_name' makes the most sense. If you are
-### running Ansible from within EC2, then perhaps you want to use the internal
-### address, and should set this to 'private_dns_name'. The key of an EC2 tag
-##...skipping...
-### pattern_include = staging-*
-##
-### If you want to exclude any hosts that match a certain regular expression
-### pattern_exclude = staging-*
-
-# Instance filters can be used to control which instances are retrieved for
-# inventory. For the full list of possible filters, please read the EC2 API
-# docs: http://docs.aws.amazon.com/AWSEC2/latest/APIReference/ApiReference-query-DescribeInstances.html#query-DescribeInstances-filters
-# Filters are key/value pairs separated by '=', to list multiple filters use
-# a list separated by commas. See examples below.
-
-# Retrieve only instances with (key=value) env=staging tag
-# instance_filters = tag:env=staging
-
-# Retrieve only instances with role=webservers OR role=dbservers tag
-# instance_filters = tag:role=webservers,tag:role=dbservers
-
-# Retrieve only t1.micro instances OR instances with tag env=staging
-# instance_filters = instance-type=t1.micro,tag:env=staging
-
-# You can use wildcards in filter values also. Below will list instances which
-# tag Name value matches webservers1*
-# (ex. webservers15, webservers1a, webservers123 etc)
-# instance_filters = tag:Name=webservers1*
-
-# A boto configuration profile may be used to separate out credentials
-# see http://boto.readthedocs.org/en/latest/boto_config_tut.html
-# boto_profile = some-boto-profile-name
diff --git a/edge-1601-dc1-dc2/ec2.py b/edge-1601-dc1-dc2/ec2.py
deleted file mode 100755
index f30958a..0000000
--- a/edge-1601-dc1-dc2/ec2.py
+++ /dev/null
@@ -1,1385 +0,0 @@
-#!/usr/bin/env python
-
-'''
-EC2 external inventory script
-=================================
-
-Generates inventory that Ansible can understand by making API request to
-AWS EC2 using the Boto library.
-
-NOTE: This script assumes Ansible is being executed where the environment
-variables needed for Boto have already been set:
-    export AWS_ACCESS_KEY_ID='AK123'
-    export AWS_SECRET_ACCESS_KEY='abc123'
-
-This script also assumes there is an ec2.ini file alongside it.  To specify a
-different path to ec2.ini, define the EC2_INI_PATH environment variable:
-
-    export EC2_INI_PATH=/path/to/my_ec2.ini
-
-If you're using eucalyptus you need to set the above variables and
-you need to define:
-
-    export EC2_URL=http://hostname_of_your_cc:port/services/Eucalyptus
-
-If you're using boto profiles (requires boto>=2.24.0) you can choose a profile
-using the --boto-profile command line argument (e.g. ec2.py --boto-profile prod) or using
-the AWS_PROFILE variable:
-
-    AWS_PROFILE=prod ansible-playbook -i ec2.py myplaybook.yml
-
-For more details, see: http://docs.pythonboto.org/en/latest/boto_config_tut.html
-
-When run against a specific host, this script returns the following variables:
- - ec2_ami_launch_index
- - ec2_architecture
- - ec2_association
- - ec2_attachTime
- - ec2_attachment
- - ec2_attachmentId
- - ec2_client_token
- - ec2_deleteOnTermination
- - ec2_description
- - ec2_deviceIndex
- - ec2_dns_name
- - ec2_eventsSet
- - ec2_group_name
- - ec2_hypervisor
- - ec2_id
- - ec2_image_id
- - ec2_instanceState
- - ec2_instance_type
- - ec2_ipOwnerId
- - ec2_ip_address
- - ec2_item
- - ec2_kernel
- - ec2_key_name
- - ec2_launch_time
- - ec2_monitored
- - ec2_monitoring
- - ec2_networkInterfaceId
- - ec2_ownerId
- - ec2_persistent
- - ec2_placement
- - ec2_platform
- - ec2_previous_state
- - ec2_private_dns_name
- - ec2_private_ip_address
- - ec2_publicIp
- - ec2_public_dns_name
- - ec2_ramdisk
- - ec2_reason
- - ec2_region
- - ec2_requester_id
- - ec2_root_device_name
- - ec2_root_device_type
- - ec2_security_group_ids
- - ec2_security_group_names
- - ec2_shutdown_state
- - ec2_sourceDestCheck
- - ec2_spot_instance_request_id
- - ec2_state
- - ec2_state_code
- - ec2_state_reason
- - ec2_status
- - ec2_subnet_id
- - ec2_tenancy
- - ec2_virtualization_type
- - ec2_vpc_id
-
-These variables are pulled out of a boto.ec2.instance object. There is a lack of
-consistency with variable spellings (camelCase and underscores) since this
-just loops through all variables the object exposes. It is preferred to use the
-ones with underscores when multiple exist.
-
-In addition, if an instance has AWS Tags associated with it, each tag is a new
-variable named:
- - ec2_tag_[Key] = [Value]
-
-Security groups are comma-separated in 'ec2_security_group_ids' and
-'ec2_security_group_names'.
-'''
-
-# (c) 2012, Peter Sankauskas
-#
-# This file is part of Ansible,
-#
-# Ansible is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# Ansible is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with Ansible.  If not, see <http://www.gnu.org/licenses/>.
-
-######################################################################
-
-import sys
-import os
-import argparse
-import re
-from time import time
-import boto
-from boto import ec2
-from boto import rds
-from boto import elasticache
-from boto import route53
-import six
-
-from six.moves import configparser
-from collections import defaultdict
-
-try:
-    import json
-except ImportError:
-    import simplejson as json
-
-
-class Ec2Inventory(object):
-
-    def _empty_inventory(self):
-        return {"_meta" : {"hostvars" : {}}}
-
-    def __init__(self):
-        ''' Main execution path '''
-
-        # Inventory grouped by instance IDs, tags, security groups, regions,
-        # and availability zones
-        self.inventory = self._empty_inventory()
-
-        # Index of hostname (address) to instance ID
-        self.index = {}
-
-        # Boto profile to use (if any)
-        self.boto_profile = None
-
-        # Read settings and parse CLI arguments
-        self.parse_cli_args()
-        self.read_settings()
-
-        # Make sure that profile_name is not passed at all if not set
-        # as pre 2.24 boto will fall over otherwise
-        if self.boto_profile:
-            if not hasattr(boto.ec2.EC2Connection, 'profile_name'):
-                self.fail_with_error("boto version must be >= 2.24 to use profile")
-
-        # Cache
-        if self.args.refresh_cache:
-            self.do_api_calls_update_cache()
-        elif not self.is_cache_valid():
-            self.do_api_calls_update_cache()
-
-        # Data to print
-        if self.args.host:
-            data_to_print = self.get_host_info()
-
-        elif self.args.list:
-            # Display list of instances for inventory
-            if self.inventory == self._empty_inventory():
-                data_to_print = self.get_inventory_from_cache()
-            else:
-                data_to_print = self.json_format_dict(self.inventory, True)
-
-        print(data_to_print)
-
-
-    def is_cache_valid(self):
-        ''' Determines if the cache files have expired, or if it is still valid '''
-
-        if os.path.isfile(self.cache_path_cache):
-            mod_time = os.path.getmtime(self.cache_path_cache)
-            current_time = time()
-            if (mod_time + self.cache_max_age) > current_time:
-                if os.path.isfile(self.cache_path_index):
-                    return True
-
-        return False
-
-
-    def read_settings(self):
-        ''' Reads the settings from the ec2.ini file '''
-        if six.PY3:
-            config = configparser.ConfigParser()
-        else:
-            config = configparser.SafeConfigParser()
-        ec2_default_ini_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'ec2.ini')
-        ec2_ini_path = os.path.expanduser(os.path.expandvars(os.environ.get('EC2_INI_PATH', ec2_default_ini_path)))
-        config.read(ec2_ini_path)
-
-        # is eucalyptus?
-        self.eucalyptus_host = None
-        self.eucalyptus = False
-        if config.has_option('ec2', 'eucalyptus'):
-            self.eucalyptus = config.getboolean('ec2', 'eucalyptus')
-        if self.eucalyptus and config.has_option('ec2', 'eucalyptus_host'):
-            self.eucalyptus_host = config.get('ec2', 'eucalyptus_host')
-
-        # Regions
-        self.regions = []
-        configRegions = config.get('ec2', 'regions')
-        configRegions_exclude = config.get('ec2', 'regions_exclude')
-        if (configRegions == 'all'):
-            if self.eucalyptus_host:
-                self.regions.append(boto.connect_euca(host=self.eucalyptus_host).region.name)
-            else:
-                for regionInfo in ec2.regions():
-                    if regionInfo.name not in configRegions_exclude:
-                        self.regions.append(regionInfo.name)
-        else:
-            self.regions = configRegions.split(",")
-
-        # Destination addresses
-        self.destination_variable = config.get('ec2', 'destination_variable')
-        self.vpc_destination_variable = config.get('ec2', 'vpc_destination_variable')
-
-        if config.has_option('ec2', 'hostname_variable'):
-            self.hostname_variable = config.get('ec2', 'hostname_variable')
-        else:
-            self.hostname_variable = None
-
-        if config.has_option('ec2', 'destination_format') and \
-                config.has_option('ec2', 'destination_format_tags'):
-            self.destination_format = config.get('ec2', 'destination_format')
-            self.destination_format_tags = config.get('ec2', 'destination_format_tags').split(',')
-        else:
-            self.destination_format = None
-            self.destination_format_tags = None
-
-        # Route53
-        self.route53_enabled = config.getboolean('ec2', 'route53')
-        self.route53_excluded_zones = []
-        if config.has_option('ec2', 'route53_excluded_zones'):
-            self.route53_excluded_zones.extend(
-                    config.get('ec2', 'route53_excluded_zones', '').split(','))
-
-        # Include RDS instances?
-        self.rds_enabled = True
-        if config.has_option('ec2', 'rds'):
-            self.rds_enabled = config.getboolean('ec2', 'rds')
-
-        # Include ElastiCache instances?
-        self.elasticache_enabled = True
-        if config.has_option('ec2', 'elasticache'):
-            self.elasticache_enabled = config.getboolean('ec2', 'elasticache')
-
-        # Return all EC2 instances?
-        if config.has_option('ec2', 'all_instances'):
-            self.all_instances = config.getboolean('ec2', 'all_instances')
-        else:
-            self.all_instances = False
-
-        # Instance states to be gathered in inventory. Default is 'running'.
-        # Setting 'all_instances' to 'yes' overrides this option.
-        ec2_valid_instance_states = [
-            'pending',
-            'running',
-            'shutting-down',
-            'terminated',
-            'stopping',
-            'stopped'
-        ]
-        self.ec2_instance_states = []
-        if self.all_instances:
-            self.ec2_instance_states = ec2_valid_instance_states
-        elif config.has_option('ec2', 'instance_states'):
-            for instance_state in config.get('ec2', 'instance_states').split(','):
-                instance_state = instance_state.strip()
-                if instance_state not in ec2_valid_instance_states:
-                    continue
-                self.ec2_instance_states.append(instance_state)
-        else:
-            self.ec2_instance_states = ['running']
-
-        # Return all RDS instances? (if RDS is enabled)
-        if config.has_option('ec2', 'all_rds_instances') and self.rds_enabled:
-            self.all_rds_instances = config.getboolean('ec2', 'all_rds_instances')
-        else:
-            self.all_rds_instances = False
-
-        # Return all ElastiCache replication groups? (if ElastiCache is enabled)
-        if config.has_option('ec2', 'all_elasticache_replication_groups') and self.elasticache_enabled:
-            self.all_elasticache_replication_groups = config.getboolean('ec2', 'all_elasticache_replication_groups')
-        else:
-            self.all_elasticache_replication_groups = False
-
-        # Return all ElastiCache clusters? (if ElastiCache is enabled)
-        if config.has_option('ec2', 'all_elasticache_clusters') and self.elasticache_enabled:
-            self.all_elasticache_clusters = config.getboolean('ec2', 'all_elasticache_clusters')
-        else:
-            self.all_elasticache_clusters = False
-
-        # Return all ElastiCache nodes? (if ElastiCache is enabled)
-        if config.has_option('ec2', 'all_elasticache_nodes') and self.elasticache_enabled:
-            self.all_elasticache_nodes = config.getboolean('ec2', 'all_elasticache_nodes')
-        else:
-            self.all_elasticache_nodes = False
-
-        # boto configuration profile (prefer CLI argument)
-        self.boto_profile = self.args.boto_profile
-        if config.has_option('ec2', 'boto_profile') and not self.boto_profile:
-            self.boto_profile = config.get('ec2', 'boto_profile')
-
-        # Cache related
-        cache_dir = os.path.expanduser(config.get('ec2', 'cache_path'))
-        if self.boto_profile:
-            cache_dir = os.path.join(cache_dir, 'profile_' + self.boto_profile)
-        if not os.path.exists(cache_dir):
-            os.makedirs(cache_dir)
-
-        cache_name = 'ansible-ec2'
-        aws_profile = lambda: (self.boto_profile or
-                               os.environ.get('AWS_PROFILE') or
-                               os.environ.get('AWS_ACCESS_KEY_ID'))
-        if aws_profile():
-            cache_name = '%s-%s' % (cache_name, aws_profile())
-        self.cache_path_cache = cache_dir + "/%s.cache" % cache_name
-        self.cache_path_index = cache_dir + "/%s.index" % cache_name
-        self.cache_max_age = config.getint('ec2', 'cache_max_age')
-
-        if config.has_option('ec2', 'expand_csv_tags'):
-            self.expand_csv_tags = config.getboolean('ec2', 'expand_csv_tags')
-        else:
-            self.expand_csv_tags = False
-
-        # Configure nested groups instead of flat namespace.
-        if config.has_option('ec2', 'nested_groups'):
-            self.nested_groups = config.getboolean('ec2', 'nested_groups')
-        else:
-            self.nested_groups = False
-
-        # Replace dash or not in group names
-        if config.has_option('ec2', 'replace_dash_in_groups'):
-            self.replace_dash_in_groups = config.getboolean('ec2', 'replace_dash_in_groups')
-        else:
-            self.replace_dash_in_groups = True
-
-        # Configure which groups should be created.
-        group_by_options = [
-            'group_by_instance_id',
-            'group_by_region',
-            'group_by_availability_zone',
-            'group_by_ami_id',
-            'group_by_instance_type',
-            'group_by_key_pair',
-            'group_by_vpc_id',
-            'group_by_security_group',
-            'group_by_tag_keys',
-            'group_by_tag_none',
-            'group_by_route53_names',
-            'group_by_rds_engine',
-            'group_by_rds_parameter_group',
-            'group_by_elasticache_engine',
-            'group_by_elasticache_cluster',
-            'group_by_elasticache_parameter_group',
-            'group_by_elasticache_replication_group',
-        ]
-        for option in group_by_options:
-            if config.has_option('ec2', option):
-                setattr(self, option, config.getboolean('ec2', option))
-            else:
-                setattr(self, option, True)
-
-        # Do we need to just include hosts that match a pattern?
-        try:
-            pattern_include = config.get('ec2', 'pattern_include')
-            if pattern_include and len(pattern_include) > 0:
-                self.pattern_include = re.compile(pattern_include)
-            else:
-                self.pattern_include = None
-        except configparser.NoOptionError:
-            self.pattern_include = None
-
-        # Do we need to exclude hosts that match a pattern?
-        try:
-            pattern_exclude = config.get('ec2', 'pattern_exclude');
-            if pattern_exclude and len(pattern_exclude) > 0:
-                self.pattern_exclude = re.compile(pattern_exclude)
-            else:
-                self.pattern_exclude = None
-        except configparser.NoOptionError:
-            self.pattern_exclude = None
-
-        # Instance filters (see boto and EC2 API docs). Ignore invalid filters.
-        self.ec2_instance_filters = defaultdict(list)
-        if config.has_option('ec2', 'instance_filters'):
-
-            filters = [f for f in config.get('ec2', 'instance_filters').split(',') if f]
-
-            for instance_filter in filters:
-                instance_filter = instance_filter.strip()
-                if not instance_filter or '=' not in instance_filter:
-                    continue
-                filter_key, filter_value = [x.strip() for x in instance_filter.split('=', 1)]
-                if not filter_key:
-                    continue
-                self.ec2_instance_filters[filter_key].append(filter_value)
-
-    def parse_cli_args(self):
-        ''' Command line argument processing '''
-
-        parser = argparse.ArgumentParser(description='Produce an Ansible Inventory file based on EC2')
-        parser.add_argument('--list', action='store_true', default=True,
-                            help='List instances (default: True)')
-        parser.add_argument('--host', action='store',
-                            help='Get all the variables about a specific instance')
-        parser.add_argument('--refresh-cache', action='store_true', default=False,
-                            help='Force refresh of cache by making API requests to EC2 (default: False - use cache files)')
-        parser.add_argument('--profile', '--boto-profile', action='store', dest='boto_profile',
-                            help='Use boto profile for connections to EC2')
-        self.args = parser.parse_args()
-
-
-    def do_api_calls_update_cache(self):
-        ''' Do API calls to each region, and save data in cache files '''
-
-        if self.route53_enabled:
-            self.get_route53_records()
-
-        for region in self.regions:
-            self.get_instances_by_region(region)
-            if self.rds_enabled:
-                self.get_rds_instances_by_region(region)
-            if self.elasticache_enabled:
-                self.get_elasticache_clusters_by_region(region)
-                self.get_elasticache_replication_groups_by_region(region)
-
-        self.write_to_cache(self.inventory, self.cache_path_cache)
-        self.write_to_cache(self.index, self.cache_path_index)
-
-    def connect(self, region):
-        ''' create connection to api server'''
-        if self.eucalyptus:
-            conn = boto.connect_euca(host=self.eucalyptus_host)
-            conn.APIVersion = '2010-08-31'
-        else:
-            conn = self.connect_to_aws(ec2, region)
-        return conn
-
-    def boto_fix_security_token_in_profile(self, connect_args):
-        ''' monkey patch for boto issue boto/boto#2100 '''
-        profile = 'profile ' + self.boto_profile
-        if boto.config.has_option(profile, 'aws_security_token'):
-            connect_args['security_token'] = boto.config.get(profile, 'aws_security_token')
-        return connect_args
-
-    def connect_to_aws(self, module, region):
-        connect_args = {}
-
-        # only pass the profile name if it's set (as it is not supported by older boto versions)
-        if self.boto_profile:
-            connect_args['profile_name'] = self.boto_profile
-            self.boto_fix_security_token_in_profile(connect_args)
-
-        conn = module.connect_to_region(region, **connect_args)
-        # connect_to_region will fail "silently" by returning None if the region name is wrong or not supported
-        if conn is None:
-            self.fail_with_error("region name: %s likely not supported, or AWS is down.  connection to region failed." % region)
-        return conn
-
-    def get_instances_by_region(self, region):
-        ''' Makes an AWS EC2 API call to the list of instances in a particular
-        region '''
-
-        try:
-            conn = self.connect(region)
-            reservations = []
-            if self.ec2_instance_filters:
-                for filter_key, filter_values in self.ec2_instance_filters.items():
-                    reservations.extend(conn.get_all_instances(filters = { filter_key : filter_values }))
-            else:
-                reservations = conn.get_all_instances()
-
-            for reservation in reservations:
-                for instance in reservation.instances:
-                    self.add_instance(instance, region)
-
-        except boto.exception.BotoServerError as e:
-            if e.error_code == 'AuthFailure':
-                error = self.get_auth_error_message()
-            else:
-                backend = 'Eucalyptus' if self.eucalyptus else 'AWS'
-                error = "Error connecting to %s backend.\n%s" % (backend, e.message)
-            self.fail_with_error(error, 'getting EC2 instances')
-
-    def get_rds_instances_by_region(self, region):
-        ''' Makes an AWS API call to the list of RDS instances in a particular
-        region '''
-
-        try:
-            conn = self.connect_to_aws(rds, region)
-            if conn:
-                marker = None
-                while True:
-                    instances = conn.get_all_dbinstances(marker=marker)
-                    marker = instances.marker
-                    for instance in instances:
-                        self.add_rds_instance(instance, region)
-                    if not marker:
-                        break
-        except boto.exception.BotoServerError as e:
-            error = e.reason
-
-            if e.error_code == 'AuthFailure':
-                error = self.get_auth_error_message()
-            if not e.reason == "Forbidden":
-                error = "Looks like AWS RDS is down:\n%s" % e.message
-            self.fail_with_error(error, 'getting RDS instances')
-
-    def get_elasticache_clusters_by_region(self, region):
-        ''' Makes an AWS API call to the list of ElastiCache clusters (with
-        nodes' info) in a particular region.'''
-
-        # ElastiCache boto module doesn't provide a get_all_intances method,
-        # that's why we need to call describe directly (it would be called by
-        # the shorthand method anyway...)
-        try:
-            conn = self.connect_to_aws(elasticache, region)
-            if conn:
-                # show_cache_node_info = True
-                # because we also want nodes' information
-                response = conn.describe_cache_clusters(None, None, None, True)
-
-        except boto.exception.BotoServerError as e:
-            error = e.reason
-
-            if e.error_code == 'AuthFailure':
-                error = self.get_auth_error_message()
-            if not e.reason == "Forbidden":
-                error = "Looks like AWS ElastiCache is down:\n%s" % e.message
-            self.fail_with_error(error, 'getting ElastiCache clusters')
-
-        try:
-            # Boto also doesn't provide wrapper classes to CacheClusters or
-            # CacheNodes. Because of that wo can't make use of the get_list
-            # method in the AWSQueryConnection. Let's do the work manually
-            clusters = response['DescribeCacheClustersResponse']['DescribeCacheClustersResult']['CacheClusters']
-
-        except KeyError as e:
-            error = "ElastiCache query to AWS failed (unexpected format)."
-            self.fail_with_error(error, 'getting ElastiCache clusters')
-
-        for cluster in clusters:
-            self.add_elasticache_cluster(cluster, region)
-
-    def get_elasticache_replication_groups_by_region(self, region):
-        ''' Makes an AWS API call to the list of ElastiCache replication groups
-        in a particular region.'''
-
-        # ElastiCache boto module doesn't provide a get_all_intances method,
-        # that's why we need to call describe directly (it would be called by
-        # the shorthand method anyway...)
-        try:
-            conn = self.connect_to_aws(elasticache, region)
-            if conn:
-                response = conn.describe_replication_groups()
-
-        except boto.exception.BotoServerError as e:
-            error = e.reason
-
-            if e.error_code == 'AuthFailure':
-                error = self.get_auth_error_message()
-            if not e.reason == "Forbidden":
-                error = "Looks like AWS ElastiCache [Replication Groups] is down:\n%s" % e.message
-            self.fail_with_error(error, 'getting ElastiCache clusters')
-
-        try:
-            # Boto also doesn't provide wrapper classes to ReplicationGroups
-            # Because of that wo can't make use of the get_list method in the
-            # AWSQueryConnection. Let's do the work manually
-            replication_groups = response['DescribeReplicationGroupsResponse']['DescribeReplicationGroupsResult']['ReplicationGroups']
-
-        except KeyError as e:
-            error = "ElastiCache [Replication Groups] query to AWS failed (unexpected format)."
-            self.fail_with_error(error, 'getting ElastiCache clusters')
-
-        for replication_group in replication_groups:
-            self.add_elasticache_replication_group(replication_group, region)
-
-    def get_auth_error_message(self):
-        ''' create an informative error message if there is an issue authenticating'''
-        errors = ["Authentication error retrieving ec2 inventory."]
-        if None in [os.environ.get('AWS_ACCESS_KEY_ID'), os.environ.get('AWS_SECRET_ACCESS_KEY')]:
-            errors.append(' - No AWS_ACCESS_KEY_ID or AWS_SECRET_ACCESS_KEY environment vars found')
-        else:
-            errors.append(' - AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY environment vars found but may not be correct')
-
-        boto_paths = ['/etc/boto.cfg', '~/.boto', '~/.aws/credentials']
-        boto_config_found = list(p for p in boto_paths if os.path.isfile(os.path.expanduser(p)))
-        if len(boto_config_found) > 0:
-            errors.append(" - Boto configs found at '%s', but the credentials contained may not be correct" % ', '.join(boto_config_found))
-        else:
-            errors.append(" - No Boto config found at any expected location '%s'" % ', '.join(boto_paths))
-
-        return '\n'.join(errors)
-
-    def fail_with_error(self, err_msg, err_operation=None):
-        '''log an error to std err for ansible-playbook to consume and exit'''
-        if err_operation:
-            err_msg = 'ERROR: "{err_msg}", while: {err_operation}'.format(
-                    err_msg=err_msg, err_operation=err_operation)
-        sys.stderr.write(err_msg)
-        sys.exit(1)
-
-    def get_instance(self, region, instance_id):
-        conn = self.connect(region)
-
-        reservations = conn.get_all_instances([instance_id])
-        for reservation in reservations:
-            for instance in reservation.instances:
-                return instance
-
-    def add_instance(self, instance, region):
-        ''' Adds an instance to the inventory and index, as long as it is
-        addressable '''
-
-        # Only return instances with desired instance states
-        if instance.state not in self.ec2_instance_states:
-            return
-
-        # Select the best destination address
-        if self.destination_format and self.destination_format_tags:
-            dest = self.destination_format.format(*[ getattr(instance, 'tags').get(tag, '') for tag in self.destination_format_tags ])
-        elif instance.subnet_id:
-            dest = getattr(instance, self.vpc_destination_variable, None)
-            if dest is None:
-                dest = getattr(instance, 'tags').get(self.vpc_destination_variable, None)
-        else:
-            dest = getattr(instance, self.destination_variable, None)
-            if dest is None:
-                dest = getattr(instance, 'tags').get(self.destination_variable, None)
-
-        if not dest:
-            # Skip instances we cannot address (e.g. private VPC subnet)
-            return
-
-        # Set the inventory name
-        hostname = None
-        if self.hostname_variable:
-            if self.hostname_variable.startswith('tag_'):
-                hostname = instance.tags.get(self.hostname_variable[4:], None)
-            else:
-                hostname = getattr(instance, self.hostname_variable)
-
-        # If we can't get a nice hostname, use the destination address
-        if not hostname:
-            hostname = dest
-        else:
-            hostname = self.to_safe(hostname).lower()
-
-        # if we only want to include hosts that match a pattern, skip those that don't
-        if self.pattern_include and not self.pattern_include.match(hostname):
-            return
-
-        # if we need to exclude hosts that match a pattern, skip those
-        if self.pattern_exclude and self.pattern_exclude.match(hostname):
-            return
-
-        # Add to index
-        self.index[hostname] = [region, instance.id]
-
-        # Inventory: Group by instance ID (always a group of 1)
-        if self.group_by_instance_id:
-            self.inventory[instance.id] = [hostname]
-            if self.nested_groups:
-                self.push_group(self.inventory, 'instances', instance.id)
-
-        # Inventory: Group by region
-        if self.group_by_region:
-            self.push(self.inventory, region, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'regions', region)
-
-        # Inventory: Group by availability zone
-        if self.group_by_availability_zone:
-            self.push(self.inventory, instance.placement, hostname)
-            if self.nested_groups:
-                if self.group_by_region:
-                    self.push_group(self.inventory, region, instance.placement)
-                self.push_group(self.inventory, 'zones', instance.placement)
-
-        # Inventory: Group by Amazon Machine Image (AMI) ID
-        if self.group_by_ami_id:
-            ami_id = self.to_safe(instance.image_id)
-            self.push(self.inventory, ami_id, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'images', ami_id)
-
-        # Inventory: Group by instance type
-        if self.group_by_instance_type:
-            type_name = self.to_safe('type_' + instance.instance_type)
-            self.push(self.inventory, type_name, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'types', type_name)
-
-        # Inventory: Group by key pair
-        if self.group_by_key_pair and instance.key_name:
-            key_name = self.to_safe('key_' + instance.key_name)
-            self.push(self.inventory, key_name, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'keys', key_name)
-
-        # Inventory: Group by VPC
-        if self.group_by_vpc_id and instance.vpc_id:
-            vpc_id_name = self.to_safe('vpc_id_' + instance.vpc_id)
-            self.push(self.inventory, vpc_id_name, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'vpcs', vpc_id_name)
-
-        # Inventory: Group by security group
-        if self.group_by_security_group:
-            try:
-                for group in instance.groups:
-                    key = self.to_safe("security_group_" + group.name)
-                    self.push(self.inventory, key, hostname)
-                    if self.nested_groups:
-                        self.push_group(self.inventory, 'security_groups', key)
-            except AttributeError:
-                self.fail_with_error('\n'.join(['Package boto seems a bit older.',
-                                                'Please upgrade boto >= 2.3.0.']))
-
-        # Inventory: Group by tag keys
-        if self.group_by_tag_keys:
-            for k, v in instance.tags.items():
-                if self.expand_csv_tags and v and ',' in v:
-                    values = map(lambda x: x.strip(), v.split(','))
-                else:
-                    values = [v]
-
-                for v in values:
-                    if v:
-                        key = self.to_safe("tag_" + k + "=" + v)
-                    else:
-                        key = self.to_safe("tag_" + k)
-                    self.push(self.inventory, key, hostname)
-                    if self.nested_groups:
-                        self.push_group(self.inventory, 'tags', self.to_safe("tag_" + k))
-                        if v:
-                            self.push_group(self.inventory, self.to_safe("tag_" + k), key)
-
-        # Inventory: Group by Route53 domain names if enabled
-        if self.route53_enabled and self.group_by_route53_names:
-            route53_names = self.get_instance_route53_names(instance)
-            for name in route53_names:
-                self.push(self.inventory, name, hostname)
-                if self.nested_groups:
-                    self.push_group(self.inventory, 'route53', name)
-
-        # Global Tag: instances without tags
-        if self.group_by_tag_none and len(instance.tags) == 0:
-            self.push(self.inventory, 'tag_none', hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'tags', 'tag_none')
-
-        # Global Tag: tag all EC2 instances
-        self.push(self.inventory, 'ec2', hostname)
-
-        self.inventory["_meta"]["hostvars"][hostname] = self.get_host_info_dict_from_instance(instance)
-        self.inventory["_meta"]["hostvars"][hostname]['ansible_ssh_host'] = dest
-
-
-    def add_rds_instance(self, instance, region):
-        ''' Adds an RDS instance to the inventory and index, as long as it is
-        addressable '''
-
-        # Only want available instances unless all_rds_instances is True
-        if not self.all_rds_instances and instance.status != 'available':
-            return
-
-        # Select the best destination address
-        dest = instance.endpoint[0]
-
-        if not dest:
-            # Skip instances we cannot address (e.g. private VPC subnet)
-            return
-
-        # Set the inventory name
-        hostname = None
-        if self.hostname_variable:
-            if self.hostname_variable.startswith('tag_'):
-                hostname = instance.tags.get(self.hostname_variable[4:], None)
-            else:
-                hostname = getattr(instance, self.hostname_variable)
-
-        # If we can't get a nice hostname, use the destination address
-        if not hostname:
-            hostname = dest
-
-        hostname = self.to_safe(hostname).lower()
-
-        # Add to index
-        self.index[hostname] = [region, instance.id]
-
-        # Inventory: Group by instance ID (always a group of 1)
-        if self.group_by_instance_id:
-            self.inventory[instance.id] = [hostname]
-            if self.nested_groups:
-                self.push_group(self.inventory, 'instances', instance.id)
-
-        # Inventory: Group by region
-        if self.group_by_region:
-            self.push(self.inventory, region, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'regions', region)
-
-        # Inventory: Group by availability zone
-        if self.group_by_availability_zone:
-            self.push(self.inventory, instance.availability_zone, hostname)
-            if self.nested_groups:
-                if self.group_by_region:
-                    self.push_group(self.inventory, region, instance.availability_zone)
-                self.push_group(self.inventory, 'zones', instance.availability_zone)
-
-        # Inventory: Group by instance type
-        if self.group_by_instance_type:
-            type_name = self.to_safe('type_' + instance.instance_class)
-            self.push(self.inventory, type_name, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'types', type_name)
-
-        # Inventory: Group by VPC
-        if self.group_by_vpc_id and instance.subnet_group and instance.subnet_group.vpc_id:
-            vpc_id_name = self.to_safe('vpc_id_' + instance.subnet_group.vpc_id)
-            self.push(self.inventory, vpc_id_name, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'vpcs', vpc_id_name)
-
-        # Inventory: Group by security group
-        if self.group_by_security_group:
-            try:
-                if instance.security_group:
-                    key = self.to_safe("security_group_" + instance.security_group.name)
-                    self.push(self.inventory, key, hostname)
-                    if self.nested_groups:
-                        self.push_group(self.inventory, 'security_groups', key)
-
-            except AttributeError:
-                self.fail_with_error('\n'.join(['Package boto seems a bit older.',
-                                                'Please upgrade boto >= 2.3.0.']))
-
-
-        # Inventory: Group by engine
-        if self.group_by_rds_engine:
-            self.push(self.inventory, self.to_safe("rds_" + instance.engine), hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'rds_engines', self.to_safe("rds_" + instance.engine))
-
-        # Inventory: Group by parameter group
-        if self.group_by_rds_parameter_group:
-            self.push(self.inventory, self.to_safe("rds_parameter_group_" + instance.parameter_group.name), hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'rds_parameter_groups', self.to_safe("rds_parameter_group_" + instance.parameter_group.name))
-
-        # Global Tag: all RDS instances
-        self.push(self.inventory, 'rds', hostname)
-
-        self.inventory["_meta"]["hostvars"][hostname] = self.get_host_info_dict_from_instance(instance)
-        self.inventory["_meta"]["hostvars"][hostname]['ansible_ssh_host'] = dest
-
-    def add_elasticache_cluster(self, cluster, region):
-        ''' Adds an ElastiCache cluster to the inventory and index, as long as
-        it's nodes are addressable '''
-
-        # Only want available clusters unless all_elasticache_clusters is True
-        if not self.all_elasticache_clusters and cluster['CacheClusterStatus'] != 'available':
-            return
-
-        # Select the best destination address
-        if 'ConfigurationEndpoint' in cluster and cluster['ConfigurationEndpoint']:
-            # Memcached cluster
-            dest = cluster['ConfigurationEndpoint']['Address']
-            is_redis = False
-        else:
-            # Redis sigle node cluster
-            # Because all Redis clusters are single nodes, we'll merge the
-            # info from the cluster with info about the node
-            dest = cluster['CacheNodes'][0]['Endpoint']['Address']
-            is_redis = True
-
-        if not dest:
-            # Skip clusters we cannot address (e.g. private VPC subnet)
-            return
-
-        # Add to index
-        self.index[dest] = [region, cluster['CacheClusterId']]
-
-        # Inventory: Group by instance ID (always a group of 1)
-        if self.group_by_instance_id:
-            self.inventory[cluster['CacheClusterId']] = [dest]
-            if self.nested_groups:
-                self.push_group(self.inventory, 'instances', cluster['CacheClusterId'])
-
-        # Inventory: Group by region
-        if self.group_by_region and not is_redis:
-            self.push(self.inventory, region, dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'regions', region)
-
-        # Inventory: Group by availability zone
-        if self.group_by_availability_zone and not is_redis:
-            self.push(self.inventory, cluster['PreferredAvailabilityZone'], dest)
-            if self.nested_groups:
-                if self.group_by_region:
-                    self.push_group(self.inventory, region, cluster['PreferredAvailabilityZone'])
-                self.push_group(self.inventory, 'zones', cluster['PreferredAvailabilityZone'])
-
-        # Inventory: Group by node type
-        if self.group_by_instance_type and not is_redis:
-            type_name = self.to_safe('type_' + cluster['CacheNodeType'])
-            self.push(self.inventory, type_name, dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'types', type_name)
-
-        # Inventory: Group by VPC (information not available in the current
-        # AWS API version for ElastiCache)
-
-        # Inventory: Group by security group
-        if self.group_by_security_group and not is_redis:
-
-            # Check for the existence of the 'SecurityGroups' key and also if
-            # this key has some value. When the cluster is not placed in a SG
-            # the query can return None here and cause an error.
-            if 'SecurityGroups' in cluster and cluster['SecurityGroups'] is not None:
-                for security_group in cluster['SecurityGroups']:
-                    key = self.to_safe("security_group_" + security_group['SecurityGroupId'])
-                    self.push(self.inventory, key, dest)
-                    if self.nested_groups:
-                        self.push_group(self.inventory, 'security_groups', key)
-
-        # Inventory: Group by engine
-        if self.group_by_elasticache_engine and not is_redis:
-            self.push(self.inventory, self.to_safe("elasticache_" + cluster['Engine']), dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'elasticache_engines', self.to_safe(cluster['Engine']))
-
-        # Inventory: Group by parameter group
-        if self.group_by_elasticache_parameter_group:
-            self.push(self.inventory, self.to_safe("elasticache_parameter_group_" + cluster['CacheParameterGroup']['CacheParameterGroupName']), dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'elasticache_parameter_groups', self.to_safe(cluster['CacheParameterGroup']['CacheParameterGroupName']))
-
-        # Inventory: Group by replication group
-        if self.group_by_elasticache_replication_group and 'ReplicationGroupId' in cluster and cluster['ReplicationGroupId']:
-            self.push(self.inventory, self.to_safe("elasticache_replication_group_" + cluster['ReplicationGroupId']), dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'elasticache_replication_groups', self.to_safe(cluster['ReplicationGroupId']))
-
-        # Global Tag: all ElastiCache clusters
-        self.push(self.inventory, 'elasticache_clusters', cluster['CacheClusterId'])
-
-        host_info = self.get_host_info_dict_from_describe_dict(cluster)
-
-        self.inventory["_meta"]["hostvars"][dest] = host_info
-
-        # Add the nodes
-        for node in cluster['CacheNodes']:
-            self.add_elasticache_node(node, cluster, region)
-
-    def add_elasticache_node(self, node, cluster, region):
-        ''' Adds an ElastiCache node to the inventory and index, as long as
-        it is addressable '''
-
-        # Only want available nodes unless all_elasticache_nodes is True
-        if not self.all_elasticache_nodes and node['CacheNodeStatus'] != 'available':
-            return
-
-        # Select the best destination address
-        dest = node['Endpoint']['Address']
-
-        if not dest:
-            # Skip nodes we cannot address (e.g. private VPC subnet)
-            return
-
-        node_id = self.to_safe(cluster['CacheClusterId'] + '_' + node['CacheNodeId'])
-
-        # Add to index
-        self.index[dest] = [region, node_id]
-
-        # Inventory: Group by node ID (always a group of 1)
-        if self.group_by_instance_id:
-            self.inventory[node_id] = [dest]
-            if self.nested_groups:
-                self.push_group(self.inventory, 'instances', node_id)
-
-        # Inventory: Group by region
-        if self.group_by_region:
-            self.push(self.inventory, region, dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'regions', region)
-
-        # Inventory: Group by availability zone
-        if self.group_by_availability_zone:
-            self.push(self.inventory, cluster['PreferredAvailabilityZone'], dest)
-            if self.nested_groups:
-                if self.group_by_region:
-                    self.push_group(self.inventory, region, cluster['PreferredAvailabilityZone'])
-                self.push_group(self.inventory, 'zones', cluster['PreferredAvailabilityZone'])
-
-        # Inventory: Group by node type
-        if self.group_by_instance_type:
-            type_name = self.to_safe('type_' + cluster['CacheNodeType'])
-            self.push(self.inventory, type_name, dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'types', type_name)
-
-        # Inventory: Group by VPC (information not available in the current
-        # AWS API version for ElastiCache)
-
-        # Inventory: Group by security group
-        if self.group_by_security_group:
-
-            # Check for the existence of the 'SecurityGroups' key and also if
-            # this key has some value. When the cluster is not placed in a SG
-            # the query can return None here and cause an error.
-            if 'SecurityGroups' in cluster and cluster['SecurityGroups'] is not None:
-                for security_group in cluster['SecurityGroups']:
-                    key = self.to_safe("security_group_" + security_group['SecurityGroupId'])
-                    self.push(self.inventory, key, dest)
-                    if self.nested_groups:
-                        self.push_group(self.inventory, 'security_groups', key)
-
-        # Inventory: Group by engine
-        if self.group_by_elasticache_engine:
-            self.push(self.inventory, self.to_safe("elasticache_" + cluster['Engine']), dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'elasticache_engines', self.to_safe("elasticache_" + cluster['Engine']))
-
-        # Inventory: Group by parameter group (done at cluster level)
-
-        # Inventory: Group by replication group (done at cluster level)
-
-        # Inventory: Group by ElastiCache Cluster
-        if self.group_by_elasticache_cluster:
-            self.push(self.inventory, self.to_safe("elasticache_cluster_" + cluster['CacheClusterId']), dest)
-
-        # Global Tag: all ElastiCache nodes
-        self.push(self.inventory, 'elasticache_nodes', dest)
-
-        host_info = self.get_host_info_dict_from_describe_dict(node)
-
-        if dest in self.inventory["_meta"]["hostvars"]:
-            self.inventory["_meta"]["hostvars"][dest].update(host_info)
-        else:
-            self.inventory["_meta"]["hostvars"][dest] = host_info
-
-    def add_elasticache_replication_group(self, replication_group, region):
-        ''' Adds an ElastiCache replication group to the inventory and index '''
-
-        # Only want available clusters unless all_elasticache_replication_groups is True
-        if not self.all_elasticache_replication_groups and replication_group['Status'] != 'available':
-            return
-
-        # Select the best destination address (PrimaryEndpoint)
-        dest = replication_group['NodeGroups'][0]['PrimaryEndpoint']['Address']
-
-        if not dest:
-            # Skip clusters we cannot address (e.g. private VPC subnet)
-            return
-
-        # Add to index
-        self.index[dest] = [region, replication_group['ReplicationGroupId']]
-
-        # Inventory: Group by ID (always a group of 1)
-        if self.group_by_instance_id:
-            self.inventory[replication_group['ReplicationGroupId']] = [dest]
-            if self.nested_groups:
-                self.push_group(self.inventory, 'instances', replication_group['ReplicationGroupId'])
-
-        # Inventory: Group by region
-        if self.group_by_region:
-            self.push(self.inventory, region, dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'regions', region)
-
-        # Inventory: Group by availability zone (doesn't apply to replication groups)
-
-        # Inventory: Group by node type (doesn't apply to replication groups)
-
-        # Inventory: Group by VPC (information not available in the current
-        # AWS API version for replication groups
-
-        # Inventory: Group by security group (doesn't apply to replication groups)
-        # Check this value in cluster level
-
-        # Inventory: Group by engine (replication groups are always Redis)
-        if self.group_by_elasticache_engine:
-            self.push(self.inventory, 'elasticache_redis', dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'elasticache_engines', 'redis')
-
-        # Global Tag: all ElastiCache clusters
-        self.push(self.inventory, 'elasticache_replication_groups', replication_group['ReplicationGroupId'])
-
-        host_info = self.get_host_info_dict_from_describe_dict(replication_group)
-
-        self.inventory["_meta"]["hostvars"][dest] = host_info
-
-    def get_route53_records(self):
-        ''' Get and store the map of resource records to domain names that
-        point to them. '''
-
-        r53_conn = route53.Route53Connection()
-        all_zones = r53_conn.get_zones()
-
-        route53_zones = [ zone for zone in all_zones if zone.name[:-1]
-                          not in self.route53_excluded_zones ]
-
-        self.route53_records = {}
-
-        for zone in route53_zones:
-            rrsets = r53_conn.get_all_rrsets(zone.id)
-
-            for record_set in rrsets:
-                record_name = record_set.name
-
-                if record_name.endswith('.'):
-                    record_name = record_name[:-1]
-
-                for resource in record_set.resource_records:
-                    self.route53_records.setdefault(resource, set())
-                    self.route53_records[resource].add(record_name)
-
-
-    def get_instance_route53_names(self, instance):
-        ''' Check if an instance is referenced in the records we have from
-        Route53. If it is, return the list of domain names pointing to said
-        instance. If nothing points to it, return an empty list. '''
-
-        instance_attributes = [ 'public_dns_name', 'private_dns_name',
-                                'ip_address', 'private_ip_address' ]
-
-        name_list = set()
-
-        for attrib in instance_attributes:
-            try:
-                value = getattr(instance, attrib)
-            except AttributeError:
-                continue
-
-            if value in self.route53_records:
-                name_list.update(self.route53_records[value])
-
-        return list(name_list)
-
-    def get_host_info_dict_from_instance(self, instance):
-        instance_vars = {}
-        for key in vars(instance):
-            value = getattr(instance, key)
-            key = self.to_safe('ec2_' + key)
-
-            # Handle complex types
-            # state/previous_state changed to properties in boto in https://github.com/boto/boto/commit/a23c379837f698212252720d2af8dec0325c9518
-            if key == 'ec2__state':
-                instance_vars['ec2_state'] = instance.state or ''
-                instance_vars['ec2_state_code'] = instance.state_code
-            elif key == 'ec2__previous_state':
-                instance_vars['ec2_previous_state'] = instance.previous_state or ''
-                instance_vars['ec2_previous_state_code'] = instance.previous_state_code
-            elif type(value) in [int, bool]:
-                instance_vars[key] = value
-            elif isinstance(value, six.string_types):
-                instance_vars[key] = value.strip()
-            elif type(value) == type(None):
-                instance_vars[key] = ''
-            elif key == 'ec2_region':
-                instance_vars[key] = value.name
-            elif key == 'ec2__placement':
-                instance_vars['ec2_placement'] = value.zone
-            elif key == 'ec2_tags':
-                for k, v in value.items():
-                    if self.expand_csv_tags and ',' in v:
-                        v = map(lambda x: x.strip(), v.split(','))
-                    key = self.to_safe('ec2_tag_' + k)
-                    instance_vars[key] = v
-            elif key == 'ec2_groups':
-                group_ids = []
-                group_names = []
-                for group in value:
-                    group_ids.append(group.id)
-                    group_names.append(group.name)
-                instance_vars["ec2_security_group_ids"] = ','.join([str(i) for i in group_ids])
-                instance_vars["ec2_security_group_names"] = ','.join([str(i) for i in group_names])
-            else:
-                pass
-                # TODO Product codes if someone finds them useful
-                #print key
-                #print type(value)
-                #print value
-
-        return instance_vars
-
-    def get_host_info_dict_from_describe_dict(self, describe_dict):
-        ''' Parses the dictionary returned by the API call into a flat list
-            of parameters. This method should be used only when 'describe' is
-            used directly because Boto doesn't provide specific classes. '''
-
-        # I really don't agree with prefixing everything with 'ec2'
-        # because EC2, RDS and ElastiCache are different services.
-        # I'm just following the pattern used until now to not break any
-        # compatibility.
-
-        host_info = {}
-        for key in describe_dict:
-            value = describe_dict[key]
-            key = self.to_safe('ec2_' + self.uncammelize(key))
-
-            # Handle complex types
-
-            # Target: Memcached Cache Clusters
-            if key == 'ec2_configuration_endpoint' and value:
-                host_info['ec2_configuration_endpoint_address'] = value['Address']
-                host_info['ec2_configuration_endpoint_port'] = value['Port']
-
-            # Target: Cache Nodes and Redis Cache Clusters (single node)
-            if key == 'ec2_endpoint' and value:
-                host_info['ec2_endpoint_address'] = value['Address']
-                host_info['ec2_endpoint_port'] = value['Port']
-
-            # Target: Redis Replication Groups
-            if key == 'ec2_node_groups' and value:
-                host_info['ec2_endpoint_address'] = value[0]['PrimaryEndpoint']['Address']
-                host_info['ec2_endpoint_port'] = value[0]['PrimaryEndpoint']['Port']
-                replica_count = 0
-                for node in value[0]['NodeGroupMembers']:
-                    if node['CurrentRole'] == 'primary':
-                        host_info['ec2_primary_cluster_address'] = node['ReadEndpoint']['Address']
-                        host_info['ec2_primary_cluster_port'] = node['ReadEndpoint']['Port']
-                        host_info['ec2_primary_cluster_id'] = node['CacheClusterId']
-                    elif node['CurrentRole'] == 'replica':
-                        host_info['ec2_replica_cluster_address_'+ str(replica_count)] = node['ReadEndpoint']['Address']
-                        host_info['ec2_replica_cluster_port_'+ str(replica_count)] = node['ReadEndpoint']['Port']
-                        host_info['ec2_replica_cluster_id_'+ str(replica_count)] = node['CacheClusterId']
-                        replica_count += 1
-
-            # Target: Redis Replication Groups
-            if key == 'ec2_member_clusters' and value:
-                host_info['ec2_member_clusters'] = ','.join([str(i) for i in value])
-
-            # Target: All Cache Clusters
-            elif key == 'ec2_cache_parameter_group':
-                host_info["ec2_cache_node_ids_to_reboot"] = ','.join([str(i) for i in value['CacheNodeIdsToReboot']])
-                host_info['ec2_cache_parameter_group_name'] = value['CacheParameterGroupName']
-                host_info['ec2_cache_parameter_apply_status'] = value['ParameterApplyStatus']
-
-            # Target: Almost everything
-            elif key == 'ec2_security_groups':
-
-                # Skip if SecurityGroups is None
-                # (it is possible to have the key defined but no value in it).
-                if value is not None:
-                    sg_ids = []
-                    for sg in value:
-                        sg_ids.append(sg['SecurityGroupId'])
-                    host_info["ec2_security_group_ids"] = ','.join([str(i) for i in sg_ids])
-
-            # Target: Everything
-            # Preserve booleans and integers
-            elif type(value) in [int, bool]:
-                host_info[key] = value
-
-            # Target: Everything
-            # Sanitize string values
-            elif isinstance(value, six.string_types):
-                host_info[key] = value.strip()
-
-            # Target: Everything
-            # Replace None by an empty string
-            elif type(value) == type(None):
-                host_info[key] = ''
-
-            else:
-                # Remove non-processed complex types
-                pass
-
-        return host_info
-
-    def get_host_info(self):
-        ''' Get variables about a specific host '''
-
-        if len(self.index) == 0:
-            # Need to load index from cache
-            self.load_index_from_cache()
-
-        if not self.args.host in self.index:
-            # try updating the cache
-            self.do_api_calls_update_cache()
-            if not self.args.host in self.index:
-                # host might not exist anymore
-                return self.json_format_dict({}, True)
-
-        (region, instance_id) = self.index[self.args.host]
-
-        instance = self.get_instance(region, instance_id)
-        return self.json_format_dict(self.get_host_info_dict_from_instance(instance), True)
-
-    def push(self, my_dict, key, element):
-        ''' Push an element onto an array that may not have been defined in
-        the dict '''
-        group_info = my_dict.setdefault(key, [])
-        if isinstance(group_info, dict):
-            host_list = group_info.setdefault('hosts', [])
-            host_list.append(element)
-        else:
-            group_info.append(element)
-
-    def push_group(self, my_dict, key, element):
-        ''' Push a group as a child of another group. '''
-        parent_group = my_dict.setdefault(key, {})
-        if not isinstance(parent_group, dict):
-            parent_group = my_dict[key] = {'hosts': parent_group}
-        child_groups = parent_group.setdefault('children', [])
-        if element not in child_groups:
-            child_groups.append(element)
-
-    def get_inventory_from_cache(self):
-        ''' Reads the inventory from the cache file and returns it as a JSON
-        object '''
-
-        cache = open(self.cache_path_cache, 'r')
-        json_inventory = cache.read()
-        return json_inventory
-
-
-    def load_index_from_cache(self):
-        ''' Reads the index from the cache file sets self.index '''
-
-        cache = open(self.cache_path_index, 'r')
-        json_index = cache.read()
-        self.index = json.loads(json_index)
-
-
-    def write_to_cache(self, data, filename):
-        ''' Writes data in JSON format to a file '''
-
-        json_data = self.json_format_dict(data, True)
-        cache = open(filename, 'w')
-        cache.write(json_data)
-        cache.close()
-
-    def uncammelize(self, key):
-        temp = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', key)
-        return re.sub('([a-z0-9])([A-Z])', r'\1_\2', temp).lower()
-
-    def to_safe(self, word):
-        ''' Converts 'bad' characters in a string to underscores so they can be used as Ansible groups '''
-        regex = "[^A-Za-z0-9\_"
-        if not self.replace_dash_in_groups:
-            regex += "\-"
-        return re.sub(regex + "]", "_", word)
-
-    def json_format_dict(self, data, pretty=False):
-        ''' Converts a dict to a JSON object and dumps it as a formatted
-        string '''
-
-        if pretty:
-            return json.dumps(data, sort_keys=True, indent=2)
-        else:
-            return json.dumps(data)
-
-
-# Run the script
-Ec2Inventory()
diff --git a/edge-1601-dc1-dc2/inventory-dc1 b/edge-1601-dc1-dc2/inventory-dc1
deleted file mode 100644
index a26a6fe..0000000
--- a/edge-1601-dc1-dc2/inventory-dc1
+++ /dev/null
@@ -1,74 +0,0 @@
-[tag_Name_dc1_n1]
-[tag_Name_dc1_n2]
-[tag_Name_dc1_n3]
-[tag_Name_dc1_n4]
-[tag_Name_dc1_n5]
-
-[planet:children]
-dc-1
-
-[dc-1:children]
-tag_Name_dc1_n1
-tag_Name_dc1_n2
-tag_Name_dc1_n3
-tag_Name_dc1_n4
-tag_Name_dc1_n5
-
-[ds:children]
-dc-1-ds
-
-[dc-1-ds:children]
-tag_Name_dc1_n1
-tag_Name_dc1_n2
-tag_Name_dc1_n3
-
-[ms:children]
-dc-1-ms
-
-[dc-1-ms:children]
-tag_Name_dc1_n1
-
-[ui:children]
-dc-1-ui
-
-[dc-1-ui:children]
-tag_Name_dc1_n1
-
-[ldap:children]
-dc-1-ldap
-
-[dc-1-ldap:children]
-tag_Name_dc1_n1
-
-[rmp:children]
-dc-1-rmp
-
-[dc-1-rmp:children]
-tag_Name_dc1_n2
-tag_Name_dc1_n3
-
-[qpid:children]
-dc-1-qpid
-
-[dc-1-qpid:children]
-tag_Name_dc1_n4
-tag_Name_dc1_n5
-
-[pg:children]
-dc-1-pg
-
-[dc-1-pg:children]
-dc-1-pgmaster
-dc-1-pgstandby
-
-[pgmaster:children]
-dc-1-pgmaster
-
-[dc-1-pgmaster:children]
-tag_Name_dc1_n4
-
-[pgstandby:children]
-dc-1-pgstandby
-
-[dc-1-pgstandby:children]
-tag_Name_dc1_n5
diff --git a/edge-1601-dc1-dc2/inventory-dc2 b/edge-1601-dc1-dc2/inventory-dc2
deleted file mode 100644
index 71a7ba8..0000000
--- a/edge-1601-dc1-dc2/inventory-dc2
+++ /dev/null
@@ -1,74 +0,0 @@
-[tag_Name_dc2_n1]
-[tag_Name_dc2_n2]
-[tag_Name_dc2_n3]
-[tag_Name_dc2_n4]
-[tag_Name_dc2_n5]
-
-[planet:children]
-dc-2
-
-[dc-2:children]
-tag_Name_dc2_n1
-tag_Name_dc2_n2
-tag_Name_dc2_n3
-tag_Name_dc2_n4
-tag_Name_dc2_n5
-
-[ds:children]
-dc-2-ds
-
-[dc-2-ds:children]
-tag_Name_dc2_n1
-tag_Name_dc2_n2
-tag_Name_dc2_n3
-
-[ms:children]
-dc-2-ms
-
-[dc-2-ms:children]
-tag_Name_dc2_n1
-
-[ui:children]
-dc-2-ui
-
-[dc-2-ui:children]
-tag_Name_dc2_n1
-
-[ldap:children]
-dc-2-ldap
-
-[dc-2-ldap:children]
-tag_Name_dc2_n1
-
-[rmp:children]
-dc-2-rmp
-
-[dc-2-rmp:children]
-tag_Name_dc2_n2
-tag_Name_dc2_n3
-
-[qpid:children]
-dc-2-qpid
-
-[dc-2-qpid:children]
-tag_Name_dc2_n4
-tag_Name_dc2_n5
-
-[pg:children]
-dc-2-pg
-
-[dc-2-pg:children]
-dc-2-pgmaster
-dc-2-pgstandby
-
-[pgmaster:children]
-dc-2-pgmaster
-
-[dc-2-pgmaster:children]
-tag_Name_dc2_n4
-
-[pgstandby:children]
-dc-2-pgstandby
-
-[dc-2-pgstandby:children]
-tag_Name_dc2_n5
diff --git a/edge-1601-dc1-dc2/inventory-haproxy b/edge-1601-dc1-dc2/inventory-haproxy
deleted file mode 100644
index 6b45b6a..0000000
--- a/edge-1601-dc1-dc2/inventory-haproxy
+++ /dev/null
@@ -1,7 +0,0 @@
-[tag_Name_dc10_n1]
-
-[planet:children]
-haproxy
-
-[haproxy:children]
-tag_Name_dc0_n1
diff --git a/edge-1601-dc1/ec2.ini b/edge-1601-dc1/ec2.ini
deleted file mode 100644
index 36b3921..0000000
--- a/edge-1601-dc1/ec2.ini
+++ /dev/null
@@ -1,200 +0,0 @@
-# Ansible EC2 external inventory script settings
-#
-
-[ec2]
-
-# to talk to a private eucalyptus instance uncomment these lines
-# and edit edit eucalyptus_host to be the host name of your cloud controller
-#eucalyptus = True
-#eucalyptus_host = clc.cloud.domain.org
-
-# AWS regions to make calls to. Set this to 'all' to make request to all regions
-# in AWS and merge the results together. Alternatively, set this to a comma
-# separated list of regions. E.g. 'us-east-1,us-west-1,us-west-2'
-regions = all
-regions_exclude = us-gov-west-1,cn-north-1
-
-# When generating inventory, Ansible needs to know how to address a server.
-# Each EC2 instance has a lot of variables associated with it. Here is the list:
-#   http://docs.pythonboto.org/en/latest/ref/ec2.html#module-boto.ec2.instance
-# Below are 2 variables that are used as the address of a server:
-#   - destination_variable
-#   - vpc_destination_variable
-
-# This is the normal destination variable to use. If you are running Ansible
-# from outside EC2, then 'public_dns_name' makes the most sense. If you are
-# running Ansible from within EC2, then perhaps you want to use the internal
-# address, and should set this to 'private_dns_name'. The key of an EC2 tag
-# may optionally be used; however the boto instance variables hold precedence
-# in the event of a collision.
-destination_variable = public_dns_name
-
-# This allows you to override the inventory_name with an ec2 variable, instead
-# of using the destination_variable above. Addressing (aka ansible_ssh_host)
-# will still use destination_variable. Tags should be written as 'tag_TAGNAME'.
-#hostname_variable = tag_Name
-
-# For server inside a VPC, using DNS names may not make sense. When an instance
-# has 'subnet_id' set, this variable is used. If the subnet is public, setting
-# this to 'ip_address' will return the public IP address. For instances in a
-# private subnet, this should be set to 'private_ip_address', and Ansible must
-# be run from within EC2. The key of an EC2 tag may optionally be used; however
-# the boto instance variables hold precedence in the event of a collision.
-# WARNING: - instances that are in the private vpc, _without_ public ip address
-# will not be listed in the inventory until You set:
-# vpc_destination_variable = private_ip_address
-vpc_destination_variable = ip_address
-
-# The following two settings allow flexible ansible host naming based on a
-# python format string and a comma-separated list of ec2 tags.  Note that:
-#
-# 1) If the tags referenced are not present for some instances, empty strings
-#    will be substituted in the format string.
-# 2) This overrides both destination_variable and vpc_destination_variable.
-#
-#destination_format = {0}.{1}.example.com
-#destination_format_tags = Name,environment
-
-# To tag instances on EC2 with the resource records that point to them from
-# Route53, uncomment and set 'route53' to True.
-route53 = False
-
-# To exclude RDS instances from the inventory, uncomment and set to False.
-rds = False
-
-# To exclude ElastiCache instances from the inventory, uncomment and set to False.
-elasticache = False
-
-# Additionally, you can specify the list of zones to exclude looking up in
-# 'route53_excluded_zones' as a comma-separated list.
-# route53_excluded_zones = samplezone1.com, samplezone2.com
-
-# By default, only EC2 instances in the 'running' state are returned. Set
-# 'all_instances' to True to return all instances regardless of state.
-all_instances = True
-
-# By default, only EC2 instances in the 'running' state are returned. Specify
-# EC2 instance states to return as a comma-separated list. This
-# option is overriden when 'all_instances' is True.
-# instance_states = pending, running, shutting-down, terminated, stopping, stopped
-
-# By default, only RDS instances in the 'available' state are returned.  Set
-# 'all_rds_instances' to True return all RDS instances regardless of state.
-all_rds_instances = False
-
-# By default, only ElastiCache clusters and nodes in the 'available' state
-# are returned. Set 'all_elasticache_clusters' and/or 'all_elastic_nodes'
-# to True return all ElastiCache clusters and nodes, regardless of state.
-#
-# Note that all_elasticache_nodes only applies to listed clusters. That means
-# if you set all_elastic_clusters to false, no node will be return from
-# unavailable clusters, regardless of the state and to what you set for
-# all_elasticache_nodes.
-all_elasticache_replication_groups = False
-all_elasticache_clusters = False
-all_elasticache_nodes = False
-
-# API calls to EC2 are slow. For this reason, we cache the results of an API
-# call. Set this to the path you want cache files to be written to. Two files
-# will be written to this directory:
-#   - ansible-ec2.cache
-#   - ansible-ec2.index
-cache_path = ~/.ansible/tmp
-
-# The number of seconds a cache file is considered valid. After this many
-# seconds, a new API call will be made, and the cache file will be updated.
-# To disable the cache, set this value to 0
-cache_max_age = 300
-
-# Organize groups into a nested/hierarchy instead of a flat namespace.
-nested_groups = False
-
-# Replace - tags when creating groups to avoid issues with ansible
-replace_dash_in_groups = True
-
-# If set to true, any tag of the form "a,b,c" is expanded into a list
-# and the results are used to create additional tag_* inventory groups.
-expand_csv_tags = False
-
-# The EC2 inventory output can become very large. To manage its size,
-# configure which groups should be created.
-group_by_instance_id = True
-group_by_region = True
-group_by_availability_zone = True
-group_by_ami_id = True
-group_by_instance_type = True
-group_by_key_pair = True
-group_by_vpc_id = True
-group_by_security_group = True
-group_by_tag_keys = True
-group_by_tag_none = True
-group_by_route53_names = True
-group_by_rds_engine = False
-group_by_rds_parameter_group = False
-group_by_elasticache_engine = True
-group_by_elasticache_cluster = True
-group_by_elasticache_parameter_group = True
-group_by_elasticache_replication_group = True
-
-# If you only want to include hosts that match a certain regular expression
-# pattern_include = staging-*
-
-# If you want to exclude any hosts that match a certain regular expression
-# pattern_exclude = staging-*
-# Ansible EC2 external inventory script settings
-#
-
-##[ec2]
-##
-### to talk to a private eucalyptus instance uncomment these lines
-### and edit edit eucalyptus_host to be the host name of your cloud controller
-###eucalyptus = True
-###eucalyptus_host = clc.cloud.domain.org
-##
-### AWS regions to make calls to. Set this to 'all' to make request to all regions
-##
-### in AWS and merge the results together. Alternatively, set this to a comma
-### separated list of regions. E.g. 'us-east-1,us-west-1,us-west-2'
-##regions = all
-##regions_exclude = us-gov-west-1,cn-north-1
-##
-### When generating inventory, Ansible needs to know how to address a server.
-### Each EC2 instance has a lot of variables associated with it. Here is the list:
-###   http://docs.pythonboto.org/en/latest/ref/ec2.html#module-boto.ec2.instance
-### Below are 2 variables that are used as the address of a server:
-###   - destination_variable
-###   - vpc_destination_variable
-##
-### This is the normal destination variable to use. If you are running Ansible
-### from outside EC2, then 'public_dns_name' makes the most sense. If you are
-### running Ansible from within EC2, then perhaps you want to use the internal
-### address, and should set this to 'private_dns_name'. The key of an EC2 tag
-##...skipping...
-### pattern_include = staging-*
-##
-### If you want to exclude any hosts that match a certain regular expression
-### pattern_exclude = staging-*
-
-# Instance filters can be used to control which instances are retrieved for
-# inventory. For the full list of possible filters, please read the EC2 API
-# docs: http://docs.aws.amazon.com/AWSEC2/latest/APIReference/ApiReference-query-DescribeInstances.html#query-DescribeInstances-filters
-# Filters are key/value pairs separated by '=', to list multiple filters use
-# a list separated by commas. See examples below.
-
-# Retrieve only instances with (key=value) env=staging tag
-# instance_filters = tag:env=staging
-
-# Retrieve only instances with role=webservers OR role=dbservers tag
-# instance_filters = tag:role=webservers,tag:role=dbservers
-
-# Retrieve only t1.micro instances OR instances with tag env=staging
-# instance_filters = instance-type=t1.micro,tag:env=staging
-
-# You can use wildcards in filter values also. Below will list instances which
-# tag Name value matches webservers1*
-# (ex. webservers15, webservers1a, webservers123 etc)
-# instance_filters = tag:Name=webservers1*
-
-# A boto configuration profile may be used to separate out credentials
-# see http://boto.readthedocs.org/en/latest/boto_config_tut.html
-# boto_profile = some-boto-profile-name
diff --git a/edge-1601-dc1/ec2.py b/edge-1601-dc1/ec2.py
deleted file mode 100755
index 25b3ab4..0000000
--- a/edge-1601-dc1/ec2.py
+++ /dev/null
@@ -1,1385 +0,0 @@
-#!/usr/bin/env python
-
-'''
-EC2 external inventory script
-=================================
-
-Generates inventory that Ansible can understand by making API request to
-AWS EC2 using the Boto library.
-
-NOTE: This script assumes Ansible is being executed where the environment
-variables needed for Boto have already been set:
-    export AWS_ACCESS_KEY_ID='AK123'
-    export AWS_SECRET_ACCESS_KEY='abc123'
-
-This script also assumes there is an ec2.ini file alongside it.  To specify a
-different path to ec2.ini, define the EC2_INI_PATH environment variable:
-
-    export EC2_INI_PATH=/path/to/my_ec2.ini
-
-If you're using eucalyptus you need to set the above variables and
-you need to define:
-
-    export EC2_URL=http://hostname_of_your_cc:port/services/Eucalyptus
-
-If you're using boto profiles (requires boto>=2.24.0) you can choose a profile
-using the --boto-profile command line argument (e.g. ec2.py --boto-profile prod) or using
-the AWS_PROFILE variable:
-
-    AWS_PROFILE=prod ansible-playbook -i ec2.py myplaybook.yml
-
-For more details, see: http://docs.pythonboto.org/en/latest/boto_config_tut.html
-
-When run against a specific host, this script returns the following variables:
- - ec2_ami_launch_index
- - ec2_architecture
- - ec2_association
- - ec2_attachTime
- - ec2_attachment
- - ec2_attachmentId
- - ec2_client_token
- - ec2_deleteOnTermination
- - ec2_description
- - ec2_deviceIndex
- - ec2_dns_name
- - ec2_eventsSet
- - ec2_group_name
- - ec2_hypervisor
- - ec2_id
- - ec2_image_id
- - ec2_instanceState
- - ec2_instance_type
- - ec2_ipOwnerId
- - ec2_ip_address
- - ec2_item
- - ec2_kernel
- - ec2_key_name
- - ec2_launch_time
- - ec2_monitored
- - ec2_monitoring
- - ec2_networkInterfaceId
- - ec2_ownerId
- - ec2_persistent
- - ec2_placement
- - ec2_platform
- - ec2_previous_state
- - ec2_private_dns_name
- - ec2_private_ip_address
- - ec2_publicIp
- - ec2_public_dns_name
- - ec2_ramdisk
- - ec2_reason
- - ec2_region
- - ec2_requester_id
- - ec2_root_device_name
- - ec2_root_device_type
- - ec2_security_group_ids
- - ec2_security_group_names
- - ec2_shutdown_state
- - ec2_sourceDestCheck
- - ec2_spot_instance_request_id
- - ec2_state
- - ec2_state_code
- - ec2_state_reason
- - ec2_status
- - ec2_subnet_id
- - ec2_tenancy
- - ec2_virtualization_type
- - ec2_vpc_id
-
-These variables are pulled out of a boto.ec2.instance object. There is a lack of
-consistency with variable spellings (camelCase and underscores) since this
-just loops through all variables the object exposes. It is preferred to use the
-ones with underscores when multiple exist.
-
-In addition, if an instance has AWS Tags associated with it, each tag is a new
-variable named:
- - ec2_tag_[Key] = [Value]
-
-Security groups are comma-separated in 'ec2_security_group_ids' and
-'ec2_security_group_names'.
-'''
-
-# (c) 2012, Peter Sankauskas
-#
-# This file is part of Ansible,
-#
-# Ansible is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# Ansible is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with Ansible.  If not, see <http://www.gnu.org/licenses/>.
-
-######################################################################
-
-import sys
-import os
-import argparse
-import re
-from time import time
-import boto
-from boto import ec2
-from boto import rds
-from boto import elasticache
-from boto import route53
-import six
-
-from six.moves import configparser
-from collections import defaultdict
-
-try:
-    import json
-except ImportError:
-    import simplejson as json
-
-
-class Ec2Inventory(object):
-
-    def _empty_inventory(self):
-        return {"_meta" : {"hostvars" : {}}}
-
-    def __init__(self):
-        ''' Main execution path '''
-
-        # Inventory grouped by instance IDs, tags, security groups, regions,
-        # and availability zones
-        self.inventory = self._empty_inventory()
-
-        # Index of hostname (address) to instance ID
-        self.index = {}
-
-        # Boto profile to use (if any)
-        self.boto_profile = None
-
-        # Read settings and parse CLI arguments
-        self.parse_cli_args()
-        self.read_settings()
-
-        # Make sure that profile_name is not passed at all if not set
-        # as pre 2.24 boto will fall over otherwise
-        if self.boto_profile:
-            if not hasattr(boto.ec2.EC2Connection, 'profile_name'):
-                self.fail_with_error("boto version must be >= 2.24 to use profile")
-
-        # Cache
-        if self.args.refresh_cache:
-            self.do_api_calls_update_cache()
-        elif not self.is_cache_valid():
-            self.do_api_calls_update_cache()
-
-        # Data to print
-        if self.args.host:
-            data_to_print = self.get_host_info()
-
-        elif self.args.list:
-            # Display list of instances for inventory
-            if self.inventory == self._empty_inventory():
-                data_to_print = self.get_inventory_from_cache()
-            else:
-                data_to_print = self.json_format_dict(self.inventory, True)
-
-        print(data_to_print)
-
-
-    def is_cache_valid(self):
-        ''' Determines if the cache files have expired, or if it is still valid '''
-
-        if os.path.isfile(self.cache_path_cache):
-            mod_time = os.path.getmtime(self.cache_path_cache)
-            current_time = time()
-            if (mod_time + self.cache_max_age) > current_time:
-                if os.path.isfile(self.cache_path_index):
-                    return True
-
-        return False
-
-
-    def read_settings(self):
-        ''' Reads the settings from the ec2.ini file '''
-        if six.PY3:
-            config = configparser.ConfigParser()
-        else:
-            config = configparser.SafeConfigParser()
-        ec2_default_ini_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'ec2.ini')
-        ec2_ini_path = os.path.expanduser(os.path.expandvars(os.environ.get('EC2_INI_PATH', ec2_default_ini_path)))
-        config.read(ec2_ini_path)
-
-        # is eucalyptus?
-        self.eucalyptus_host = None
-        self.eucalyptus = False
-        if config.has_option('ec2', 'eucalyptus'):
-            self.eucalyptus = config.getboolean('ec2', 'eucalyptus')
-        if self.eucalyptus and config.has_option('ec2', 'eucalyptus_host'):
-            self.eucalyptus_host = config.get('ec2', 'eucalyptus_host')
-
-        # Regions
-        self.regions = []
-        configRegions = config.get('ec2', 'regions')
-        configRegions_exclude = config.get('ec2', 'regions_exclude')
-        if (configRegions == 'all'):
-            if self.eucalyptus_host:
-                self.regions.append(boto.connect_euca(host=self.eucalyptus_host).region.name)
-            else:
-                for regionInfo in ec2.regions():
-                    if regionInfo.name not in configRegions_exclude:
-                        self.regions.append(regionInfo.name)
-        else:
-            self.regions = configRegions.split(",")
-
-        # Destination addresses
-        self.destination_variable = config.get('ec2', 'destination_variable')
-        self.vpc_destination_variable = config.get('ec2', 'vpc_destination_variable')
-
-        if config.has_option('ec2', 'hostname_variable'):
-            self.hostname_variable = config.get('ec2', 'hostname_variable')
-        else:
-            self.hostname_variable = None
-
-        if config.has_option('ec2', 'destination_format') and \
-            config.has_option('ec2', 'destination_format_tags'):
-            self.destination_format = config.get('ec2', 'destination_format')
-            self.destination_format_tags = config.get('ec2', 'destination_format_tags').split(',')
-        else:
-            self.destination_format = None
-            self.destination_format_tags = None
-
-        # Route53
-        self.route53_enabled = config.getboolean('ec2', 'route53')
-        self.route53_excluded_zones = []
-        if config.has_option('ec2', 'route53_excluded_zones'):
-            self.route53_excluded_zones.extend(
-                config.get('ec2', 'route53_excluded_zones', '').split(','))
-
-        # Include RDS instances?
-        self.rds_enabled = True
-        if config.has_option('ec2', 'rds'):
-            self.rds_enabled = config.getboolean('ec2', 'rds')
-
-        # Include ElastiCache instances?
-        self.elasticache_enabled = True
-        if config.has_option('ec2', 'elasticache'):
-            self.elasticache_enabled = config.getboolean('ec2', 'elasticache')
-
-        # Return all EC2 instances?
-        if config.has_option('ec2', 'all_instances'):
-            self.all_instances = config.getboolean('ec2', 'all_instances')
-        else:
-            self.all_instances = False
-
-        # Instance states to be gathered in inventory. Default is 'running'.
-        # Setting 'all_instances' to 'yes' overrides this option.
-        ec2_valid_instance_states = [
-            'pending',
-            'running',
-            'shutting-down',
-            'terminated',
-            'stopping',
-            'stopped'
-        ]
-        self.ec2_instance_states = []
-        if self.all_instances:
-            self.ec2_instance_states = ec2_valid_instance_states
-        elif config.has_option('ec2', 'instance_states'):
-            for instance_state in config.get('ec2', 'instance_states').split(','):
-                instance_state = instance_state.strip()
-                if instance_state not in ec2_valid_instance_states:
-                    continue
-                self.ec2_instance_states.append(instance_state)
-        else:
-            self.ec2_instance_states = ['running']
-
-        # Return all RDS instances? (if RDS is enabled)
-        if config.has_option('ec2', 'all_rds_instances') and self.rds_enabled:
-            self.all_rds_instances = config.getboolean('ec2', 'all_rds_instances')
-        else:
-            self.all_rds_instances = False
-
-        # Return all ElastiCache replication groups? (if ElastiCache is enabled)
-        if config.has_option('ec2', 'all_elasticache_replication_groups') and self.elasticache_enabled:
-            self.all_elasticache_replication_groups = config.getboolean('ec2', 'all_elasticache_replication_groups')
-        else:
-            self.all_elasticache_replication_groups = False
-
-        # Return all ElastiCache clusters? (if ElastiCache is enabled)
-        if config.has_option('ec2', 'all_elasticache_clusters') and self.elasticache_enabled:
-            self.all_elasticache_clusters = config.getboolean('ec2', 'all_elasticache_clusters')
-        else:
-            self.all_elasticache_clusters = False
-
-        # Return all ElastiCache nodes? (if ElastiCache is enabled)
-        if config.has_option('ec2', 'all_elasticache_nodes') and self.elasticache_enabled:
-            self.all_elasticache_nodes = config.getboolean('ec2', 'all_elasticache_nodes')
-        else:
-            self.all_elasticache_nodes = False
-
-        # boto configuration profile (prefer CLI argument)
-        self.boto_profile = self.args.boto_profile
-        if config.has_option('ec2', 'boto_profile') and not self.boto_profile:
-            self.boto_profile = config.get('ec2', 'boto_profile')
-
-        # Cache related
-        cache_dir = os.path.expanduser(config.get('ec2', 'cache_path'))
-        if self.boto_profile:
-            cache_dir = os.path.join(cache_dir, 'profile_' + self.boto_profile)
-        if not os.path.exists(cache_dir):
-            os.makedirs(cache_dir)
-
-        cache_name = 'ansible-ec2'
-        aws_profile = lambda: (self.boto_profile or
-                               os.environ.get('AWS_PROFILE') or
-                               os.environ.get('AWS_ACCESS_KEY_ID'))
-        if aws_profile():
-            cache_name = '%s-%s' % (cache_name, aws_profile())
-        self.cache_path_cache = cache_dir + "/%s.cache" % cache_name
-        self.cache_path_index = cache_dir + "/%s.index" % cache_name
-        self.cache_max_age = config.getint('ec2', 'cache_max_age')
-
-        if config.has_option('ec2', 'expand_csv_tags'):
-            self.expand_csv_tags = config.getboolean('ec2', 'expand_csv_tags')
-        else:
-            self.expand_csv_tags = False
-
-        # Configure nested groups instead of flat namespace.
-        if config.has_option('ec2', 'nested_groups'):
-            self.nested_groups = config.getboolean('ec2', 'nested_groups')
-        else:
-            self.nested_groups = False
-
-        # Replace dash or not in group names
-        if config.has_option('ec2', 'replace_dash_in_groups'):
-            self.replace_dash_in_groups = config.getboolean('ec2', 'replace_dash_in_groups')
-        else:
-            self.replace_dash_in_groups = True
-
-        # Configure which groups should be created.
-        group_by_options = [
-            'group_by_instance_id',
-            'group_by_region',
-            'group_by_availability_zone',
-            'group_by_ami_id',
-            'group_by_instance_type',
-            'group_by_key_pair',
-            'group_by_vpc_id',
-            'group_by_security_group',
-            'group_by_tag_keys',
-            'group_by_tag_none',
-            'group_by_route53_names',
-            'group_by_rds_engine',
-            'group_by_rds_parameter_group',
-            'group_by_elasticache_engine',
-            'group_by_elasticache_cluster',
-            'group_by_elasticache_parameter_group',
-            'group_by_elasticache_replication_group',
-        ]
-        for option in group_by_options:
-            if config.has_option('ec2', option):
-                setattr(self, option, config.getboolean('ec2', option))
-            else:
-                setattr(self, option, True)
-
-        # Do we need to just include hosts that match a pattern?
-        try:
-            pattern_include = config.get('ec2', 'pattern_include')
-            if pattern_include and len(pattern_include) > 0:
-                self.pattern_include = re.compile(pattern_include)
-            else:
-                self.pattern_include = None
-        except configparser.NoOptionError:
-            self.pattern_include = None
-
-        # Do we need to exclude hosts that match a pattern?
-        try:
-            pattern_exclude = config.get('ec2', 'pattern_exclude');
-            if pattern_exclude and len(pattern_exclude) > 0:
-                self.pattern_exclude = re.compile(pattern_exclude)
-            else:
-                self.pattern_exclude = None
-        except configparser.NoOptionError:
-            self.pattern_exclude = None
-
-        # Instance filters (see boto and EC2 API docs). Ignore invalid filters.
-        self.ec2_instance_filters = defaultdict(list)
-        if config.has_option('ec2', 'instance_filters'):
-
-            filters = [f for f in config.get('ec2', 'instance_filters').split(',') if f]
-
-            for instance_filter in filters:
-                instance_filter = instance_filter.strip()
-                if not instance_filter or '=' not in instance_filter:
-                    continue
-                filter_key, filter_value = [x.strip() for x in instance_filter.split('=', 1)]
-                if not filter_key:
-                    continue
-                self.ec2_instance_filters[filter_key].append(filter_value)
-
-    def parse_cli_args(self):
-        ''' Command line argument processing '''
-
-        parser = argparse.ArgumentParser(description='Produce an Ansible Inventory file based on EC2')
-        parser.add_argument('--list', action='store_true', default=True,
-                            help='List instances (default: True)')
-        parser.add_argument('--host', action='store',
-                            help='Get all the variables about a specific instance')
-        parser.add_argument('--refresh-cache', action='store_true', default=False,
-                            help='Force refresh of cache by making API requests to EC2 (default: False - use cache files)')
-        parser.add_argument('--profile', '--boto-profile', action='store', dest='boto_profile',
-                            help='Use boto profile for connections to EC2')
-        self.args = parser.parse_args()
-
-
-    def do_api_calls_update_cache(self):
-        ''' Do API calls to each region, and save data in cache files '''
-
-        if self.route53_enabled:
-            self.get_route53_records()
-
-        for region in self.regions:
-            self.get_instances_by_region(region)
-            if self.rds_enabled:
-                self.get_rds_instances_by_region(region)
-            if self.elasticache_enabled:
-                self.get_elasticache_clusters_by_region(region)
-                self.get_elasticache_replication_groups_by_region(region)
-
-        self.write_to_cache(self.inventory, self.cache_path_cache)
-        self.write_to_cache(self.index, self.cache_path_index)
-
-    def connect(self, region):
-        ''' create connection to api server'''
-        if self.eucalyptus:
-            conn = boto.connect_euca(host=self.eucalyptus_host)
-            conn.APIVersion = '2010-08-31'
-        else:
-            conn = self.connect_to_aws(ec2, region)
-        return conn
-
-    def boto_fix_security_token_in_profile(self, connect_args):
-        ''' monkey patch for boto issue boto/boto#2100 '''
-        profile = 'profile ' + self.boto_profile
-        if boto.config.has_option(profile, 'aws_security_token'):
-            connect_args['security_token'] = boto.config.get(profile, 'aws_security_token')
-        return connect_args
-
-    def connect_to_aws(self, module, region):
-        connect_args = {}
-
-        # only pass the profile name if it's set (as it is not supported by older boto versions)
-        if self.boto_profile:
-            connect_args['profile_name'] = self.boto_profile
-            self.boto_fix_security_token_in_profile(connect_args)
-
-        conn = module.connect_to_region(region, **connect_args)
-        # connect_to_region will fail "silently" by returning None if the region name is wrong or not supported
-        if conn is None:
-            self.fail_with_error("region name: %s likely not supported, or AWS is down.  connection to region failed." % region)
-        return conn
-
-    def get_instances_by_region(self, region):
-        ''' Makes an AWS EC2 API call to the list of instances in a particular
-        region '''
-
-        try:
-            conn = self.connect(region)
-            reservations = []
-            if self.ec2_instance_filters:
-                for filter_key, filter_values in self.ec2_instance_filters.items():
-                    reservations.extend(conn.get_all_instances(filters = { filter_key : filter_values }))
-            else:
-                reservations = conn.get_all_instances()
-
-            for reservation in reservations:
-                for instance in reservation.instances:
-                    self.add_instance(instance, region)
-
-        except boto.exception.BotoServerError as e:
-            if e.error_code == 'AuthFailure':
-                error = self.get_auth_error_message()
-            else:
-                backend = 'Eucalyptus' if self.eucalyptus else 'AWS'
-                error = "Error connecting to %s backend.\n%s" % (backend, e.message)
-            self.fail_with_error(error, 'getting EC2 instances')
-
-    def get_rds_instances_by_region(self, region):
-        ''' Makes an AWS API call to the list of RDS instances in a particular
-        region '''
-
-        try:
-            conn = self.connect_to_aws(rds, region)
-            if conn:
-                marker = None
-                while True:
-                    instances = conn.get_all_dbinstances(marker=marker)
-                    marker = instances.marker
-                    for instance in instances:
-                        self.add_rds_instance(instance, region)
-                    if not marker:
-                        break
-        except boto.exception.BotoServerError as e:
-            error = e.reason
-
-            if e.error_code == 'AuthFailure':
-                error = self.get_auth_error_message()
-            if not e.reason == "Forbidden":
-                error = "Looks like AWS RDS is down:\n%s" % e.message
-            self.fail_with_error(error, 'getting RDS instances')
-
-    def get_elasticache_clusters_by_region(self, region):
-        ''' Makes an AWS API call to the list of ElastiCache clusters (with
-        nodes' info) in a particular region.'''
-
-        # ElastiCache boto module doesn't provide a get_all_intances method,
-        # that's why we need to call describe directly (it would be called by
-        # the shorthand method anyway...)
-        try:
-            conn = self.connect_to_aws(elasticache, region)
-            if conn:
-                # show_cache_node_info = True
-                # because we also want nodes' information
-                response = conn.describe_cache_clusters(None, None, None, True)
-
-        except boto.exception.BotoServerError as e:
-            error = e.reason
-
-            if e.error_code == 'AuthFailure':
-                error = self.get_auth_error_message()
-            if not e.reason == "Forbidden":
-                error = "Looks like AWS ElastiCache is down:\n%s" % e.message
-            self.fail_with_error(error, 'getting ElastiCache clusters')
-
-        try:
-            # Boto also doesn't provide wrapper classes to CacheClusters or
-            # CacheNodes. Because of that wo can't make use of the get_list
-            # method in the AWSQueryConnection. Let's do the work manually
-            clusters = response['DescribeCacheClustersResponse']['DescribeCacheClustersResult']['CacheClusters']
-
-        except KeyError as e:
-            error = "ElastiCache query to AWS failed (unexpected format)."
-            self.fail_with_error(error, 'getting ElastiCache clusters')
-
-        for cluster in clusters:
-            self.add_elasticache_cluster(cluster, region)
-
-    def get_elasticache_replication_groups_by_region(self, region):
-        ''' Makes an AWS API call to the list of ElastiCache replication groups
-        in a particular region.'''
-
-        # ElastiCache boto module doesn't provide a get_all_intances method,
-        # that's why we need to call describe directly (it would be called by
-        # the shorthand method anyway...)
-        try:
-            conn = self.connect_to_aws(elasticache, region)
-            if conn:
-                response = conn.describe_replication_groups()
-
-        except boto.exception.BotoServerError as e:
-            error = e.reason
-
-            if e.error_code == 'AuthFailure':
-                error = self.get_auth_error_message()
-            if not e.reason == "Forbidden":
-                error = "Looks like AWS ElastiCache [Replication Groups] is down:\n%s" % e.message
-            self.fail_with_error(error, 'getting ElastiCache clusters')
-
-        try:
-            # Boto also doesn't provide wrapper classes to ReplicationGroups
-            # Because of that wo can't make use of the get_list method in the
-            # AWSQueryConnection. Let's do the work manually
-            replication_groups = response['DescribeReplicationGroupsResponse']['DescribeReplicationGroupsResult']['ReplicationGroups']
-
-        except KeyError as e:
-            error = "ElastiCache [Replication Groups] query to AWS failed (unexpected format)."
-            self.fail_with_error(error, 'getting ElastiCache clusters')
-
-        for replication_group in replication_groups:
-            self.add_elasticache_replication_group(replication_group, region)
-
-    def get_auth_error_message(self):
-        ''' create an informative error message if there is an issue authenticating'''
-        errors = ["Authentication error retrieving ec2 inventory."]
-        if None in [os.environ.get('AWS_ACCESS_KEY_ID'), os.environ.get('AWS_SECRET_ACCESS_KEY')]:
-            errors.append(' - No AWS_ACCESS_KEY_ID or AWS_SECRET_ACCESS_KEY environment vars found')
-        else:
-            errors.append(' - AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY environment vars found but may not be correct')
-
-        boto_paths = ['/etc/boto.cfg', '~/.boto', '~/.aws/credentials']
-        boto_config_found = list(p for p in boto_paths if os.path.isfile(os.path.expanduser(p)))
-        if len(boto_config_found) > 0:
-            errors.append(" - Boto configs found at '%s', but the credentials contained may not be correct" % ', '.join(boto_config_found))
-        else:
-            errors.append(" - No Boto config found at any expected location '%s'" % ', '.join(boto_paths))
-
-        return '\n'.join(errors)
-
-    def fail_with_error(self, err_msg, err_operation=None):
-        '''log an error to std err for ansible-playbook to consume and exit'''
-        if err_operation:
-            err_msg = 'ERROR: "{err_msg}", while: {err_operation}'.format(
-                err_msg=err_msg, err_operation=err_operation)
-        sys.stderr.write(err_msg)
-        sys.exit(1)
-
-    def get_instance(self, region, instance_id):
-        conn = self.connect(region)
-
-        reservations = conn.get_all_instances([instance_id])
-        for reservation in reservations:
-            for instance in reservation.instances:
-                return instance
-
-    def add_instance(self, instance, region):
-        ''' Adds an instance to the inventory and index, as long as it is
-        addressable '''
-
-        # Only return instances with desired instance states
-        if instance.state not in self.ec2_instance_states:
-            return
-
-        # Select the best destination address
-        if self.destination_format and self.destination_format_tags:
-            dest = self.destination_format.format(*[ getattr(instance, 'tags').get(tag, '') for tag in self.destination_format_tags ])
-        elif instance.subnet_id:
-            dest = getattr(instance, self.vpc_destination_variable, None)
-            if dest is None:
-                dest = getattr(instance, 'tags').get(self.vpc_destination_variable, None)
-        else:
-            dest = getattr(instance, self.destination_variable, None)
-            if dest is None:
-                dest = getattr(instance, 'tags').get(self.destination_variable, None)
-
-        if not dest:
-            # Skip instances we cannot address (e.g. private VPC subnet)
-            return
-
-        # Set the inventory name
-        hostname = None
-        if self.hostname_variable:
-            if self.hostname_variable.startswith('tag_'):
-                hostname = instance.tags.get(self.hostname_variable[4:], None)
-            else:
-                hostname = getattr(instance, self.hostname_variable)
-
-        # If we can't get a nice hostname, use the destination address
-        if not hostname:
-            hostname = dest
-        else:
-            hostname = self.to_safe(hostname).lower()
-
-        # if we only want to include hosts that match a pattern, skip those that don't
-        if self.pattern_include and not self.pattern_include.match(hostname):
-            return
-
-        # if we need to exclude hosts that match a pattern, skip those
-        if self.pattern_exclude and self.pattern_exclude.match(hostname):
-            return
-
-        # Add to index
-        self.index[hostname] = [region, instance.id]
-
-        # Inventory: Group by instance ID (always a group of 1)
-        if self.group_by_instance_id:
-            self.inventory[instance.id] = [hostname]
-            if self.nested_groups:
-                self.push_group(self.inventory, 'instances', instance.id)
-
-        # Inventory: Group by region
-        if self.group_by_region:
-            self.push(self.inventory, region, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'regions', region)
-
-        # Inventory: Group by availability zone
-        if self.group_by_availability_zone:
-            self.push(self.inventory, instance.placement, hostname)
-            if self.nested_groups:
-                if self.group_by_region:
-                    self.push_group(self.inventory, region, instance.placement)
-                self.push_group(self.inventory, 'zones', instance.placement)
-
-        # Inventory: Group by Amazon Machine Image (AMI) ID
-        if self.group_by_ami_id:
-            ami_id = self.to_safe(instance.image_id)
-            self.push(self.inventory, ami_id, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'images', ami_id)
-
-        # Inventory: Group by instance type
-        if self.group_by_instance_type:
-            type_name = self.to_safe('type_' + instance.instance_type)
-            self.push(self.inventory, type_name, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'types', type_name)
-
-        # Inventory: Group by key pair
-        if self.group_by_key_pair and instance.key_name:
-            key_name = self.to_safe('key_' + instance.key_name)
-            self.push(self.inventory, key_name, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'keys', key_name)
-
-        # Inventory: Group by VPC
-        if self.group_by_vpc_id and instance.vpc_id:
-            vpc_id_name = self.to_safe('vpc_id_' + instance.vpc_id)
-            self.push(self.inventory, vpc_id_name, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'vpcs', vpc_id_name)
-
-        # Inventory: Group by security group
-        if self.group_by_security_group:
-            try:
-                for group in instance.groups:
-                    key = self.to_safe("security_group_" + group.name)
-                    self.push(self.inventory, key, hostname)
-                    if self.nested_groups:
-                        self.push_group(self.inventory, 'security_groups', key)
-            except AttributeError:
-                self.fail_with_error('\n'.join(['Package boto seems a bit older.',
-                                                'Please upgrade boto >= 2.3.0.']))
-
-        # Inventory: Group by tag keys
-        if self.group_by_tag_keys:
-            for k, v in instance.tags.items():
-                if self.expand_csv_tags and v and ',' in v:
-                    values = map(lambda x: x.strip(), v.split(','))
-                else:
-                    values = [v]
-
-                for v in values:
-                    if v:
-                        key = self.to_safe("tag_" + k + "=" + v)
-                    else:
-                        key = self.to_safe("tag_" + k)
-                    self.push(self.inventory, key, hostname)
-                    if self.nested_groups:
-                        self.push_group(self.inventory, 'tags', self.to_safe("tag_" + k))
-                        if v:
-                            self.push_group(self.inventory, self.to_safe("tag_" + k), key)
-
-        # Inventory: Group by Route53 domain names if enabled
-        if self.route53_enabled and self.group_by_route53_names:
-            route53_names = self.get_instance_route53_names(instance)
-            for name in route53_names:
-                self.push(self.inventory, name, hostname)
-                if self.nested_groups:
-                    self.push_group(self.inventory, 'route53', name)
-
-        # Global Tag: instances without tags
-        if self.group_by_tag_none and len(instance.tags) == 0:
-            self.push(self.inventory, 'tag_none', hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'tags', 'tag_none')
-
-        # Global Tag: tag all EC2 instances
-        self.push(self.inventory, 'ec2', hostname)
-
-        self.inventory["_meta"]["hostvars"][hostname] = self.get_host_info_dict_from_instance(instance)
-        self.inventory["_meta"]["hostvars"][hostname]['ansible_ssh_host'] = dest
-
-
-    def add_rds_instance(self, instance, region):
-        ''' Adds an RDS instance to the inventory and index, as long as it is
-        addressable '''
-
-        # Only want available instances unless all_rds_instances is True
-        if not self.all_rds_instances and instance.status != 'available':
-            return
-
-        # Select the best destination address
-        dest = instance.endpoint[0]
-
-        if not dest:
-            # Skip instances we cannot address (e.g. private VPC subnet)
-            return
-
-        # Set the inventory name
-        hostname = None
-        if self.hostname_variable:
-            if self.hostname_variable.startswith('tag_'):
-                hostname = instance.tags.get(self.hostname_variable[4:], None)
-            else:
-                hostname = getattr(instance, self.hostname_variable)
-
-        # If we can't get a nice hostname, use the destination address
-        if not hostname:
-            hostname = dest
-
-        hostname = self.to_safe(hostname).lower()
-
-        # Add to index
-        self.index[hostname] = [region, instance.id]
-
-        # Inventory: Group by instance ID (always a group of 1)
-        if self.group_by_instance_id:
-            self.inventory[instance.id] = [hostname]
-            if self.nested_groups:
-                self.push_group(self.inventory, 'instances', instance.id)
-
-        # Inventory: Group by region
-        if self.group_by_region:
-            self.push(self.inventory, region, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'regions', region)
-
-        # Inventory: Group by availability zone
-        if self.group_by_availability_zone:
-            self.push(self.inventory, instance.availability_zone, hostname)
-            if self.nested_groups:
-                if self.group_by_region:
-                    self.push_group(self.inventory, region, instance.availability_zone)
-                self.push_group(self.inventory, 'zones', instance.availability_zone)
-
-        # Inventory: Group by instance type
-        if self.group_by_instance_type:
-            type_name = self.to_safe('type_' + instance.instance_class)
-            self.push(self.inventory, type_name, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'types', type_name)
-
-        # Inventory: Group by VPC
-        if self.group_by_vpc_id and instance.subnet_group and instance.subnet_group.vpc_id:
-            vpc_id_name = self.to_safe('vpc_id_' + instance.subnet_group.vpc_id)
-            self.push(self.inventory, vpc_id_name, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'vpcs', vpc_id_name)
-
-        # Inventory: Group by security group
-        if self.group_by_security_group:
-            try:
-                if instance.security_group:
-                    key = self.to_safe("security_group_" + instance.security_group.name)
-                    self.push(self.inventory, key, hostname)
-                    if self.nested_groups:
-                        self.push_group(self.inventory, 'security_groups', key)
-
-            except AttributeError:
-                self.fail_with_error('\n'.join(['Package boto seems a bit older.',
-                                                'Please upgrade boto >= 2.3.0.']))
-
-
-        # Inventory: Group by engine
-        if self.group_by_rds_engine:
-            self.push(self.inventory, self.to_safe("rds_" + instance.engine), hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'rds_engines', self.to_safe("rds_" + instance.engine))
-
-        # Inventory: Group by parameter group
-        if self.group_by_rds_parameter_group:
-            self.push(self.inventory, self.to_safe("rds_parameter_group_" + instance.parameter_group.name), hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'rds_parameter_groups', self.to_safe("rds_parameter_group_" + instance.parameter_group.name))
-
-        # Global Tag: all RDS instances
-        self.push(self.inventory, 'rds', hostname)
-
-        self.inventory["_meta"]["hostvars"][hostname] = self.get_host_info_dict_from_instance(instance)
-        self.inventory["_meta"]["hostvars"][hostname]['ansible_ssh_host'] = dest
-
-    def add_elasticache_cluster(self, cluster, region):
-        ''' Adds an ElastiCache cluster to the inventory and index, as long as
-        it's nodes are addressable '''
-
-        # Only want available clusters unless all_elasticache_clusters is True
-        if not self.all_elasticache_clusters and cluster['CacheClusterStatus'] != 'available':
-            return
-
-        # Select the best destination address
-        if 'ConfigurationEndpoint' in cluster and cluster['ConfigurationEndpoint']:
-            # Memcached cluster
-            dest = cluster['ConfigurationEndpoint']['Address']
-            is_redis = False
-        else:
-            # Redis sigle node cluster
-            # Because all Redis clusters are single nodes, we'll merge the
-            # info from the cluster with info about the node
-            dest = cluster['CacheNodes'][0]['Endpoint']['Address']
-            is_redis = True
-
-        if not dest:
-            # Skip clusters we cannot address (e.g. private VPC subnet)
-            return
-
-        # Add to index
-        self.index[dest] = [region, cluster['CacheClusterId']]
-
-        # Inventory: Group by instance ID (always a group of 1)
-        if self.group_by_instance_id:
-            self.inventory[cluster['CacheClusterId']] = [dest]
-            if self.nested_groups:
-                self.push_group(self.inventory, 'instances', cluster['CacheClusterId'])
-
-        # Inventory: Group by region
-        if self.group_by_region and not is_redis:
-            self.push(self.inventory, region, dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'regions', region)
-
-        # Inventory: Group by availability zone
-        if self.group_by_availability_zone and not is_redis:
-            self.push(self.inventory, cluster['PreferredAvailabilityZone'], dest)
-            if self.nested_groups:
-                if self.group_by_region:
-                    self.push_group(self.inventory, region, cluster['PreferredAvailabilityZone'])
-                self.push_group(self.inventory, 'zones', cluster['PreferredAvailabilityZone'])
-
-        # Inventory: Group by node type
-        if self.group_by_instance_type and not is_redis:
-            type_name = self.to_safe('type_' + cluster['CacheNodeType'])
-            self.push(self.inventory, type_name, dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'types', type_name)
-
-        # Inventory: Group by VPC (information not available in the current
-        # AWS API version for ElastiCache)
-
-        # Inventory: Group by security group
-        if self.group_by_security_group and not is_redis:
-
-            # Check for the existence of the 'SecurityGroups' key and also if
-            # this key has some value. When the cluster is not placed in a SG
-            # the query can return None here and cause an error.
-            if 'SecurityGroups' in cluster and cluster['SecurityGroups'] is not None:
-                for security_group in cluster['SecurityGroups']:
-                    key = self.to_safe("security_group_" + security_group['SecurityGroupId'])
-                    self.push(self.inventory, key, dest)
-                    if self.nested_groups:
-                        self.push_group(self.inventory, 'security_groups', key)
-
-        # Inventory: Group by engine
-        if self.group_by_elasticache_engine and not is_redis:
-            self.push(self.inventory, self.to_safe("elasticache_" + cluster['Engine']), dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'elasticache_engines', self.to_safe(cluster['Engine']))
-
-        # Inventory: Group by parameter group
-        if self.group_by_elasticache_parameter_group:
-            self.push(self.inventory, self.to_safe("elasticache_parameter_group_" + cluster['CacheParameterGroup']['CacheParameterGroupName']), dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'elasticache_parameter_groups', self.to_safe(cluster['CacheParameterGroup']['CacheParameterGroupName']))
-
-        # Inventory: Group by replication group
-        if self.group_by_elasticache_replication_group and 'ReplicationGroupId' in cluster and cluster['ReplicationGroupId']:
-            self.push(self.inventory, self.to_safe("elasticache_replication_group_" + cluster['ReplicationGroupId']), dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'elasticache_replication_groups', self.to_safe(cluster['ReplicationGroupId']))
-
-        # Global Tag: all ElastiCache clusters
-        self.push(self.inventory, 'elasticache_clusters', cluster['CacheClusterId'])
-
-        host_info = self.get_host_info_dict_from_describe_dict(cluster)
-
-        self.inventory["_meta"]["hostvars"][dest] = host_info
-
-        # Add the nodes
-        for node in cluster['CacheNodes']:
-            self.add_elasticache_node(node, cluster, region)
-
-    def add_elasticache_node(self, node, cluster, region):
-        ''' Adds an ElastiCache node to the inventory and index, as long as
-        it is addressable '''
-
-        # Only want available nodes unless all_elasticache_nodes is True
-        if not self.all_elasticache_nodes and node['CacheNodeStatus'] != 'available':
-            return
-
-        # Select the best destination address
-        dest = node['Endpoint']['Address']
-
-        if not dest:
-            # Skip nodes we cannot address (e.g. private VPC subnet)
-            return
-
-        node_id = self.to_safe(cluster['CacheClusterId'] + '_' + node['CacheNodeId'])
-
-        # Add to index
-        self.index[dest] = [region, node_id]
-
-        # Inventory: Group by node ID (always a group of 1)
-        if self.group_by_instance_id:
-            self.inventory[node_id] = [dest]
-            if self.nested_groups:
-                self.push_group(self.inventory, 'instances', node_id)
-
-        # Inventory: Group by region
-        if self.group_by_region:
-            self.push(self.inventory, region, dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'regions', region)
-
-        # Inventory: Group by availability zone
-        if self.group_by_availability_zone:
-            self.push(self.inventory, cluster['PreferredAvailabilityZone'], dest)
-            if self.nested_groups:
-                if self.group_by_region:
-                    self.push_group(self.inventory, region, cluster['PreferredAvailabilityZone'])
-                self.push_group(self.inventory, 'zones', cluster['PreferredAvailabilityZone'])
-
-        # Inventory: Group by node type
-        if self.group_by_instance_type:
-            type_name = self.to_safe('type_' + cluster['CacheNodeType'])
-            self.push(self.inventory, type_name, dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'types', type_name)
-
-        # Inventory: Group by VPC (information not available in the current
-        # AWS API version for ElastiCache)
-
-        # Inventory: Group by security group
-        if self.group_by_security_group:
-
-            # Check for the existence of the 'SecurityGroups' key and also if
-            # this key has some value. When the cluster is not placed in a SG
-            # the query can return None here and cause an error.
-            if 'SecurityGroups' in cluster and cluster['SecurityGroups'] is not None:
-                for security_group in cluster['SecurityGroups']:
-                    key = self.to_safe("security_group_" + security_group['SecurityGroupId'])
-                    self.push(self.inventory, key, dest)
-                    if self.nested_groups:
-                        self.push_group(self.inventory, 'security_groups', key)
-
-        # Inventory: Group by engine
-        if self.group_by_elasticache_engine:
-            self.push(self.inventory, self.to_safe("elasticache_" + cluster['Engine']), dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'elasticache_engines', self.to_safe("elasticache_" + cluster['Engine']))
-
-        # Inventory: Group by parameter group (done at cluster level)
-
-        # Inventory: Group by replication group (done at cluster level)
-
-        # Inventory: Group by ElastiCache Cluster
-        if self.group_by_elasticache_cluster:
-            self.push(self.inventory, self.to_safe("elasticache_cluster_" + cluster['CacheClusterId']), dest)
-
-        # Global Tag: all ElastiCache nodes
-        self.push(self.inventory, 'elasticache_nodes', dest)
-
-        host_info = self.get_host_info_dict_from_describe_dict(node)
-
-        if dest in self.inventory["_meta"]["hostvars"]:
-            self.inventory["_meta"]["hostvars"][dest].update(host_info)
-        else:
-            self.inventory["_meta"]["hostvars"][dest] = host_info
-
-    def add_elasticache_replication_group(self, replication_group, region):
-        ''' Adds an ElastiCache replication group to the inventory and index '''
-
-        # Only want available clusters unless all_elasticache_replication_groups is True
-        if not self.all_elasticache_replication_groups and replication_group['Status'] != 'available':
-            return
-
-        # Select the best destination address (PrimaryEndpoint)
-        dest = replication_group['NodeGroups'][0]['PrimaryEndpoint']['Address']
-
-        if not dest:
-            # Skip clusters we cannot address (e.g. private VPC subnet)
-            return
-
-        # Add to index
-        self.index[dest] = [region, replication_group['ReplicationGroupId']]
-
-        # Inventory: Group by ID (always a group of 1)
-        if self.group_by_instance_id:
-            self.inventory[replication_group['ReplicationGroupId']] = [dest]
-            if self.nested_groups:
-                self.push_group(self.inventory, 'instances', replication_group['ReplicationGroupId'])
-
-        # Inventory: Group by region
-        if self.group_by_region:
-            self.push(self.inventory, region, dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'regions', region)
-
-        # Inventory: Group by availability zone (doesn't apply to replication groups)
-
-        # Inventory: Group by node type (doesn't apply to replication groups)
-
-        # Inventory: Group by VPC (information not available in the current
-        # AWS API version for replication groups
-
-        # Inventory: Group by security group (doesn't apply to replication groups)
-        # Check this value in cluster level
-
-        # Inventory: Group by engine (replication groups are always Redis)
-        if self.group_by_elasticache_engine:
-            self.push(self.inventory, 'elasticache_redis', dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'elasticache_engines', 'redis')
-
-        # Global Tag: all ElastiCache clusters
-        self.push(self.inventory, 'elasticache_replication_groups', replication_group['ReplicationGroupId'])
-
-        host_info = self.get_host_info_dict_from_describe_dict(replication_group)
-
-        self.inventory["_meta"]["hostvars"][dest] = host_info
-
-    def get_route53_records(self):
-        ''' Get and store the map of resource records to domain names that
-        point to them. '''
-
-        r53_conn = route53.Route53Connection()
-        all_zones = r53_conn.get_zones()
-
-        route53_zones = [ zone for zone in all_zones if zone.name[:-1]
-                          not in self.route53_excluded_zones ]
-
-        self.route53_records = {}
-
-        for zone in route53_zones:
-            rrsets = r53_conn.get_all_rrsets(zone.id)
-
-            for record_set in rrsets:
-                record_name = record_set.name
-
-                if record_name.endswith('.'):
-                    record_name = record_name[:-1]
-
-                for resource in record_set.resource_records:
-                    self.route53_records.setdefault(resource, set())
-                    self.route53_records[resource].add(record_name)
-
-
-    def get_instance_route53_names(self, instance):
-        ''' Check if an instance is referenced in the records we have from
-        Route53. If it is, return the list of domain names pointing to said
-        instance. If nothing points to it, return an empty list. '''
-
-        instance_attributes = [ 'public_dns_name', 'private_dns_name',
-                                'ip_address', 'private_ip_address' ]
-
-        name_list = set()
-
-        for attrib in instance_attributes:
-            try:
-                value = getattr(instance, attrib)
-            except AttributeError:
-                continue
-
-            if value in self.route53_records:
-                name_list.update(self.route53_records[value])
-
-        return list(name_list)
-
-    def get_host_info_dict_from_instance(self, instance):
-        instance_vars = {}
-        for key in vars(instance):
-            value = getattr(instance, key)
-            key = self.to_safe('ec2_' + key)
-
-            # Handle complex types
-            # state/previous_state changed to properties in boto in https://github.com/boto/boto/commit/a23c379837f698212252720d2af8dec0325c9518
-            if key == 'ec2__state':
-                instance_vars['ec2_state'] = instance.state or ''
-                instance_vars['ec2_state_code'] = instance.state_code
-            elif key == 'ec2__previous_state':
-                instance_vars['ec2_previous_state'] = instance.previous_state or ''
-                instance_vars['ec2_previous_state_code'] = instance.previous_state_code
-            elif type(value) in [int, bool]:
-                instance_vars[key] = value
-            elif isinstance(value, six.string_types):
-                instance_vars[key] = value.strip()
-            elif type(value) == type(None):
-                instance_vars[key] = ''
-            elif key == 'ec2_region':
-                instance_vars[key] = value.name
-            elif key == 'ec2__placement':
-                instance_vars['ec2_placement'] = value.zone
-            elif key == 'ec2_tags':
-                for k, v in value.items():
-                    if self.expand_csv_tags and ',' in v:
-                        v = map(lambda x: x.strip(), v.split(','))
-                    key = self.to_safe('ec2_tag_' + k)
-                    instance_vars[key] = v
-            elif key == 'ec2_groups':
-                group_ids = []
-                group_names = []
-                for group in value:
-                    group_ids.append(group.id)
-                    group_names.append(group.name)
-                instance_vars["ec2_security_group_ids"] = ','.join([str(i) for i in group_ids])
-                instance_vars["ec2_security_group_names"] = ','.join([str(i) for i in group_names])
-            else:
-                pass
-                # TODO Product codes if someone finds them useful
-                #print key
-                #print type(value)
-                #print value
-
-        return instance_vars
-
-    def get_host_info_dict_from_describe_dict(self, describe_dict):
-        ''' Parses the dictionary returned by the API call into a flat list
-            of parameters. This method should be used only when 'describe' is
-            used directly because Boto doesn't provide specific classes. '''
-
-        # I really don't agree with prefixing everything with 'ec2'
-        # because EC2, RDS and ElastiCache are different services.
-        # I'm just following the pattern used until now to not break any
-        # compatibility.
-
-        host_info = {}
-        for key in describe_dict:
-            value = describe_dict[key]
-            key = self.to_safe('ec2_' + self.uncammelize(key))
-
-            # Handle complex types
-
-            # Target: Memcached Cache Clusters
-            if key == 'ec2_configuration_endpoint' and value:
-                host_info['ec2_configuration_endpoint_address'] = value['Address']
-                host_info['ec2_configuration_endpoint_port'] = value['Port']
-
-            # Target: Cache Nodes and Redis Cache Clusters (single node)
-            if key == 'ec2_endpoint' and value:
-                host_info['ec2_endpoint_address'] = value['Address']
-                host_info['ec2_endpoint_port'] = value['Port']
-
-            # Target: Redis Replication Groups
-            if key == 'ec2_node_groups' and value:
-                host_info['ec2_endpoint_address'] = value[0]['PrimaryEndpoint']['Address']
-                host_info['ec2_endpoint_port'] = value[0]['PrimaryEndpoint']['Port']
-                replica_count = 0
-                for node in value[0]['NodeGroupMembers']:
-                    if node['CurrentRole'] == 'primary':
-                        host_info['ec2_primary_cluster_address'] = node['ReadEndpoint']['Address']
-                        host_info['ec2_primary_cluster_port'] = node['ReadEndpoint']['Port']
-                        host_info['ec2_primary_cluster_id'] = node['CacheClusterId']
-                    elif node['CurrentRole'] == 'replica':
-                        host_info['ec2_replica_cluster_address_'+ str(replica_count)] = node['ReadEndpoint']['Address']
-                        host_info['ec2_replica_cluster_port_'+ str(replica_count)] = node['ReadEndpoint']['Port']
-                        host_info['ec2_replica_cluster_id_'+ str(replica_count)] = node['CacheClusterId']
-                        replica_count += 1
-
-            # Target: Redis Replication Groups
-            if key == 'ec2_member_clusters' and value:
-                host_info['ec2_member_clusters'] = ','.join([str(i) for i in value])
-
-            # Target: All Cache Clusters
-            elif key == 'ec2_cache_parameter_group':
-                host_info["ec2_cache_node_ids_to_reboot"] = ','.join([str(i) for i in value['CacheNodeIdsToReboot']])
-                host_info['ec2_cache_parameter_group_name'] = value['CacheParameterGroupName']
-                host_info['ec2_cache_parameter_apply_status'] = value['ParameterApplyStatus']
-
-            # Target: Almost everything
-            elif key == 'ec2_security_groups':
-
-                # Skip if SecurityGroups is None
-                # (it is possible to have the key defined but no value in it).
-                if value is not None:
-                    sg_ids = []
-                    for sg in value:
-                        sg_ids.append(sg['SecurityGroupId'])
-                    host_info["ec2_security_group_ids"] = ','.join([str(i) for i in sg_ids])
-
-            # Target: Everything
-            # Preserve booleans and integers
-            elif type(value) in [int, bool]:
-                host_info[key] = value
-
-            # Target: Everything
-            # Sanitize string values
-            elif isinstance(value, six.string_types):
-                host_info[key] = value.strip()
-
-            # Target: Everything
-            # Replace None by an empty string
-            elif type(value) == type(None):
-                host_info[key] = ''
-
-            else:
-                # Remove non-processed complex types
-                pass
-
-        return host_info
-
-    def get_host_info(self):
-        ''' Get variables about a specific host '''
-
-        if len(self.index) == 0:
-            # Need to load index from cache
-            self.load_index_from_cache()
-
-        if not self.args.host in self.index:
-            # try updating the cache
-            self.do_api_calls_update_cache()
-            if not self.args.host in self.index:
-                # host might not exist anymore
-                return self.json_format_dict({}, True)
-
-        (region, instance_id) = self.index[self.args.host]
-
-        instance = self.get_instance(region, instance_id)
-        return self.json_format_dict(self.get_host_info_dict_from_instance(instance), True)
-
-    def push(self, my_dict, key, element):
-        ''' Push an element onto an array that may not have been defined in
-        the dict '''
-        group_info = my_dict.setdefault(key, [])
-        if isinstance(group_info, dict):
-            host_list = group_info.setdefault('hosts', [])
-            host_list.append(element)
-        else:
-            group_info.append(element)
-
-    def push_group(self, my_dict, key, element):
-        ''' Push a group as a child of another group. '''
-        parent_group = my_dict.setdefault(key, {})
-        if not isinstance(parent_group, dict):
-            parent_group = my_dict[key] = {'hosts': parent_group}
-        child_groups = parent_group.setdefault('children', [])
-        if element not in child_groups:
-            child_groups.append(element)
-
-    def get_inventory_from_cache(self):
-        ''' Reads the inventory from the cache file and returns it as a JSON
-        object '''
-
-        cache = open(self.cache_path_cache, 'r')
-        json_inventory = cache.read()
-        return json_inventory
-
-
-    def load_index_from_cache(self):
-        ''' Reads the index from the cache file sets self.index '''
-
-        cache = open(self.cache_path_index, 'r')
-        json_index = cache.read()
-        self.index = json.loads(json_index)
-
-
-    def write_to_cache(self, data, filename):
-        ''' Writes data in JSON format to a file '''
-
-        json_data = self.json_format_dict(data, True)
-        cache = open(filename, 'w')
-        cache.write(json_data)
-        cache.close()
-
-    def uncammelize(self, key):
-        temp = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', key)
-        return re.sub('([a-z0-9])([A-Z])', r'\1_\2', temp).lower()
-
-    def to_safe(self, word):
-        ''' Converts 'bad' characters in a string to underscores so they can be used as Ansible groups '''
-        regex = "[^A-Za-z0-9\_"
-        if not self.replace_dash_in_groups:
-            regex += "\-"
-        return re.sub(regex + "]", "_", word)
-
-    def json_format_dict(self, data, pretty=False):
-        ''' Converts a dict to a JSON object and dumps it as a formatted
-        string '''
-
-        if pretty:
-            return json.dumps(data, sort_keys=True, indent=2)
-        else:
-            return json.dumps(data)
-
-
-# Run the script
-Ec2Inventory()
diff --git a/edge-1601-dc1/inventory b/edge-1601-dc1/inventory
deleted file mode 100644
index a26a6fe..0000000
--- a/edge-1601-dc1/inventory
+++ /dev/null
@@ -1,74 +0,0 @@
-[tag_Name_dc1_n1]
-[tag_Name_dc1_n2]
-[tag_Name_dc1_n3]
-[tag_Name_dc1_n4]
-[tag_Name_dc1_n5]
-
-[planet:children]
-dc-1
-
-[dc-1:children]
-tag_Name_dc1_n1
-tag_Name_dc1_n2
-tag_Name_dc1_n3
-tag_Name_dc1_n4
-tag_Name_dc1_n5
-
-[ds:children]
-dc-1-ds
-
-[dc-1-ds:children]
-tag_Name_dc1_n1
-tag_Name_dc1_n2
-tag_Name_dc1_n3
-
-[ms:children]
-dc-1-ms
-
-[dc-1-ms:children]
-tag_Name_dc1_n1
-
-[ui:children]
-dc-1-ui
-
-[dc-1-ui:children]
-tag_Name_dc1_n1
-
-[ldap:children]
-dc-1-ldap
-
-[dc-1-ldap:children]
-tag_Name_dc1_n1
-
-[rmp:children]
-dc-1-rmp
-
-[dc-1-rmp:children]
-tag_Name_dc1_n2
-tag_Name_dc1_n3
-
-[qpid:children]
-dc-1-qpid
-
-[dc-1-qpid:children]
-tag_Name_dc1_n4
-tag_Name_dc1_n5
-
-[pg:children]
-dc-1-pg
-
-[dc-1-pg:children]
-dc-1-pgmaster
-dc-1-pgstandby
-
-[pgmaster:children]
-dc-1-pgmaster
-
-[dc-1-pgmaster:children]
-tag_Name_dc1_n4
-
-[pgstandby:children]
-dc-1-pgstandby
-
-[dc-1-pgstandby:children]
-tag_Name_dc1_n5
diff --git a/edge-1601-dc2-dc3/ec2.ini b/edge-1601-dc2-dc3/ec2.ini
deleted file mode 100644
index 36b3921..0000000
--- a/edge-1601-dc2-dc3/ec2.ini
+++ /dev/null
@@ -1,200 +0,0 @@
-# Ansible EC2 external inventory script settings
-#
-
-[ec2]
-
-# to talk to a private eucalyptus instance uncomment these lines
-# and edit edit eucalyptus_host to be the host name of your cloud controller
-#eucalyptus = True
-#eucalyptus_host = clc.cloud.domain.org
-
-# AWS regions to make calls to. Set this to 'all' to make request to all regions
-# in AWS and merge the results together. Alternatively, set this to a comma
-# separated list of regions. E.g. 'us-east-1,us-west-1,us-west-2'
-regions = all
-regions_exclude = us-gov-west-1,cn-north-1
-
-# When generating inventory, Ansible needs to know how to address a server.
-# Each EC2 instance has a lot of variables associated with it. Here is the list:
-#   http://docs.pythonboto.org/en/latest/ref/ec2.html#module-boto.ec2.instance
-# Below are 2 variables that are used as the address of a server:
-#   - destination_variable
-#   - vpc_destination_variable
-
-# This is the normal destination variable to use. If you are running Ansible
-# from outside EC2, then 'public_dns_name' makes the most sense. If you are
-# running Ansible from within EC2, then perhaps you want to use the internal
-# address, and should set this to 'private_dns_name'. The key of an EC2 tag
-# may optionally be used; however the boto instance variables hold precedence
-# in the event of a collision.
-destination_variable = public_dns_name
-
-# This allows you to override the inventory_name with an ec2 variable, instead
-# of using the destination_variable above. Addressing (aka ansible_ssh_host)
-# will still use destination_variable. Tags should be written as 'tag_TAGNAME'.
-#hostname_variable = tag_Name
-
-# For server inside a VPC, using DNS names may not make sense. When an instance
-# has 'subnet_id' set, this variable is used. If the subnet is public, setting
-# this to 'ip_address' will return the public IP address. For instances in a
-# private subnet, this should be set to 'private_ip_address', and Ansible must
-# be run from within EC2. The key of an EC2 tag may optionally be used; however
-# the boto instance variables hold precedence in the event of a collision.
-# WARNING: - instances that are in the private vpc, _without_ public ip address
-# will not be listed in the inventory until You set:
-# vpc_destination_variable = private_ip_address
-vpc_destination_variable = ip_address
-
-# The following two settings allow flexible ansible host naming based on a
-# python format string and a comma-separated list of ec2 tags.  Note that:
-#
-# 1) If the tags referenced are not present for some instances, empty strings
-#    will be substituted in the format string.
-# 2) This overrides both destination_variable and vpc_destination_variable.
-#
-#destination_format = {0}.{1}.example.com
-#destination_format_tags = Name,environment
-
-# To tag instances on EC2 with the resource records that point to them from
-# Route53, uncomment and set 'route53' to True.
-route53 = False
-
-# To exclude RDS instances from the inventory, uncomment and set to False.
-rds = False
-
-# To exclude ElastiCache instances from the inventory, uncomment and set to False.
-elasticache = False
-
-# Additionally, you can specify the list of zones to exclude looking up in
-# 'route53_excluded_zones' as a comma-separated list.
-# route53_excluded_zones = samplezone1.com, samplezone2.com
-
-# By default, only EC2 instances in the 'running' state are returned. Set
-# 'all_instances' to True to return all instances regardless of state.
-all_instances = True
-
-# By default, only EC2 instances in the 'running' state are returned. Specify
-# EC2 instance states to return as a comma-separated list. This
-# option is overriden when 'all_instances' is True.
-# instance_states = pending, running, shutting-down, terminated, stopping, stopped
-
-# By default, only RDS instances in the 'available' state are returned.  Set
-# 'all_rds_instances' to True return all RDS instances regardless of state.
-all_rds_instances = False
-
-# By default, only ElastiCache clusters and nodes in the 'available' state
-# are returned. Set 'all_elasticache_clusters' and/or 'all_elastic_nodes'
-# to True return all ElastiCache clusters and nodes, regardless of state.
-#
-# Note that all_elasticache_nodes only applies to listed clusters. That means
-# if you set all_elastic_clusters to false, no node will be return from
-# unavailable clusters, regardless of the state and to what you set for
-# all_elasticache_nodes.
-all_elasticache_replication_groups = False
-all_elasticache_clusters = False
-all_elasticache_nodes = False
-
-# API calls to EC2 are slow. For this reason, we cache the results of an API
-# call. Set this to the path you want cache files to be written to. Two files
-# will be written to this directory:
-#   - ansible-ec2.cache
-#   - ansible-ec2.index
-cache_path = ~/.ansible/tmp
-
-# The number of seconds a cache file is considered valid. After this many
-# seconds, a new API call will be made, and the cache file will be updated.
-# To disable the cache, set this value to 0
-cache_max_age = 300
-
-# Organize groups into a nested/hierarchy instead of a flat namespace.
-nested_groups = False
-
-# Replace - tags when creating groups to avoid issues with ansible
-replace_dash_in_groups = True
-
-# If set to true, any tag of the form "a,b,c" is expanded into a list
-# and the results are used to create additional tag_* inventory groups.
-expand_csv_tags = False
-
-# The EC2 inventory output can become very large. To manage its size,
-# configure which groups should be created.
-group_by_instance_id = True
-group_by_region = True
-group_by_availability_zone = True
-group_by_ami_id = True
-group_by_instance_type = True
-group_by_key_pair = True
-group_by_vpc_id = True
-group_by_security_group = True
-group_by_tag_keys = True
-group_by_tag_none = True
-group_by_route53_names = True
-group_by_rds_engine = False
-group_by_rds_parameter_group = False
-group_by_elasticache_engine = True
-group_by_elasticache_cluster = True
-group_by_elasticache_parameter_group = True
-group_by_elasticache_replication_group = True
-
-# If you only want to include hosts that match a certain regular expression
-# pattern_include = staging-*
-
-# If you want to exclude any hosts that match a certain regular expression
-# pattern_exclude = staging-*
-# Ansible EC2 external inventory script settings
-#
-
-##[ec2]
-##
-### to talk to a private eucalyptus instance uncomment these lines
-### and edit edit eucalyptus_host to be the host name of your cloud controller
-###eucalyptus = True
-###eucalyptus_host = clc.cloud.domain.org
-##
-### AWS regions to make calls to. Set this to 'all' to make request to all regions
-##
-### in AWS and merge the results together. Alternatively, set this to a comma
-### separated list of regions. E.g. 'us-east-1,us-west-1,us-west-2'
-##regions = all
-##regions_exclude = us-gov-west-1,cn-north-1
-##
-### When generating inventory, Ansible needs to know how to address a server.
-### Each EC2 instance has a lot of variables associated with it. Here is the list:
-###   http://docs.pythonboto.org/en/latest/ref/ec2.html#module-boto.ec2.instance
-### Below are 2 variables that are used as the address of a server:
-###   - destination_variable
-###   - vpc_destination_variable
-##
-### This is the normal destination variable to use. If you are running Ansible
-### from outside EC2, then 'public_dns_name' makes the most sense. If you are
-### running Ansible from within EC2, then perhaps you want to use the internal
-### address, and should set this to 'private_dns_name'. The key of an EC2 tag
-##...skipping...
-### pattern_include = staging-*
-##
-### If you want to exclude any hosts that match a certain regular expression
-### pattern_exclude = staging-*
-
-# Instance filters can be used to control which instances are retrieved for
-# inventory. For the full list of possible filters, please read the EC2 API
-# docs: http://docs.aws.amazon.com/AWSEC2/latest/APIReference/ApiReference-query-DescribeInstances.html#query-DescribeInstances-filters
-# Filters are key/value pairs separated by '=', to list multiple filters use
-# a list separated by commas. See examples below.
-
-# Retrieve only instances with (key=value) env=staging tag
-# instance_filters = tag:env=staging
-
-# Retrieve only instances with role=webservers OR role=dbservers tag
-# instance_filters = tag:role=webservers,tag:role=dbservers
-
-# Retrieve only t1.micro instances OR instances with tag env=staging
-# instance_filters = instance-type=t1.micro,tag:env=staging
-
-# You can use wildcards in filter values also. Below will list instances which
-# tag Name value matches webservers1*
-# (ex. webservers15, webservers1a, webservers123 etc)
-# instance_filters = tag:Name=webservers1*
-
-# A boto configuration profile may be used to separate out credentials
-# see http://boto.readthedocs.org/en/latest/boto_config_tut.html
-# boto_profile = some-boto-profile-name
diff --git a/edge-1601-dc2-dc3/ec2.py b/edge-1601-dc2-dc3/ec2.py
deleted file mode 100755
index f30958a..0000000
--- a/edge-1601-dc2-dc3/ec2.py
+++ /dev/null
@@ -1,1385 +0,0 @@
-#!/usr/bin/env python
-
-'''
-EC2 external inventory script
-=================================
-
-Generates inventory that Ansible can understand by making API request to
-AWS EC2 using the Boto library.
-
-NOTE: This script assumes Ansible is being executed where the environment
-variables needed for Boto have already been set:
-    export AWS_ACCESS_KEY_ID='AK123'
-    export AWS_SECRET_ACCESS_KEY='abc123'
-
-This script also assumes there is an ec2.ini file alongside it.  To specify a
-different path to ec2.ini, define the EC2_INI_PATH environment variable:
-
-    export EC2_INI_PATH=/path/to/my_ec2.ini
-
-If you're using eucalyptus you need to set the above variables and
-you need to define:
-
-    export EC2_URL=http://hostname_of_your_cc:port/services/Eucalyptus
-
-If you're using boto profiles (requires boto>=2.24.0) you can choose a profile
-using the --boto-profile command line argument (e.g. ec2.py --boto-profile prod) or using
-the AWS_PROFILE variable:
-
-    AWS_PROFILE=prod ansible-playbook -i ec2.py myplaybook.yml
-
-For more details, see: http://docs.pythonboto.org/en/latest/boto_config_tut.html
-
-When run against a specific host, this script returns the following variables:
- - ec2_ami_launch_index
- - ec2_architecture
- - ec2_association
- - ec2_attachTime
- - ec2_attachment
- - ec2_attachmentId
- - ec2_client_token
- - ec2_deleteOnTermination
- - ec2_description
- - ec2_deviceIndex
- - ec2_dns_name
- - ec2_eventsSet
- - ec2_group_name
- - ec2_hypervisor
- - ec2_id
- - ec2_image_id
- - ec2_instanceState
- - ec2_instance_type
- - ec2_ipOwnerId
- - ec2_ip_address
- - ec2_item
- - ec2_kernel
- - ec2_key_name
- - ec2_launch_time
- - ec2_monitored
- - ec2_monitoring
- - ec2_networkInterfaceId
- - ec2_ownerId
- - ec2_persistent
- - ec2_placement
- - ec2_platform
- - ec2_previous_state
- - ec2_private_dns_name
- - ec2_private_ip_address
- - ec2_publicIp
- - ec2_public_dns_name
- - ec2_ramdisk
- - ec2_reason
- - ec2_region
- - ec2_requester_id
- - ec2_root_device_name
- - ec2_root_device_type
- - ec2_security_group_ids
- - ec2_security_group_names
- - ec2_shutdown_state
- - ec2_sourceDestCheck
- - ec2_spot_instance_request_id
- - ec2_state
- - ec2_state_code
- - ec2_state_reason
- - ec2_status
- - ec2_subnet_id
- - ec2_tenancy
- - ec2_virtualization_type
- - ec2_vpc_id
-
-These variables are pulled out of a boto.ec2.instance object. There is a lack of
-consistency with variable spellings (camelCase and underscores) since this
-just loops through all variables the object exposes. It is preferred to use the
-ones with underscores when multiple exist.
-
-In addition, if an instance has AWS Tags associated with it, each tag is a new
-variable named:
- - ec2_tag_[Key] = [Value]
-
-Security groups are comma-separated in 'ec2_security_group_ids' and
-'ec2_security_group_names'.
-'''
-
-# (c) 2012, Peter Sankauskas
-#
-# This file is part of Ansible,
-#
-# Ansible is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# Ansible is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with Ansible.  If not, see <http://www.gnu.org/licenses/>.
-
-######################################################################
-
-import sys
-import os
-import argparse
-import re
-from time import time
-import boto
-from boto import ec2
-from boto import rds
-from boto import elasticache
-from boto import route53
-import six
-
-from six.moves import configparser
-from collections import defaultdict
-
-try:
-    import json
-except ImportError:
-    import simplejson as json
-
-
-class Ec2Inventory(object):
-
-    def _empty_inventory(self):
-        return {"_meta" : {"hostvars" : {}}}
-
-    def __init__(self):
-        ''' Main execution path '''
-
-        # Inventory grouped by instance IDs, tags, security groups, regions,
-        # and availability zones
-        self.inventory = self._empty_inventory()
-
-        # Index of hostname (address) to instance ID
-        self.index = {}
-
-        # Boto profile to use (if any)
-        self.boto_profile = None
-
-        # Read settings and parse CLI arguments
-        self.parse_cli_args()
-        self.read_settings()
-
-        # Make sure that profile_name is not passed at all if not set
-        # as pre 2.24 boto will fall over otherwise
-        if self.boto_profile:
-            if not hasattr(boto.ec2.EC2Connection, 'profile_name'):
-                self.fail_with_error("boto version must be >= 2.24 to use profile")
-
-        # Cache
-        if self.args.refresh_cache:
-            self.do_api_calls_update_cache()
-        elif not self.is_cache_valid():
-            self.do_api_calls_update_cache()
-
-        # Data to print
-        if self.args.host:
-            data_to_print = self.get_host_info()
-
-        elif self.args.list:
-            # Display list of instances for inventory
-            if self.inventory == self._empty_inventory():
-                data_to_print = self.get_inventory_from_cache()
-            else:
-                data_to_print = self.json_format_dict(self.inventory, True)
-
-        print(data_to_print)
-
-
-    def is_cache_valid(self):
-        ''' Determines if the cache files have expired, or if it is still valid '''
-
-        if os.path.isfile(self.cache_path_cache):
-            mod_time = os.path.getmtime(self.cache_path_cache)
-            current_time = time()
-            if (mod_time + self.cache_max_age) > current_time:
-                if os.path.isfile(self.cache_path_index):
-                    return True
-
-        return False
-
-
-    def read_settings(self):
-        ''' Reads the settings from the ec2.ini file '''
-        if six.PY3:
-            config = configparser.ConfigParser()
-        else:
-            config = configparser.SafeConfigParser()
-        ec2_default_ini_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'ec2.ini')
-        ec2_ini_path = os.path.expanduser(os.path.expandvars(os.environ.get('EC2_INI_PATH', ec2_default_ini_path)))
-        config.read(ec2_ini_path)
-
-        # is eucalyptus?
-        self.eucalyptus_host = None
-        self.eucalyptus = False
-        if config.has_option('ec2', 'eucalyptus'):
-            self.eucalyptus = config.getboolean('ec2', 'eucalyptus')
-        if self.eucalyptus and config.has_option('ec2', 'eucalyptus_host'):
-            self.eucalyptus_host = config.get('ec2', 'eucalyptus_host')
-
-        # Regions
-        self.regions = []
-        configRegions = config.get('ec2', 'regions')
-        configRegions_exclude = config.get('ec2', 'regions_exclude')
-        if (configRegions == 'all'):
-            if self.eucalyptus_host:
-                self.regions.append(boto.connect_euca(host=self.eucalyptus_host).region.name)
-            else:
-                for regionInfo in ec2.regions():
-                    if regionInfo.name not in configRegions_exclude:
-                        self.regions.append(regionInfo.name)
-        else:
-            self.regions = configRegions.split(",")
-
-        # Destination addresses
-        self.destination_variable = config.get('ec2', 'destination_variable')
-        self.vpc_destination_variable = config.get('ec2', 'vpc_destination_variable')
-
-        if config.has_option('ec2', 'hostname_variable'):
-            self.hostname_variable = config.get('ec2', 'hostname_variable')
-        else:
-            self.hostname_variable = None
-
-        if config.has_option('ec2', 'destination_format') and \
-                config.has_option('ec2', 'destination_format_tags'):
-            self.destination_format = config.get('ec2', 'destination_format')
-            self.destination_format_tags = config.get('ec2', 'destination_format_tags').split(',')
-        else:
-            self.destination_format = None
-            self.destination_format_tags = None
-
-        # Route53
-        self.route53_enabled = config.getboolean('ec2', 'route53')
-        self.route53_excluded_zones = []
-        if config.has_option('ec2', 'route53_excluded_zones'):
-            self.route53_excluded_zones.extend(
-                    config.get('ec2', 'route53_excluded_zones', '').split(','))
-
-        # Include RDS instances?
-        self.rds_enabled = True
-        if config.has_option('ec2', 'rds'):
-            self.rds_enabled = config.getboolean('ec2', 'rds')
-
-        # Include ElastiCache instances?
-        self.elasticache_enabled = True
-        if config.has_option('ec2', 'elasticache'):
-            self.elasticache_enabled = config.getboolean('ec2', 'elasticache')
-
-        # Return all EC2 instances?
-        if config.has_option('ec2', 'all_instances'):
-            self.all_instances = config.getboolean('ec2', 'all_instances')
-        else:
-            self.all_instances = False
-
-        # Instance states to be gathered in inventory. Default is 'running'.
-        # Setting 'all_instances' to 'yes' overrides this option.
-        ec2_valid_instance_states = [
-            'pending',
-            'running',
-            'shutting-down',
-            'terminated',
-            'stopping',
-            'stopped'
-        ]
-        self.ec2_instance_states = []
-        if self.all_instances:
-            self.ec2_instance_states = ec2_valid_instance_states
-        elif config.has_option('ec2', 'instance_states'):
-            for instance_state in config.get('ec2', 'instance_states').split(','):
-                instance_state = instance_state.strip()
-                if instance_state not in ec2_valid_instance_states:
-                    continue
-                self.ec2_instance_states.append(instance_state)
-        else:
-            self.ec2_instance_states = ['running']
-
-        # Return all RDS instances? (if RDS is enabled)
-        if config.has_option('ec2', 'all_rds_instances') and self.rds_enabled:
-            self.all_rds_instances = config.getboolean('ec2', 'all_rds_instances')
-        else:
-            self.all_rds_instances = False
-
-        # Return all ElastiCache replication groups? (if ElastiCache is enabled)
-        if config.has_option('ec2', 'all_elasticache_replication_groups') and self.elasticache_enabled:
-            self.all_elasticache_replication_groups = config.getboolean('ec2', 'all_elasticache_replication_groups')
-        else:
-            self.all_elasticache_replication_groups = False
-
-        # Return all ElastiCache clusters? (if ElastiCache is enabled)
-        if config.has_option('ec2', 'all_elasticache_clusters') and self.elasticache_enabled:
-            self.all_elasticache_clusters = config.getboolean('ec2', 'all_elasticache_clusters')
-        else:
-            self.all_elasticache_clusters = False
-
-        # Return all ElastiCache nodes? (if ElastiCache is enabled)
-        if config.has_option('ec2', 'all_elasticache_nodes') and self.elasticache_enabled:
-            self.all_elasticache_nodes = config.getboolean('ec2', 'all_elasticache_nodes')
-        else:
-            self.all_elasticache_nodes = False
-
-        # boto configuration profile (prefer CLI argument)
-        self.boto_profile = self.args.boto_profile
-        if config.has_option('ec2', 'boto_profile') and not self.boto_profile:
-            self.boto_profile = config.get('ec2', 'boto_profile')
-
-        # Cache related
-        cache_dir = os.path.expanduser(config.get('ec2', 'cache_path'))
-        if self.boto_profile:
-            cache_dir = os.path.join(cache_dir, 'profile_' + self.boto_profile)
-        if not os.path.exists(cache_dir):
-            os.makedirs(cache_dir)
-
-        cache_name = 'ansible-ec2'
-        aws_profile = lambda: (self.boto_profile or
-                               os.environ.get('AWS_PROFILE') or
-                               os.environ.get('AWS_ACCESS_KEY_ID'))
-        if aws_profile():
-            cache_name = '%s-%s' % (cache_name, aws_profile())
-        self.cache_path_cache = cache_dir + "/%s.cache" % cache_name
-        self.cache_path_index = cache_dir + "/%s.index" % cache_name
-        self.cache_max_age = config.getint('ec2', 'cache_max_age')
-
-        if config.has_option('ec2', 'expand_csv_tags'):
-            self.expand_csv_tags = config.getboolean('ec2', 'expand_csv_tags')
-        else:
-            self.expand_csv_tags = False
-
-        # Configure nested groups instead of flat namespace.
-        if config.has_option('ec2', 'nested_groups'):
-            self.nested_groups = config.getboolean('ec2', 'nested_groups')
-        else:
-            self.nested_groups = False
-
-        # Replace dash or not in group names
-        if config.has_option('ec2', 'replace_dash_in_groups'):
-            self.replace_dash_in_groups = config.getboolean('ec2', 'replace_dash_in_groups')
-        else:
-            self.replace_dash_in_groups = True
-
-        # Configure which groups should be created.
-        group_by_options = [
-            'group_by_instance_id',
-            'group_by_region',
-            'group_by_availability_zone',
-            'group_by_ami_id',
-            'group_by_instance_type',
-            'group_by_key_pair',
-            'group_by_vpc_id',
-            'group_by_security_group',
-            'group_by_tag_keys',
-            'group_by_tag_none',
-            'group_by_route53_names',
-            'group_by_rds_engine',
-            'group_by_rds_parameter_group',
-            'group_by_elasticache_engine',
-            'group_by_elasticache_cluster',
-            'group_by_elasticache_parameter_group',
-            'group_by_elasticache_replication_group',
-        ]
-        for option in group_by_options:
-            if config.has_option('ec2', option):
-                setattr(self, option, config.getboolean('ec2', option))
-            else:
-                setattr(self, option, True)
-
-        # Do we need to just include hosts that match a pattern?
-        try:
-            pattern_include = config.get('ec2', 'pattern_include')
-            if pattern_include and len(pattern_include) > 0:
-                self.pattern_include = re.compile(pattern_include)
-            else:
-                self.pattern_include = None
-        except configparser.NoOptionError:
-            self.pattern_include = None
-
-        # Do we need to exclude hosts that match a pattern?
-        try:
-            pattern_exclude = config.get('ec2', 'pattern_exclude');
-            if pattern_exclude and len(pattern_exclude) > 0:
-                self.pattern_exclude = re.compile(pattern_exclude)
-            else:
-                self.pattern_exclude = None
-        except configparser.NoOptionError:
-            self.pattern_exclude = None
-
-        # Instance filters (see boto and EC2 API docs). Ignore invalid filters.
-        self.ec2_instance_filters = defaultdict(list)
-        if config.has_option('ec2', 'instance_filters'):
-
-            filters = [f for f in config.get('ec2', 'instance_filters').split(',') if f]
-
-            for instance_filter in filters:
-                instance_filter = instance_filter.strip()
-                if not instance_filter or '=' not in instance_filter:
-                    continue
-                filter_key, filter_value = [x.strip() for x in instance_filter.split('=', 1)]
-                if not filter_key:
-                    continue
-                self.ec2_instance_filters[filter_key].append(filter_value)
-
-    def parse_cli_args(self):
-        ''' Command line argument processing '''
-
-        parser = argparse.ArgumentParser(description='Produce an Ansible Inventory file based on EC2')
-        parser.add_argument('--list', action='store_true', default=True,
-                            help='List instances (default: True)')
-        parser.add_argument('--host', action='store',
-                            help='Get all the variables about a specific instance')
-        parser.add_argument('--refresh-cache', action='store_true', default=False,
-                            help='Force refresh of cache by making API requests to EC2 (default: False - use cache files)')
-        parser.add_argument('--profile', '--boto-profile', action='store', dest='boto_profile',
-                            help='Use boto profile for connections to EC2')
-        self.args = parser.parse_args()
-
-
-    def do_api_calls_update_cache(self):
-        ''' Do API calls to each region, and save data in cache files '''
-
-        if self.route53_enabled:
-            self.get_route53_records()
-
-        for region in self.regions:
-            self.get_instances_by_region(region)
-            if self.rds_enabled:
-                self.get_rds_instances_by_region(region)
-            if self.elasticache_enabled:
-                self.get_elasticache_clusters_by_region(region)
-                self.get_elasticache_replication_groups_by_region(region)
-
-        self.write_to_cache(self.inventory, self.cache_path_cache)
-        self.write_to_cache(self.index, self.cache_path_index)
-
-    def connect(self, region):
-        ''' create connection to api server'''
-        if self.eucalyptus:
-            conn = boto.connect_euca(host=self.eucalyptus_host)
-            conn.APIVersion = '2010-08-31'
-        else:
-            conn = self.connect_to_aws(ec2, region)
-        return conn
-
-    def boto_fix_security_token_in_profile(self, connect_args):
-        ''' monkey patch for boto issue boto/boto#2100 '''
-        profile = 'profile ' + self.boto_profile
-        if boto.config.has_option(profile, 'aws_security_token'):
-            connect_args['security_token'] = boto.config.get(profile, 'aws_security_token')
-        return connect_args
-
-    def connect_to_aws(self, module, region):
-        connect_args = {}
-
-        # only pass the profile name if it's set (as it is not supported by older boto versions)
-        if self.boto_profile:
-            connect_args['profile_name'] = self.boto_profile
-            self.boto_fix_security_token_in_profile(connect_args)
-
-        conn = module.connect_to_region(region, **connect_args)
-        # connect_to_region will fail "silently" by returning None if the region name is wrong or not supported
-        if conn is None:
-            self.fail_with_error("region name: %s likely not supported, or AWS is down.  connection to region failed." % region)
-        return conn
-
-    def get_instances_by_region(self, region):
-        ''' Makes an AWS EC2 API call to the list of instances in a particular
-        region '''
-
-        try:
-            conn = self.connect(region)
-            reservations = []
-            if self.ec2_instance_filters:
-                for filter_key, filter_values in self.ec2_instance_filters.items():
-                    reservations.extend(conn.get_all_instances(filters = { filter_key : filter_values }))
-            else:
-                reservations = conn.get_all_instances()
-
-            for reservation in reservations:
-                for instance in reservation.instances:
-                    self.add_instance(instance, region)
-
-        except boto.exception.BotoServerError as e:
-            if e.error_code == 'AuthFailure':
-                error = self.get_auth_error_message()
-            else:
-                backend = 'Eucalyptus' if self.eucalyptus else 'AWS'
-                error = "Error connecting to %s backend.\n%s" % (backend, e.message)
-            self.fail_with_error(error, 'getting EC2 instances')
-
-    def get_rds_instances_by_region(self, region):
-        ''' Makes an AWS API call to the list of RDS instances in a particular
-        region '''
-
-        try:
-            conn = self.connect_to_aws(rds, region)
-            if conn:
-                marker = None
-                while True:
-                    instances = conn.get_all_dbinstances(marker=marker)
-                    marker = instances.marker
-                    for instance in instances:
-                        self.add_rds_instance(instance, region)
-                    if not marker:
-                        break
-        except boto.exception.BotoServerError as e:
-            error = e.reason
-
-            if e.error_code == 'AuthFailure':
-                error = self.get_auth_error_message()
-            if not e.reason == "Forbidden":
-                error = "Looks like AWS RDS is down:\n%s" % e.message
-            self.fail_with_error(error, 'getting RDS instances')
-
-    def get_elasticache_clusters_by_region(self, region):
-        ''' Makes an AWS API call to the list of ElastiCache clusters (with
-        nodes' info) in a particular region.'''
-
-        # ElastiCache boto module doesn't provide a get_all_intances method,
-        # that's why we need to call describe directly (it would be called by
-        # the shorthand method anyway...)
-        try:
-            conn = self.connect_to_aws(elasticache, region)
-            if conn:
-                # show_cache_node_info = True
-                # because we also want nodes' information
-                response = conn.describe_cache_clusters(None, None, None, True)
-
-        except boto.exception.BotoServerError as e:
-            error = e.reason
-
-            if e.error_code == 'AuthFailure':
-                error = self.get_auth_error_message()
-            if not e.reason == "Forbidden":
-                error = "Looks like AWS ElastiCache is down:\n%s" % e.message
-            self.fail_with_error(error, 'getting ElastiCache clusters')
-
-        try:
-            # Boto also doesn't provide wrapper classes to CacheClusters or
-            # CacheNodes. Because of that wo can't make use of the get_list
-            # method in the AWSQueryConnection. Let's do the work manually
-            clusters = response['DescribeCacheClustersResponse']['DescribeCacheClustersResult']['CacheClusters']
-
-        except KeyError as e:
-            error = "ElastiCache query to AWS failed (unexpected format)."
-            self.fail_with_error(error, 'getting ElastiCache clusters')
-
-        for cluster in clusters:
-            self.add_elasticache_cluster(cluster, region)
-
-    def get_elasticache_replication_groups_by_region(self, region):
-        ''' Makes an AWS API call to the list of ElastiCache replication groups
-        in a particular region.'''
-
-        # ElastiCache boto module doesn't provide a get_all_intances method,
-        # that's why we need to call describe directly (it would be called by
-        # the shorthand method anyway...)
-        try:
-            conn = self.connect_to_aws(elasticache, region)
-            if conn:
-                response = conn.describe_replication_groups()
-
-        except boto.exception.BotoServerError as e:
-            error = e.reason
-
-            if e.error_code == 'AuthFailure':
-                error = self.get_auth_error_message()
-            if not e.reason == "Forbidden":
-                error = "Looks like AWS ElastiCache [Replication Groups] is down:\n%s" % e.message
-            self.fail_with_error(error, 'getting ElastiCache clusters')
-
-        try:
-            # Boto also doesn't provide wrapper classes to ReplicationGroups
-            # Because of that wo can't make use of the get_list method in the
-            # AWSQueryConnection. Let's do the work manually
-            replication_groups = response['DescribeReplicationGroupsResponse']['DescribeReplicationGroupsResult']['ReplicationGroups']
-
-        except KeyError as e:
-            error = "ElastiCache [Replication Groups] query to AWS failed (unexpected format)."
-            self.fail_with_error(error, 'getting ElastiCache clusters')
-
-        for replication_group in replication_groups:
-            self.add_elasticache_replication_group(replication_group, region)
-
-    def get_auth_error_message(self):
-        ''' create an informative error message if there is an issue authenticating'''
-        errors = ["Authentication error retrieving ec2 inventory."]
-        if None in [os.environ.get('AWS_ACCESS_KEY_ID'), os.environ.get('AWS_SECRET_ACCESS_KEY')]:
-            errors.append(' - No AWS_ACCESS_KEY_ID or AWS_SECRET_ACCESS_KEY environment vars found')
-        else:
-            errors.append(' - AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY environment vars found but may not be correct')
-
-        boto_paths = ['/etc/boto.cfg', '~/.boto', '~/.aws/credentials']
-        boto_config_found = list(p for p in boto_paths if os.path.isfile(os.path.expanduser(p)))
-        if len(boto_config_found) > 0:
-            errors.append(" - Boto configs found at '%s', but the credentials contained may not be correct" % ', '.join(boto_config_found))
-        else:
-            errors.append(" - No Boto config found at any expected location '%s'" % ', '.join(boto_paths))
-
-        return '\n'.join(errors)
-
-    def fail_with_error(self, err_msg, err_operation=None):
-        '''log an error to std err for ansible-playbook to consume and exit'''
-        if err_operation:
-            err_msg = 'ERROR: "{err_msg}", while: {err_operation}'.format(
-                    err_msg=err_msg, err_operation=err_operation)
-        sys.stderr.write(err_msg)
-        sys.exit(1)
-
-    def get_instance(self, region, instance_id):
-        conn = self.connect(region)
-
-        reservations = conn.get_all_instances([instance_id])
-        for reservation in reservations:
-            for instance in reservation.instances:
-                return instance
-
-    def add_instance(self, instance, region):
-        ''' Adds an instance to the inventory and index, as long as it is
-        addressable '''
-
-        # Only return instances with desired instance states
-        if instance.state not in self.ec2_instance_states:
-            return
-
-        # Select the best destination address
-        if self.destination_format and self.destination_format_tags:
-            dest = self.destination_format.format(*[ getattr(instance, 'tags').get(tag, '') for tag in self.destination_format_tags ])
-        elif instance.subnet_id:
-            dest = getattr(instance, self.vpc_destination_variable, None)
-            if dest is None:
-                dest = getattr(instance, 'tags').get(self.vpc_destination_variable, None)
-        else:
-            dest = getattr(instance, self.destination_variable, None)
-            if dest is None:
-                dest = getattr(instance, 'tags').get(self.destination_variable, None)
-
-        if not dest:
-            # Skip instances we cannot address (e.g. private VPC subnet)
-            return
-
-        # Set the inventory name
-        hostname = None
-        if self.hostname_variable:
-            if self.hostname_variable.startswith('tag_'):
-                hostname = instance.tags.get(self.hostname_variable[4:], None)
-            else:
-                hostname = getattr(instance, self.hostname_variable)
-
-        # If we can't get a nice hostname, use the destination address
-        if not hostname:
-            hostname = dest
-        else:
-            hostname = self.to_safe(hostname).lower()
-
-        # if we only want to include hosts that match a pattern, skip those that don't
-        if self.pattern_include and not self.pattern_include.match(hostname):
-            return
-
-        # if we need to exclude hosts that match a pattern, skip those
-        if self.pattern_exclude and self.pattern_exclude.match(hostname):
-            return
-
-        # Add to index
-        self.index[hostname] = [region, instance.id]
-
-        # Inventory: Group by instance ID (always a group of 1)
-        if self.group_by_instance_id:
-            self.inventory[instance.id] = [hostname]
-            if self.nested_groups:
-                self.push_group(self.inventory, 'instances', instance.id)
-
-        # Inventory: Group by region
-        if self.group_by_region:
-            self.push(self.inventory, region, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'regions', region)
-
-        # Inventory: Group by availability zone
-        if self.group_by_availability_zone:
-            self.push(self.inventory, instance.placement, hostname)
-            if self.nested_groups:
-                if self.group_by_region:
-                    self.push_group(self.inventory, region, instance.placement)
-                self.push_group(self.inventory, 'zones', instance.placement)
-
-        # Inventory: Group by Amazon Machine Image (AMI) ID
-        if self.group_by_ami_id:
-            ami_id = self.to_safe(instance.image_id)
-            self.push(self.inventory, ami_id, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'images', ami_id)
-
-        # Inventory: Group by instance type
-        if self.group_by_instance_type:
-            type_name = self.to_safe('type_' + instance.instance_type)
-            self.push(self.inventory, type_name, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'types', type_name)
-
-        # Inventory: Group by key pair
-        if self.group_by_key_pair and instance.key_name:
-            key_name = self.to_safe('key_' + instance.key_name)
-            self.push(self.inventory, key_name, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'keys', key_name)
-
-        # Inventory: Group by VPC
-        if self.group_by_vpc_id and instance.vpc_id:
-            vpc_id_name = self.to_safe('vpc_id_' + instance.vpc_id)
-            self.push(self.inventory, vpc_id_name, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'vpcs', vpc_id_name)
-
-        # Inventory: Group by security group
-        if self.group_by_security_group:
-            try:
-                for group in instance.groups:
-                    key = self.to_safe("security_group_" + group.name)
-                    self.push(self.inventory, key, hostname)
-                    if self.nested_groups:
-                        self.push_group(self.inventory, 'security_groups', key)
-            except AttributeError:
-                self.fail_with_error('\n'.join(['Package boto seems a bit older.',
-                                                'Please upgrade boto >= 2.3.0.']))
-
-        # Inventory: Group by tag keys
-        if self.group_by_tag_keys:
-            for k, v in instance.tags.items():
-                if self.expand_csv_tags and v and ',' in v:
-                    values = map(lambda x: x.strip(), v.split(','))
-                else:
-                    values = [v]
-
-                for v in values:
-                    if v:
-                        key = self.to_safe("tag_" + k + "=" + v)
-                    else:
-                        key = self.to_safe("tag_" + k)
-                    self.push(self.inventory, key, hostname)
-                    if self.nested_groups:
-                        self.push_group(self.inventory, 'tags', self.to_safe("tag_" + k))
-                        if v:
-                            self.push_group(self.inventory, self.to_safe("tag_" + k), key)
-
-        # Inventory: Group by Route53 domain names if enabled
-        if self.route53_enabled and self.group_by_route53_names:
-            route53_names = self.get_instance_route53_names(instance)
-            for name in route53_names:
-                self.push(self.inventory, name, hostname)
-                if self.nested_groups:
-                    self.push_group(self.inventory, 'route53', name)
-
-        # Global Tag: instances without tags
-        if self.group_by_tag_none and len(instance.tags) == 0:
-            self.push(self.inventory, 'tag_none', hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'tags', 'tag_none')
-
-        # Global Tag: tag all EC2 instances
-        self.push(self.inventory, 'ec2', hostname)
-
-        self.inventory["_meta"]["hostvars"][hostname] = self.get_host_info_dict_from_instance(instance)
-        self.inventory["_meta"]["hostvars"][hostname]['ansible_ssh_host'] = dest
-
-
-    def add_rds_instance(self, instance, region):
-        ''' Adds an RDS instance to the inventory and index, as long as it is
-        addressable '''
-
-        # Only want available instances unless all_rds_instances is True
-        if not self.all_rds_instances and instance.status != 'available':
-            return
-
-        # Select the best destination address
-        dest = instance.endpoint[0]
-
-        if not dest:
-            # Skip instances we cannot address (e.g. private VPC subnet)
-            return
-
-        # Set the inventory name
-        hostname = None
-        if self.hostname_variable:
-            if self.hostname_variable.startswith('tag_'):
-                hostname = instance.tags.get(self.hostname_variable[4:], None)
-            else:
-                hostname = getattr(instance, self.hostname_variable)
-
-        # If we can't get a nice hostname, use the destination address
-        if not hostname:
-            hostname = dest
-
-        hostname = self.to_safe(hostname).lower()
-
-        # Add to index
-        self.index[hostname] = [region, instance.id]
-
-        # Inventory: Group by instance ID (always a group of 1)
-        if self.group_by_instance_id:
-            self.inventory[instance.id] = [hostname]
-            if self.nested_groups:
-                self.push_group(self.inventory, 'instances', instance.id)
-
-        # Inventory: Group by region
-        if self.group_by_region:
-            self.push(self.inventory, region, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'regions', region)
-
-        # Inventory: Group by availability zone
-        if self.group_by_availability_zone:
-            self.push(self.inventory, instance.availability_zone, hostname)
-            if self.nested_groups:
-                if self.group_by_region:
-                    self.push_group(self.inventory, region, instance.availability_zone)
-                self.push_group(self.inventory, 'zones', instance.availability_zone)
-
-        # Inventory: Group by instance type
-        if self.group_by_instance_type:
-            type_name = self.to_safe('type_' + instance.instance_class)
-            self.push(self.inventory, type_name, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'types', type_name)
-
-        # Inventory: Group by VPC
-        if self.group_by_vpc_id and instance.subnet_group and instance.subnet_group.vpc_id:
-            vpc_id_name = self.to_safe('vpc_id_' + instance.subnet_group.vpc_id)
-            self.push(self.inventory, vpc_id_name, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'vpcs', vpc_id_name)
-
-        # Inventory: Group by security group
-        if self.group_by_security_group:
-            try:
-                if instance.security_group:
-                    key = self.to_safe("security_group_" + instance.security_group.name)
-                    self.push(self.inventory, key, hostname)
-                    if self.nested_groups:
-                        self.push_group(self.inventory, 'security_groups', key)
-
-            except AttributeError:
-                self.fail_with_error('\n'.join(['Package boto seems a bit older.',
-                                                'Please upgrade boto >= 2.3.0.']))
-
-
-        # Inventory: Group by engine
-        if self.group_by_rds_engine:
-            self.push(self.inventory, self.to_safe("rds_" + instance.engine), hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'rds_engines', self.to_safe("rds_" + instance.engine))
-
-        # Inventory: Group by parameter group
-        if self.group_by_rds_parameter_group:
-            self.push(self.inventory, self.to_safe("rds_parameter_group_" + instance.parameter_group.name), hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'rds_parameter_groups', self.to_safe("rds_parameter_group_" + instance.parameter_group.name))
-
-        # Global Tag: all RDS instances
-        self.push(self.inventory, 'rds', hostname)
-
-        self.inventory["_meta"]["hostvars"][hostname] = self.get_host_info_dict_from_instance(instance)
-        self.inventory["_meta"]["hostvars"][hostname]['ansible_ssh_host'] = dest
-
-    def add_elasticache_cluster(self, cluster, region):
-        ''' Adds an ElastiCache cluster to the inventory and index, as long as
-        it's nodes are addressable '''
-
-        # Only want available clusters unless all_elasticache_clusters is True
-        if not self.all_elasticache_clusters and cluster['CacheClusterStatus'] != 'available':
-            return
-
-        # Select the best destination address
-        if 'ConfigurationEndpoint' in cluster and cluster['ConfigurationEndpoint']:
-            # Memcached cluster
-            dest = cluster['ConfigurationEndpoint']['Address']
-            is_redis = False
-        else:
-            # Redis sigle node cluster
-            # Because all Redis clusters are single nodes, we'll merge the
-            # info from the cluster with info about the node
-            dest = cluster['CacheNodes'][0]['Endpoint']['Address']
-            is_redis = True
-
-        if not dest:
-            # Skip clusters we cannot address (e.g. private VPC subnet)
-            return
-
-        # Add to index
-        self.index[dest] = [region, cluster['CacheClusterId']]
-
-        # Inventory: Group by instance ID (always a group of 1)
-        if self.group_by_instance_id:
-            self.inventory[cluster['CacheClusterId']] = [dest]
-            if self.nested_groups:
-                self.push_group(self.inventory, 'instances', cluster['CacheClusterId'])
-
-        # Inventory: Group by region
-        if self.group_by_region and not is_redis:
-            self.push(self.inventory, region, dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'regions', region)
-
-        # Inventory: Group by availability zone
-        if self.group_by_availability_zone and not is_redis:
-            self.push(self.inventory, cluster['PreferredAvailabilityZone'], dest)
-            if self.nested_groups:
-                if self.group_by_region:
-                    self.push_group(self.inventory, region, cluster['PreferredAvailabilityZone'])
-                self.push_group(self.inventory, 'zones', cluster['PreferredAvailabilityZone'])
-
-        # Inventory: Group by node type
-        if self.group_by_instance_type and not is_redis:
-            type_name = self.to_safe('type_' + cluster['CacheNodeType'])
-            self.push(self.inventory, type_name, dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'types', type_name)
-
-        # Inventory: Group by VPC (information not available in the current
-        # AWS API version for ElastiCache)
-
-        # Inventory: Group by security group
-        if self.group_by_security_group and not is_redis:
-
-            # Check for the existence of the 'SecurityGroups' key and also if
-            # this key has some value. When the cluster is not placed in a SG
-            # the query can return None here and cause an error.
-            if 'SecurityGroups' in cluster and cluster['SecurityGroups'] is not None:
-                for security_group in cluster['SecurityGroups']:
-                    key = self.to_safe("security_group_" + security_group['SecurityGroupId'])
-                    self.push(self.inventory, key, dest)
-                    if self.nested_groups:
-                        self.push_group(self.inventory, 'security_groups', key)
-
-        # Inventory: Group by engine
-        if self.group_by_elasticache_engine and not is_redis:
-            self.push(self.inventory, self.to_safe("elasticache_" + cluster['Engine']), dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'elasticache_engines', self.to_safe(cluster['Engine']))
-
-        # Inventory: Group by parameter group
-        if self.group_by_elasticache_parameter_group:
-            self.push(self.inventory, self.to_safe("elasticache_parameter_group_" + cluster['CacheParameterGroup']['CacheParameterGroupName']), dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'elasticache_parameter_groups', self.to_safe(cluster['CacheParameterGroup']['CacheParameterGroupName']))
-
-        # Inventory: Group by replication group
-        if self.group_by_elasticache_replication_group and 'ReplicationGroupId' in cluster and cluster['ReplicationGroupId']:
-            self.push(self.inventory, self.to_safe("elasticache_replication_group_" + cluster['ReplicationGroupId']), dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'elasticache_replication_groups', self.to_safe(cluster['ReplicationGroupId']))
-
-        # Global Tag: all ElastiCache clusters
-        self.push(self.inventory, 'elasticache_clusters', cluster['CacheClusterId'])
-
-        host_info = self.get_host_info_dict_from_describe_dict(cluster)
-
-        self.inventory["_meta"]["hostvars"][dest] = host_info
-
-        # Add the nodes
-        for node in cluster['CacheNodes']:
-            self.add_elasticache_node(node, cluster, region)
-
-    def add_elasticache_node(self, node, cluster, region):
-        ''' Adds an ElastiCache node to the inventory and index, as long as
-        it is addressable '''
-
-        # Only want available nodes unless all_elasticache_nodes is True
-        if not self.all_elasticache_nodes and node['CacheNodeStatus'] != 'available':
-            return
-
-        # Select the best destination address
-        dest = node['Endpoint']['Address']
-
-        if not dest:
-            # Skip nodes we cannot address (e.g. private VPC subnet)
-            return
-
-        node_id = self.to_safe(cluster['CacheClusterId'] + '_' + node['CacheNodeId'])
-
-        # Add to index
-        self.index[dest] = [region, node_id]
-
-        # Inventory: Group by node ID (always a group of 1)
-        if self.group_by_instance_id:
-            self.inventory[node_id] = [dest]
-            if self.nested_groups:
-                self.push_group(self.inventory, 'instances', node_id)
-
-        # Inventory: Group by region
-        if self.group_by_region:
-            self.push(self.inventory, region, dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'regions', region)
-
-        # Inventory: Group by availability zone
-        if self.group_by_availability_zone:
-            self.push(self.inventory, cluster['PreferredAvailabilityZone'], dest)
-            if self.nested_groups:
-                if self.group_by_region:
-                    self.push_group(self.inventory, region, cluster['PreferredAvailabilityZone'])
-                self.push_group(self.inventory, 'zones', cluster['PreferredAvailabilityZone'])
-
-        # Inventory: Group by node type
-        if self.group_by_instance_type:
-            type_name = self.to_safe('type_' + cluster['CacheNodeType'])
-            self.push(self.inventory, type_name, dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'types', type_name)
-
-        # Inventory: Group by VPC (information not available in the current
-        # AWS API version for ElastiCache)
-
-        # Inventory: Group by security group
-        if self.group_by_security_group:
-
-            # Check for the existence of the 'SecurityGroups' key and also if
-            # this key has some value. When the cluster is not placed in a SG
-            # the query can return None here and cause an error.
-            if 'SecurityGroups' in cluster and cluster['SecurityGroups'] is not None:
-                for security_group in cluster['SecurityGroups']:
-                    key = self.to_safe("security_group_" + security_group['SecurityGroupId'])
-                    self.push(self.inventory, key, dest)
-                    if self.nested_groups:
-                        self.push_group(self.inventory, 'security_groups', key)
-
-        # Inventory: Group by engine
-        if self.group_by_elasticache_engine:
-            self.push(self.inventory, self.to_safe("elasticache_" + cluster['Engine']), dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'elasticache_engines', self.to_safe("elasticache_" + cluster['Engine']))
-
-        # Inventory: Group by parameter group (done at cluster level)
-
-        # Inventory: Group by replication group (done at cluster level)
-
-        # Inventory: Group by ElastiCache Cluster
-        if self.group_by_elasticache_cluster:
-            self.push(self.inventory, self.to_safe("elasticache_cluster_" + cluster['CacheClusterId']), dest)
-
-        # Global Tag: all ElastiCache nodes
-        self.push(self.inventory, 'elasticache_nodes', dest)
-
-        host_info = self.get_host_info_dict_from_describe_dict(node)
-
-        if dest in self.inventory["_meta"]["hostvars"]:
-            self.inventory["_meta"]["hostvars"][dest].update(host_info)
-        else:
-            self.inventory["_meta"]["hostvars"][dest] = host_info
-
-    def add_elasticache_replication_group(self, replication_group, region):
-        ''' Adds an ElastiCache replication group to the inventory and index '''
-
-        # Only want available clusters unless all_elasticache_replication_groups is True
-        if not self.all_elasticache_replication_groups and replication_group['Status'] != 'available':
-            return
-
-        # Select the best destination address (PrimaryEndpoint)
-        dest = replication_group['NodeGroups'][0]['PrimaryEndpoint']['Address']
-
-        if not dest:
-            # Skip clusters we cannot address (e.g. private VPC subnet)
-            return
-
-        # Add to index
-        self.index[dest] = [region, replication_group['ReplicationGroupId']]
-
-        # Inventory: Group by ID (always a group of 1)
-        if self.group_by_instance_id:
-            self.inventory[replication_group['ReplicationGroupId']] = [dest]
-            if self.nested_groups:
-                self.push_group(self.inventory, 'instances', replication_group['ReplicationGroupId'])
-
-        # Inventory: Group by region
-        if self.group_by_region:
-            self.push(self.inventory, region, dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'regions', region)
-
-        # Inventory: Group by availability zone (doesn't apply to replication groups)
-
-        # Inventory: Group by node type (doesn't apply to replication groups)
-
-        # Inventory: Group by VPC (information not available in the current
-        # AWS API version for replication groups
-
-        # Inventory: Group by security group (doesn't apply to replication groups)
-        # Check this value in cluster level
-
-        # Inventory: Group by engine (replication groups are always Redis)
-        if self.group_by_elasticache_engine:
-            self.push(self.inventory, 'elasticache_redis', dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'elasticache_engines', 'redis')
-
-        # Global Tag: all ElastiCache clusters
-        self.push(self.inventory, 'elasticache_replication_groups', replication_group['ReplicationGroupId'])
-
-        host_info = self.get_host_info_dict_from_describe_dict(replication_group)
-
-        self.inventory["_meta"]["hostvars"][dest] = host_info
-
-    def get_route53_records(self):
-        ''' Get and store the map of resource records to domain names that
-        point to them. '''
-
-        r53_conn = route53.Route53Connection()
-        all_zones = r53_conn.get_zones()
-
-        route53_zones = [ zone for zone in all_zones if zone.name[:-1]
-                          not in self.route53_excluded_zones ]
-
-        self.route53_records = {}
-
-        for zone in route53_zones:
-            rrsets = r53_conn.get_all_rrsets(zone.id)
-
-            for record_set in rrsets:
-                record_name = record_set.name
-
-                if record_name.endswith('.'):
-                    record_name = record_name[:-1]
-
-                for resource in record_set.resource_records:
-                    self.route53_records.setdefault(resource, set())
-                    self.route53_records[resource].add(record_name)
-
-
-    def get_instance_route53_names(self, instance):
-        ''' Check if an instance is referenced in the records we have from
-        Route53. If it is, return the list of domain names pointing to said
-        instance. If nothing points to it, return an empty list. '''
-
-        instance_attributes = [ 'public_dns_name', 'private_dns_name',
-                                'ip_address', 'private_ip_address' ]
-
-        name_list = set()
-
-        for attrib in instance_attributes:
-            try:
-                value = getattr(instance, attrib)
-            except AttributeError:
-                continue
-
-            if value in self.route53_records:
-                name_list.update(self.route53_records[value])
-
-        return list(name_list)
-
-    def get_host_info_dict_from_instance(self, instance):
-        instance_vars = {}
-        for key in vars(instance):
-            value = getattr(instance, key)
-            key = self.to_safe('ec2_' + key)
-
-            # Handle complex types
-            # state/previous_state changed to properties in boto in https://github.com/boto/boto/commit/a23c379837f698212252720d2af8dec0325c9518
-            if key == 'ec2__state':
-                instance_vars['ec2_state'] = instance.state or ''
-                instance_vars['ec2_state_code'] = instance.state_code
-            elif key == 'ec2__previous_state':
-                instance_vars['ec2_previous_state'] = instance.previous_state or ''
-                instance_vars['ec2_previous_state_code'] = instance.previous_state_code
-            elif type(value) in [int, bool]:
-                instance_vars[key] = value
-            elif isinstance(value, six.string_types):
-                instance_vars[key] = value.strip()
-            elif type(value) == type(None):
-                instance_vars[key] = ''
-            elif key == 'ec2_region':
-                instance_vars[key] = value.name
-            elif key == 'ec2__placement':
-                instance_vars['ec2_placement'] = value.zone
-            elif key == 'ec2_tags':
-                for k, v in value.items():
-                    if self.expand_csv_tags and ',' in v:
-                        v = map(lambda x: x.strip(), v.split(','))
-                    key = self.to_safe('ec2_tag_' + k)
-                    instance_vars[key] = v
-            elif key == 'ec2_groups':
-                group_ids = []
-                group_names = []
-                for group in value:
-                    group_ids.append(group.id)
-                    group_names.append(group.name)
-                instance_vars["ec2_security_group_ids"] = ','.join([str(i) for i in group_ids])
-                instance_vars["ec2_security_group_names"] = ','.join([str(i) for i in group_names])
-            else:
-                pass
-                # TODO Product codes if someone finds them useful
-                #print key
-                #print type(value)
-                #print value
-
-        return instance_vars
-
-    def get_host_info_dict_from_describe_dict(self, describe_dict):
-        ''' Parses the dictionary returned by the API call into a flat list
-            of parameters. This method should be used only when 'describe' is
-            used directly because Boto doesn't provide specific classes. '''
-
-        # I really don't agree with prefixing everything with 'ec2'
-        # because EC2, RDS and ElastiCache are different services.
-        # I'm just following the pattern used until now to not break any
-        # compatibility.
-
-        host_info = {}
-        for key in describe_dict:
-            value = describe_dict[key]
-            key = self.to_safe('ec2_' + self.uncammelize(key))
-
-            # Handle complex types
-
-            # Target: Memcached Cache Clusters
-            if key == 'ec2_configuration_endpoint' and value:
-                host_info['ec2_configuration_endpoint_address'] = value['Address']
-                host_info['ec2_configuration_endpoint_port'] = value['Port']
-
-            # Target: Cache Nodes and Redis Cache Clusters (single node)
-            if key == 'ec2_endpoint' and value:
-                host_info['ec2_endpoint_address'] = value['Address']
-                host_info['ec2_endpoint_port'] = value['Port']
-
-            # Target: Redis Replication Groups
-            if key == 'ec2_node_groups' and value:
-                host_info['ec2_endpoint_address'] = value[0]['PrimaryEndpoint']['Address']
-                host_info['ec2_endpoint_port'] = value[0]['PrimaryEndpoint']['Port']
-                replica_count = 0
-                for node in value[0]['NodeGroupMembers']:
-                    if node['CurrentRole'] == 'primary':
-                        host_info['ec2_primary_cluster_address'] = node['ReadEndpoint']['Address']
-                        host_info['ec2_primary_cluster_port'] = node['ReadEndpoint']['Port']
-                        host_info['ec2_primary_cluster_id'] = node['CacheClusterId']
-                    elif node['CurrentRole'] == 'replica':
-                        host_info['ec2_replica_cluster_address_'+ str(replica_count)] = node['ReadEndpoint']['Address']
-                        host_info['ec2_replica_cluster_port_'+ str(replica_count)] = node['ReadEndpoint']['Port']
-                        host_info['ec2_replica_cluster_id_'+ str(replica_count)] = node['CacheClusterId']
-                        replica_count += 1
-
-            # Target: Redis Replication Groups
-            if key == 'ec2_member_clusters' and value:
-                host_info['ec2_member_clusters'] = ','.join([str(i) for i in value])
-
-            # Target: All Cache Clusters
-            elif key == 'ec2_cache_parameter_group':
-                host_info["ec2_cache_node_ids_to_reboot"] = ','.join([str(i) for i in value['CacheNodeIdsToReboot']])
-                host_info['ec2_cache_parameter_group_name'] = value['CacheParameterGroupName']
-                host_info['ec2_cache_parameter_apply_status'] = value['ParameterApplyStatus']
-
-            # Target: Almost everything
-            elif key == 'ec2_security_groups':
-
-                # Skip if SecurityGroups is None
-                # (it is possible to have the key defined but no value in it).
-                if value is not None:
-                    sg_ids = []
-                    for sg in value:
-                        sg_ids.append(sg['SecurityGroupId'])
-                    host_info["ec2_security_group_ids"] = ','.join([str(i) for i in sg_ids])
-
-            # Target: Everything
-            # Preserve booleans and integers
-            elif type(value) in [int, bool]:
-                host_info[key] = value
-
-            # Target: Everything
-            # Sanitize string values
-            elif isinstance(value, six.string_types):
-                host_info[key] = value.strip()
-
-            # Target: Everything
-            # Replace None by an empty string
-            elif type(value) == type(None):
-                host_info[key] = ''
-
-            else:
-                # Remove non-processed complex types
-                pass
-
-        return host_info
-
-    def get_host_info(self):
-        ''' Get variables about a specific host '''
-
-        if len(self.index) == 0:
-            # Need to load index from cache
-            self.load_index_from_cache()
-
-        if not self.args.host in self.index:
-            # try updating the cache
-            self.do_api_calls_update_cache()
-            if not self.args.host in self.index:
-                # host might not exist anymore
-                return self.json_format_dict({}, True)
-
-        (region, instance_id) = self.index[self.args.host]
-
-        instance = self.get_instance(region, instance_id)
-        return self.json_format_dict(self.get_host_info_dict_from_instance(instance), True)
-
-    def push(self, my_dict, key, element):
-        ''' Push an element onto an array that may not have been defined in
-        the dict '''
-        group_info = my_dict.setdefault(key, [])
-        if isinstance(group_info, dict):
-            host_list = group_info.setdefault('hosts', [])
-            host_list.append(element)
-        else:
-            group_info.append(element)
-
-    def push_group(self, my_dict, key, element):
-        ''' Push a group as a child of another group. '''
-        parent_group = my_dict.setdefault(key, {})
-        if not isinstance(parent_group, dict):
-            parent_group = my_dict[key] = {'hosts': parent_group}
-        child_groups = parent_group.setdefault('children', [])
-        if element not in child_groups:
-            child_groups.append(element)
-
-    def get_inventory_from_cache(self):
-        ''' Reads the inventory from the cache file and returns it as a JSON
-        object '''
-
-        cache = open(self.cache_path_cache, 'r')
-        json_inventory = cache.read()
-        return json_inventory
-
-
-    def load_index_from_cache(self):
-        ''' Reads the index from the cache file sets self.index '''
-
-        cache = open(self.cache_path_index, 'r')
-        json_index = cache.read()
-        self.index = json.loads(json_index)
-
-
-    def write_to_cache(self, data, filename):
-        ''' Writes data in JSON format to a file '''
-
-        json_data = self.json_format_dict(data, True)
-        cache = open(filename, 'w')
-        cache.write(json_data)
-        cache.close()
-
-    def uncammelize(self, key):
-        temp = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', key)
-        return re.sub('([a-z0-9])([A-Z])', r'\1_\2', temp).lower()
-
-    def to_safe(self, word):
-        ''' Converts 'bad' characters in a string to underscores so they can be used as Ansible groups '''
-        regex = "[^A-Za-z0-9\_"
-        if not self.replace_dash_in_groups:
-            regex += "\-"
-        return re.sub(regex + "]", "_", word)
-
-    def json_format_dict(self, data, pretty=False):
-        ''' Converts a dict to a JSON object and dumps it as a formatted
-        string '''
-
-        if pretty:
-            return json.dumps(data, sort_keys=True, indent=2)
-        else:
-            return json.dumps(data)
-
-
-# Run the script
-Ec2Inventory()
diff --git a/edge-1601-dc2/inventory b/edge-1601-dc2/inventory
deleted file mode 100644
index 3bb90ab..0000000
--- a/edge-1601-dc2/inventory
+++ /dev/null
@@ -1,74 +0,0 @@
-[tag_Name_dc2_n1]
-[tag_Name_dc2_n2]
-[tag_Name_dc2_n3]
-[tag_Name_dc2_n4]
-[tag_Name_dc2_n5]
-
-[planet:children]
-dc-1
-
-[dc-1:children]
-tag_Name_dc2_n1
-tag_Name_dc2_n2
-tag_Name_dc2_n3
-tag_Name_dc2_n4
-tag_Name_dc2_n5
-
-[ds:children]
-dc-1-ds
-
-[dc-1-ds:children]
-tag_Name_dc2_n1
-tag_Name_dc2_n2
-tag_Name_dc2_n3
-
-[ms:children]
-dc-1-ms
-
-[dc-1-ms:children]
-tag_Name_dc2_n1
-
-[ui:children]
-dc-1-ui
-
-[dc-1-ui:children]
-tag_Name_dc2_n1
-
-[ldap:children]
-dc-1-ldap
-
-[dc-1-ldap:children]
-tag_Name_dc2_n1
-
-[rmp:children]
-dc-1-rmp
-
-[dc-1-rmp:children]
-tag_Name_dc2_n2
-tag_Name_dc2_n3
-
-[qpid:children]
-dc-1-qpid
-
-[dc-1-qpid:children]
-tag_Name_dc2_n4
-tag_Name_dc2_n5
-
-[pg:children]
-dc-1-pg
-
-[dc-1-pg:children]
-dc-1-pgmaster
-dc-1-pgstandby
-
-[pgmaster:children]
-dc-1-pgmaster
-
-[dc-1-pgmaster:children]
-tag_Name_dc2_n4
-
-[pgstandby:children]
-dc-1-pgstandby
-
-[dc-1-pgstandby:children]
-tag_Name_dc2_n5
diff --git a/edge-1601-dc3-dc4/ec2.ini b/edge-1601-dc3-dc4/ec2.ini
deleted file mode 100644
index 36b3921..0000000
--- a/edge-1601-dc3-dc4/ec2.ini
+++ /dev/null
@@ -1,200 +0,0 @@
-# Ansible EC2 external inventory script settings
-#
-
-[ec2]
-
-# to talk to a private eucalyptus instance uncomment these lines
-# and edit edit eucalyptus_host to be the host name of your cloud controller
-#eucalyptus = True
-#eucalyptus_host = clc.cloud.domain.org
-
-# AWS regions to make calls to. Set this to 'all' to make request to all regions
-# in AWS and merge the results together. Alternatively, set this to a comma
-# separated list of regions. E.g. 'us-east-1,us-west-1,us-west-2'
-regions = all
-regions_exclude = us-gov-west-1,cn-north-1
-
-# When generating inventory, Ansible needs to know how to address a server.
-# Each EC2 instance has a lot of variables associated with it. Here is the list:
-#   http://docs.pythonboto.org/en/latest/ref/ec2.html#module-boto.ec2.instance
-# Below are 2 variables that are used as the address of a server:
-#   - destination_variable
-#   - vpc_destination_variable
-
-# This is the normal destination variable to use. If you are running Ansible
-# from outside EC2, then 'public_dns_name' makes the most sense. If you are
-# running Ansible from within EC2, then perhaps you want to use the internal
-# address, and should set this to 'private_dns_name'. The key of an EC2 tag
-# may optionally be used; however the boto instance variables hold precedence
-# in the event of a collision.
-destination_variable = public_dns_name
-
-# This allows you to override the inventory_name with an ec2 variable, instead
-# of using the destination_variable above. Addressing (aka ansible_ssh_host)
-# will still use destination_variable. Tags should be written as 'tag_TAGNAME'.
-#hostname_variable = tag_Name
-
-# For server inside a VPC, using DNS names may not make sense. When an instance
-# has 'subnet_id' set, this variable is used. If the subnet is public, setting
-# this to 'ip_address' will return the public IP address. For instances in a
-# private subnet, this should be set to 'private_ip_address', and Ansible must
-# be run from within EC2. The key of an EC2 tag may optionally be used; however
-# the boto instance variables hold precedence in the event of a collision.
-# WARNING: - instances that are in the private vpc, _without_ public ip address
-# will not be listed in the inventory until You set:
-# vpc_destination_variable = private_ip_address
-vpc_destination_variable = ip_address
-
-# The following two settings allow flexible ansible host naming based on a
-# python format string and a comma-separated list of ec2 tags.  Note that:
-#
-# 1) If the tags referenced are not present for some instances, empty strings
-#    will be substituted in the format string.
-# 2) This overrides both destination_variable and vpc_destination_variable.
-#
-#destination_format = {0}.{1}.example.com
-#destination_format_tags = Name,environment
-
-# To tag instances on EC2 with the resource records that point to them from
-# Route53, uncomment and set 'route53' to True.
-route53 = False
-
-# To exclude RDS instances from the inventory, uncomment and set to False.
-rds = False
-
-# To exclude ElastiCache instances from the inventory, uncomment and set to False.
-elasticache = False
-
-# Additionally, you can specify the list of zones to exclude looking up in
-# 'route53_excluded_zones' as a comma-separated list.
-# route53_excluded_zones = samplezone1.com, samplezone2.com
-
-# By default, only EC2 instances in the 'running' state are returned. Set
-# 'all_instances' to True to return all instances regardless of state.
-all_instances = True
-
-# By default, only EC2 instances in the 'running' state are returned. Specify
-# EC2 instance states to return as a comma-separated list. This
-# option is overriden when 'all_instances' is True.
-# instance_states = pending, running, shutting-down, terminated, stopping, stopped
-
-# By default, only RDS instances in the 'available' state are returned.  Set
-# 'all_rds_instances' to True return all RDS instances regardless of state.
-all_rds_instances = False
-
-# By default, only ElastiCache clusters and nodes in the 'available' state
-# are returned. Set 'all_elasticache_clusters' and/or 'all_elastic_nodes'
-# to True return all ElastiCache clusters and nodes, regardless of state.
-#
-# Note that all_elasticache_nodes only applies to listed clusters. That means
-# if you set all_elastic_clusters to false, no node will be return from
-# unavailable clusters, regardless of the state and to what you set for
-# all_elasticache_nodes.
-all_elasticache_replication_groups = False
-all_elasticache_clusters = False
-all_elasticache_nodes = False
-
-# API calls to EC2 are slow. For this reason, we cache the results of an API
-# call. Set this to the path you want cache files to be written to. Two files
-# will be written to this directory:
-#   - ansible-ec2.cache
-#   - ansible-ec2.index
-cache_path = ~/.ansible/tmp
-
-# The number of seconds a cache file is considered valid. After this many
-# seconds, a new API call will be made, and the cache file will be updated.
-# To disable the cache, set this value to 0
-cache_max_age = 300
-
-# Organize groups into a nested/hierarchy instead of a flat namespace.
-nested_groups = False
-
-# Replace - tags when creating groups to avoid issues with ansible
-replace_dash_in_groups = True
-
-# If set to true, any tag of the form "a,b,c" is expanded into a list
-# and the results are used to create additional tag_* inventory groups.
-expand_csv_tags = False
-
-# The EC2 inventory output can become very large. To manage its size,
-# configure which groups should be created.
-group_by_instance_id = True
-group_by_region = True
-group_by_availability_zone = True
-group_by_ami_id = True
-group_by_instance_type = True
-group_by_key_pair = True
-group_by_vpc_id = True
-group_by_security_group = True
-group_by_tag_keys = True
-group_by_tag_none = True
-group_by_route53_names = True
-group_by_rds_engine = False
-group_by_rds_parameter_group = False
-group_by_elasticache_engine = True
-group_by_elasticache_cluster = True
-group_by_elasticache_parameter_group = True
-group_by_elasticache_replication_group = True
-
-# If you only want to include hosts that match a certain regular expression
-# pattern_include = staging-*
-
-# If you want to exclude any hosts that match a certain regular expression
-# pattern_exclude = staging-*
-# Ansible EC2 external inventory script settings
-#
-
-##[ec2]
-##
-### to talk to a private eucalyptus instance uncomment these lines
-### and edit edit eucalyptus_host to be the host name of your cloud controller
-###eucalyptus = True
-###eucalyptus_host = clc.cloud.domain.org
-##
-### AWS regions to make calls to. Set this to 'all' to make request to all regions
-##
-### in AWS and merge the results together. Alternatively, set this to a comma
-### separated list of regions. E.g. 'us-east-1,us-west-1,us-west-2'
-##regions = all
-##regions_exclude = us-gov-west-1,cn-north-1
-##
-### When generating inventory, Ansible needs to know how to address a server.
-### Each EC2 instance has a lot of variables associated with it. Here is the list:
-###   http://docs.pythonboto.org/en/latest/ref/ec2.html#module-boto.ec2.instance
-### Below are 2 variables that are used as the address of a server:
-###   - destination_variable
-###   - vpc_destination_variable
-##
-### This is the normal destination variable to use. If you are running Ansible
-### from outside EC2, then 'public_dns_name' makes the most sense. If you are
-### running Ansible from within EC2, then perhaps you want to use the internal
-### address, and should set this to 'private_dns_name'. The key of an EC2 tag
-##...skipping...
-### pattern_include = staging-*
-##
-### If you want to exclude any hosts that match a certain regular expression
-### pattern_exclude = staging-*
-
-# Instance filters can be used to control which instances are retrieved for
-# inventory. For the full list of possible filters, please read the EC2 API
-# docs: http://docs.aws.amazon.com/AWSEC2/latest/APIReference/ApiReference-query-DescribeInstances.html#query-DescribeInstances-filters
-# Filters are key/value pairs separated by '=', to list multiple filters use
-# a list separated by commas. See examples below.
-
-# Retrieve only instances with (key=value) env=staging tag
-# instance_filters = tag:env=staging
-
-# Retrieve only instances with role=webservers OR role=dbservers tag
-# instance_filters = tag:role=webservers,tag:role=dbservers
-
-# Retrieve only t1.micro instances OR instances with tag env=staging
-# instance_filters = instance-type=t1.micro,tag:env=staging
-
-# You can use wildcards in filter values also. Below will list instances which
-# tag Name value matches webservers1*
-# (ex. webservers15, webservers1a, webservers123 etc)
-# instance_filters = tag:Name=webservers1*
-
-# A boto configuration profile may be used to separate out credentials
-# see http://boto.readthedocs.org/en/latest/boto_config_tut.html
-# boto_profile = some-boto-profile-name
diff --git a/edge-1601-dc3-dc4/ec2.py b/edge-1601-dc3-dc4/ec2.py
deleted file mode 100755
index f30958a..0000000
--- a/edge-1601-dc3-dc4/ec2.py
+++ /dev/null
@@ -1,1385 +0,0 @@
-#!/usr/bin/env python
-
-'''
-EC2 external inventory script
-=================================
-
-Generates inventory that Ansible can understand by making API request to
-AWS EC2 using the Boto library.
-
-NOTE: This script assumes Ansible is being executed where the environment
-variables needed for Boto have already been set:
-    export AWS_ACCESS_KEY_ID='AK123'
-    export AWS_SECRET_ACCESS_KEY='abc123'
-
-This script also assumes there is an ec2.ini file alongside it.  To specify a
-different path to ec2.ini, define the EC2_INI_PATH environment variable:
-
-    export EC2_INI_PATH=/path/to/my_ec2.ini
-
-If you're using eucalyptus you need to set the above variables and
-you need to define:
-
-    export EC2_URL=http://hostname_of_your_cc:port/services/Eucalyptus
-
-If you're using boto profiles (requires boto>=2.24.0) you can choose a profile
-using the --boto-profile command line argument (e.g. ec2.py --boto-profile prod) or using
-the AWS_PROFILE variable:
-
-    AWS_PROFILE=prod ansible-playbook -i ec2.py myplaybook.yml
-
-For more details, see: http://docs.pythonboto.org/en/latest/boto_config_tut.html
-
-When run against a specific host, this script returns the following variables:
- - ec2_ami_launch_index
- - ec2_architecture
- - ec2_association
- - ec2_attachTime
- - ec2_attachment
- - ec2_attachmentId
- - ec2_client_token
- - ec2_deleteOnTermination
- - ec2_description
- - ec2_deviceIndex
- - ec2_dns_name
- - ec2_eventsSet
- - ec2_group_name
- - ec2_hypervisor
- - ec2_id
- - ec2_image_id
- - ec2_instanceState
- - ec2_instance_type
- - ec2_ipOwnerId
- - ec2_ip_address
- - ec2_item
- - ec2_kernel
- - ec2_key_name
- - ec2_launch_time
- - ec2_monitored
- - ec2_monitoring
- - ec2_networkInterfaceId
- - ec2_ownerId
- - ec2_persistent
- - ec2_placement
- - ec2_platform
- - ec2_previous_state
- - ec2_private_dns_name
- - ec2_private_ip_address
- - ec2_publicIp
- - ec2_public_dns_name
- - ec2_ramdisk
- - ec2_reason
- - ec2_region
- - ec2_requester_id
- - ec2_root_device_name
- - ec2_root_device_type
- - ec2_security_group_ids
- - ec2_security_group_names
- - ec2_shutdown_state
- - ec2_sourceDestCheck
- - ec2_spot_instance_request_id
- - ec2_state
- - ec2_state_code
- - ec2_state_reason
- - ec2_status
- - ec2_subnet_id
- - ec2_tenancy
- - ec2_virtualization_type
- - ec2_vpc_id
-
-These variables are pulled out of a boto.ec2.instance object. There is a lack of
-consistency with variable spellings (camelCase and underscores) since this
-just loops through all variables the object exposes. It is preferred to use the
-ones with underscores when multiple exist.
-
-In addition, if an instance has AWS Tags associated with it, each tag is a new
-variable named:
- - ec2_tag_[Key] = [Value]
-
-Security groups are comma-separated in 'ec2_security_group_ids' and
-'ec2_security_group_names'.
-'''
-
-# (c) 2012, Peter Sankauskas
-#
-# This file is part of Ansible,
-#
-# Ansible is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# Ansible is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with Ansible.  If not, see <http://www.gnu.org/licenses/>.
-
-######################################################################
-
-import sys
-import os
-import argparse
-import re
-from time import time
-import boto
-from boto import ec2
-from boto import rds
-from boto import elasticache
-from boto import route53
-import six
-
-from six.moves import configparser
-from collections import defaultdict
-
-try:
-    import json
-except ImportError:
-    import simplejson as json
-
-
-class Ec2Inventory(object):
-
-    def _empty_inventory(self):
-        return {"_meta" : {"hostvars" : {}}}
-
-    def __init__(self):
-        ''' Main execution path '''
-
-        # Inventory grouped by instance IDs, tags, security groups, regions,
-        # and availability zones
-        self.inventory = self._empty_inventory()
-
-        # Index of hostname (address) to instance ID
-        self.index = {}
-
-        # Boto profile to use (if any)
-        self.boto_profile = None
-
-        # Read settings and parse CLI arguments
-        self.parse_cli_args()
-        self.read_settings()
-
-        # Make sure that profile_name is not passed at all if not set
-        # as pre 2.24 boto will fall over otherwise
-        if self.boto_profile:
-            if not hasattr(boto.ec2.EC2Connection, 'profile_name'):
-                self.fail_with_error("boto version must be >= 2.24 to use profile")
-
-        # Cache
-        if self.args.refresh_cache:
-            self.do_api_calls_update_cache()
-        elif not self.is_cache_valid():
-            self.do_api_calls_update_cache()
-
-        # Data to print
-        if self.args.host:
-            data_to_print = self.get_host_info()
-
-        elif self.args.list:
-            # Display list of instances for inventory
-            if self.inventory == self._empty_inventory():
-                data_to_print = self.get_inventory_from_cache()
-            else:
-                data_to_print = self.json_format_dict(self.inventory, True)
-
-        print(data_to_print)
-
-
-    def is_cache_valid(self):
-        ''' Determines if the cache files have expired, or if it is still valid '''
-
-        if os.path.isfile(self.cache_path_cache):
-            mod_time = os.path.getmtime(self.cache_path_cache)
-            current_time = time()
-            if (mod_time + self.cache_max_age) > current_time:
-                if os.path.isfile(self.cache_path_index):
-                    return True
-
-        return False
-
-
-    def read_settings(self):
-        ''' Reads the settings from the ec2.ini file '''
-        if six.PY3:
-            config = configparser.ConfigParser()
-        else:
-            config = configparser.SafeConfigParser()
-        ec2_default_ini_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'ec2.ini')
-        ec2_ini_path = os.path.expanduser(os.path.expandvars(os.environ.get('EC2_INI_PATH', ec2_default_ini_path)))
-        config.read(ec2_ini_path)
-
-        # is eucalyptus?
-        self.eucalyptus_host = None
-        self.eucalyptus = False
-        if config.has_option('ec2', 'eucalyptus'):
-            self.eucalyptus = config.getboolean('ec2', 'eucalyptus')
-        if self.eucalyptus and config.has_option('ec2', 'eucalyptus_host'):
-            self.eucalyptus_host = config.get('ec2', 'eucalyptus_host')
-
-        # Regions
-        self.regions = []
-        configRegions = config.get('ec2', 'regions')
-        configRegions_exclude = config.get('ec2', 'regions_exclude')
-        if (configRegions == 'all'):
-            if self.eucalyptus_host:
-                self.regions.append(boto.connect_euca(host=self.eucalyptus_host).region.name)
-            else:
-                for regionInfo in ec2.regions():
-                    if regionInfo.name not in configRegions_exclude:
-                        self.regions.append(regionInfo.name)
-        else:
-            self.regions = configRegions.split(",")
-
-        # Destination addresses
-        self.destination_variable = config.get('ec2', 'destination_variable')
-        self.vpc_destination_variable = config.get('ec2', 'vpc_destination_variable')
-
-        if config.has_option('ec2', 'hostname_variable'):
-            self.hostname_variable = config.get('ec2', 'hostname_variable')
-        else:
-            self.hostname_variable = None
-
-        if config.has_option('ec2', 'destination_format') and \
-                config.has_option('ec2', 'destination_format_tags'):
-            self.destination_format = config.get('ec2', 'destination_format')
-            self.destination_format_tags = config.get('ec2', 'destination_format_tags').split(',')
-        else:
-            self.destination_format = None
-            self.destination_format_tags = None
-
-        # Route53
-        self.route53_enabled = config.getboolean('ec2', 'route53')
-        self.route53_excluded_zones = []
-        if config.has_option('ec2', 'route53_excluded_zones'):
-            self.route53_excluded_zones.extend(
-                    config.get('ec2', 'route53_excluded_zones', '').split(','))
-
-        # Include RDS instances?
-        self.rds_enabled = True
-        if config.has_option('ec2', 'rds'):
-            self.rds_enabled = config.getboolean('ec2', 'rds')
-
-        # Include ElastiCache instances?
-        self.elasticache_enabled = True
-        if config.has_option('ec2', 'elasticache'):
-            self.elasticache_enabled = config.getboolean('ec2', 'elasticache')
-
-        # Return all EC2 instances?
-        if config.has_option('ec2', 'all_instances'):
-            self.all_instances = config.getboolean('ec2', 'all_instances')
-        else:
-            self.all_instances = False
-
-        # Instance states to be gathered in inventory. Default is 'running'.
-        # Setting 'all_instances' to 'yes' overrides this option.
-        ec2_valid_instance_states = [
-            'pending',
-            'running',
-            'shutting-down',
-            'terminated',
-            'stopping',
-            'stopped'
-        ]
-        self.ec2_instance_states = []
-        if self.all_instances:
-            self.ec2_instance_states = ec2_valid_instance_states
-        elif config.has_option('ec2', 'instance_states'):
-            for instance_state in config.get('ec2', 'instance_states').split(','):
-                instance_state = instance_state.strip()
-                if instance_state not in ec2_valid_instance_states:
-                    continue
-                self.ec2_instance_states.append(instance_state)
-        else:
-            self.ec2_instance_states = ['running']
-
-        # Return all RDS instances? (if RDS is enabled)
-        if config.has_option('ec2', 'all_rds_instances') and self.rds_enabled:
-            self.all_rds_instances = config.getboolean('ec2', 'all_rds_instances')
-        else:
-            self.all_rds_instances = False
-
-        # Return all ElastiCache replication groups? (if ElastiCache is enabled)
-        if config.has_option('ec2', 'all_elasticache_replication_groups') and self.elasticache_enabled:
-            self.all_elasticache_replication_groups = config.getboolean('ec2', 'all_elasticache_replication_groups')
-        else:
-            self.all_elasticache_replication_groups = False
-
-        # Return all ElastiCache clusters? (if ElastiCache is enabled)
-        if config.has_option('ec2', 'all_elasticache_clusters') and self.elasticache_enabled:
-            self.all_elasticache_clusters = config.getboolean('ec2', 'all_elasticache_clusters')
-        else:
-            self.all_elasticache_clusters = False
-
-        # Return all ElastiCache nodes? (if ElastiCache is enabled)
-        if config.has_option('ec2', 'all_elasticache_nodes') and self.elasticache_enabled:
-            self.all_elasticache_nodes = config.getboolean('ec2', 'all_elasticache_nodes')
-        else:
-            self.all_elasticache_nodes = False
-
-        # boto configuration profile (prefer CLI argument)
-        self.boto_profile = self.args.boto_profile
-        if config.has_option('ec2', 'boto_profile') and not self.boto_profile:
-            self.boto_profile = config.get('ec2', 'boto_profile')
-
-        # Cache related
-        cache_dir = os.path.expanduser(config.get('ec2', 'cache_path'))
-        if self.boto_profile:
-            cache_dir = os.path.join(cache_dir, 'profile_' + self.boto_profile)
-        if not os.path.exists(cache_dir):
-            os.makedirs(cache_dir)
-
-        cache_name = 'ansible-ec2'
-        aws_profile = lambda: (self.boto_profile or
-                               os.environ.get('AWS_PROFILE') or
-                               os.environ.get('AWS_ACCESS_KEY_ID'))
-        if aws_profile():
-            cache_name = '%s-%s' % (cache_name, aws_profile())
-        self.cache_path_cache = cache_dir + "/%s.cache" % cache_name
-        self.cache_path_index = cache_dir + "/%s.index" % cache_name
-        self.cache_max_age = config.getint('ec2', 'cache_max_age')
-
-        if config.has_option('ec2', 'expand_csv_tags'):
-            self.expand_csv_tags = config.getboolean('ec2', 'expand_csv_tags')
-        else:
-            self.expand_csv_tags = False
-
-        # Configure nested groups instead of flat namespace.
-        if config.has_option('ec2', 'nested_groups'):
-            self.nested_groups = config.getboolean('ec2', 'nested_groups')
-        else:
-            self.nested_groups = False
-
-        # Replace dash or not in group names
-        if config.has_option('ec2', 'replace_dash_in_groups'):
-            self.replace_dash_in_groups = config.getboolean('ec2', 'replace_dash_in_groups')
-        else:
-            self.replace_dash_in_groups = True
-
-        # Configure which groups should be created.
-        group_by_options = [
-            'group_by_instance_id',
-            'group_by_region',
-            'group_by_availability_zone',
-            'group_by_ami_id',
-            'group_by_instance_type',
-            'group_by_key_pair',
-            'group_by_vpc_id',
-            'group_by_security_group',
-            'group_by_tag_keys',
-            'group_by_tag_none',
-            'group_by_route53_names',
-            'group_by_rds_engine',
-            'group_by_rds_parameter_group',
-            'group_by_elasticache_engine',
-            'group_by_elasticache_cluster',
-            'group_by_elasticache_parameter_group',
-            'group_by_elasticache_replication_group',
-        ]
-        for option in group_by_options:
-            if config.has_option('ec2', option):
-                setattr(self, option, config.getboolean('ec2', option))
-            else:
-                setattr(self, option, True)
-
-        # Do we need to just include hosts that match a pattern?
-        try:
-            pattern_include = config.get('ec2', 'pattern_include')
-            if pattern_include and len(pattern_include) > 0:
-                self.pattern_include = re.compile(pattern_include)
-            else:
-                self.pattern_include = None
-        except configparser.NoOptionError:
-            self.pattern_include = None
-
-        # Do we need to exclude hosts that match a pattern?
-        try:
-            pattern_exclude = config.get('ec2', 'pattern_exclude');
-            if pattern_exclude and len(pattern_exclude) > 0:
-                self.pattern_exclude = re.compile(pattern_exclude)
-            else:
-                self.pattern_exclude = None
-        except configparser.NoOptionError:
-            self.pattern_exclude = None
-
-        # Instance filters (see boto and EC2 API docs). Ignore invalid filters.
-        self.ec2_instance_filters = defaultdict(list)
-        if config.has_option('ec2', 'instance_filters'):
-
-            filters = [f for f in config.get('ec2', 'instance_filters').split(',') if f]
-
-            for instance_filter in filters:
-                instance_filter = instance_filter.strip()
-                if not instance_filter or '=' not in instance_filter:
-                    continue
-                filter_key, filter_value = [x.strip() for x in instance_filter.split('=', 1)]
-                if not filter_key:
-                    continue
-                self.ec2_instance_filters[filter_key].append(filter_value)
-
-    def parse_cli_args(self):
-        ''' Command line argument processing '''
-
-        parser = argparse.ArgumentParser(description='Produce an Ansible Inventory file based on EC2')
-        parser.add_argument('--list', action='store_true', default=True,
-                            help='List instances (default: True)')
-        parser.add_argument('--host', action='store',
-                            help='Get all the variables about a specific instance')
-        parser.add_argument('--refresh-cache', action='store_true', default=False,
-                            help='Force refresh of cache by making API requests to EC2 (default: False - use cache files)')
-        parser.add_argument('--profile', '--boto-profile', action='store', dest='boto_profile',
-                            help='Use boto profile for connections to EC2')
-        self.args = parser.parse_args()
-
-
-    def do_api_calls_update_cache(self):
-        ''' Do API calls to each region, and save data in cache files '''
-
-        if self.route53_enabled:
-            self.get_route53_records()
-
-        for region in self.regions:
-            self.get_instances_by_region(region)
-            if self.rds_enabled:
-                self.get_rds_instances_by_region(region)
-            if self.elasticache_enabled:
-                self.get_elasticache_clusters_by_region(region)
-                self.get_elasticache_replication_groups_by_region(region)
-
-        self.write_to_cache(self.inventory, self.cache_path_cache)
-        self.write_to_cache(self.index, self.cache_path_index)
-
-    def connect(self, region):
-        ''' create connection to api server'''
-        if self.eucalyptus:
-            conn = boto.connect_euca(host=self.eucalyptus_host)
-            conn.APIVersion = '2010-08-31'
-        else:
-            conn = self.connect_to_aws(ec2, region)
-        return conn
-
-    def boto_fix_security_token_in_profile(self, connect_args):
-        ''' monkey patch for boto issue boto/boto#2100 '''
-        profile = 'profile ' + self.boto_profile
-        if boto.config.has_option(profile, 'aws_security_token'):
-            connect_args['security_token'] = boto.config.get(profile, 'aws_security_token')
-        return connect_args
-
-    def connect_to_aws(self, module, region):
-        connect_args = {}
-
-        # only pass the profile name if it's set (as it is not supported by older boto versions)
-        if self.boto_profile:
-            connect_args['profile_name'] = self.boto_profile
-            self.boto_fix_security_token_in_profile(connect_args)
-
-        conn = module.connect_to_region(region, **connect_args)
-        # connect_to_region will fail "silently" by returning None if the region name is wrong or not supported
-        if conn is None:
-            self.fail_with_error("region name: %s likely not supported, or AWS is down.  connection to region failed." % region)
-        return conn
-
-    def get_instances_by_region(self, region):
-        ''' Makes an AWS EC2 API call to the list of instances in a particular
-        region '''
-
-        try:
-            conn = self.connect(region)
-            reservations = []
-            if self.ec2_instance_filters:
-                for filter_key, filter_values in self.ec2_instance_filters.items():
-                    reservations.extend(conn.get_all_instances(filters = { filter_key : filter_values }))
-            else:
-                reservations = conn.get_all_instances()
-
-            for reservation in reservations:
-                for instance in reservation.instances:
-                    self.add_instance(instance, region)
-
-        except boto.exception.BotoServerError as e:
-            if e.error_code == 'AuthFailure':
-                error = self.get_auth_error_message()
-            else:
-                backend = 'Eucalyptus' if self.eucalyptus else 'AWS'
-                error = "Error connecting to %s backend.\n%s" % (backend, e.message)
-            self.fail_with_error(error, 'getting EC2 instances')
-
-    def get_rds_instances_by_region(self, region):
-        ''' Makes an AWS API call to the list of RDS instances in a particular
-        region '''
-
-        try:
-            conn = self.connect_to_aws(rds, region)
-            if conn:
-                marker = None
-                while True:
-                    instances = conn.get_all_dbinstances(marker=marker)
-                    marker = instances.marker
-                    for instance in instances:
-                        self.add_rds_instance(instance, region)
-                    if not marker:
-                        break
-        except boto.exception.BotoServerError as e:
-            error = e.reason
-
-            if e.error_code == 'AuthFailure':
-                error = self.get_auth_error_message()
-            if not e.reason == "Forbidden":
-                error = "Looks like AWS RDS is down:\n%s" % e.message
-            self.fail_with_error(error, 'getting RDS instances')
-
-    def get_elasticache_clusters_by_region(self, region):
-        ''' Makes an AWS API call to the list of ElastiCache clusters (with
-        nodes' info) in a particular region.'''
-
-        # ElastiCache boto module doesn't provide a get_all_intances method,
-        # that's why we need to call describe directly (it would be called by
-        # the shorthand method anyway...)
-        try:
-            conn = self.connect_to_aws(elasticache, region)
-            if conn:
-                # show_cache_node_info = True
-                # because we also want nodes' information
-                response = conn.describe_cache_clusters(None, None, None, True)
-
-        except boto.exception.BotoServerError as e:
-            error = e.reason
-
-            if e.error_code == 'AuthFailure':
-                error = self.get_auth_error_message()
-            if not e.reason == "Forbidden":
-                error = "Looks like AWS ElastiCache is down:\n%s" % e.message
-            self.fail_with_error(error, 'getting ElastiCache clusters')
-
-        try:
-            # Boto also doesn't provide wrapper classes to CacheClusters or
-            # CacheNodes. Because of that wo can't make use of the get_list
-            # method in the AWSQueryConnection. Let's do the work manually
-            clusters = response['DescribeCacheClustersResponse']['DescribeCacheClustersResult']['CacheClusters']
-
-        except KeyError as e:
-            error = "ElastiCache query to AWS failed (unexpected format)."
-            self.fail_with_error(error, 'getting ElastiCache clusters')
-
-        for cluster in clusters:
-            self.add_elasticache_cluster(cluster, region)
-
-    def get_elasticache_replication_groups_by_region(self, region):
-        ''' Makes an AWS API call to the list of ElastiCache replication groups
-        in a particular region.'''
-
-        # ElastiCache boto module doesn't provide a get_all_intances method,
-        # that's why we need to call describe directly (it would be called by
-        # the shorthand method anyway...)
-        try:
-            conn = self.connect_to_aws(elasticache, region)
-            if conn:
-                response = conn.describe_replication_groups()
-
-        except boto.exception.BotoServerError as e:
-            error = e.reason
-
-            if e.error_code == 'AuthFailure':
-                error = self.get_auth_error_message()
-            if not e.reason == "Forbidden":
-                error = "Looks like AWS ElastiCache [Replication Groups] is down:\n%s" % e.message
-            self.fail_with_error(error, 'getting ElastiCache clusters')
-
-        try:
-            # Boto also doesn't provide wrapper classes to ReplicationGroups
-            # Because of that wo can't make use of the get_list method in the
-            # AWSQueryConnection. Let's do the work manually
-            replication_groups = response['DescribeReplicationGroupsResponse']['DescribeReplicationGroupsResult']['ReplicationGroups']
-
-        except KeyError as e:
-            error = "ElastiCache [Replication Groups] query to AWS failed (unexpected format)."
-            self.fail_with_error(error, 'getting ElastiCache clusters')
-
-        for replication_group in replication_groups:
-            self.add_elasticache_replication_group(replication_group, region)
-
-    def get_auth_error_message(self):
-        ''' create an informative error message if there is an issue authenticating'''
-        errors = ["Authentication error retrieving ec2 inventory."]
-        if None in [os.environ.get('AWS_ACCESS_KEY_ID'), os.environ.get('AWS_SECRET_ACCESS_KEY')]:
-            errors.append(' - No AWS_ACCESS_KEY_ID or AWS_SECRET_ACCESS_KEY environment vars found')
-        else:
-            errors.append(' - AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY environment vars found but may not be correct')
-
-        boto_paths = ['/etc/boto.cfg', '~/.boto', '~/.aws/credentials']
-        boto_config_found = list(p for p in boto_paths if os.path.isfile(os.path.expanduser(p)))
-        if len(boto_config_found) > 0:
-            errors.append(" - Boto configs found at '%s', but the credentials contained may not be correct" % ', '.join(boto_config_found))
-        else:
-            errors.append(" - No Boto config found at any expected location '%s'" % ', '.join(boto_paths))
-
-        return '\n'.join(errors)
-
-    def fail_with_error(self, err_msg, err_operation=None):
-        '''log an error to std err for ansible-playbook to consume and exit'''
-        if err_operation:
-            err_msg = 'ERROR: "{err_msg}", while: {err_operation}'.format(
-                    err_msg=err_msg, err_operation=err_operation)
-        sys.stderr.write(err_msg)
-        sys.exit(1)
-
-    def get_instance(self, region, instance_id):
-        conn = self.connect(region)
-
-        reservations = conn.get_all_instances([instance_id])
-        for reservation in reservations:
-            for instance in reservation.instances:
-                return instance
-
-    def add_instance(self, instance, region):
-        ''' Adds an instance to the inventory and index, as long as it is
-        addressable '''
-
-        # Only return instances with desired instance states
-        if instance.state not in self.ec2_instance_states:
-            return
-
-        # Select the best destination address
-        if self.destination_format and self.destination_format_tags:
-            dest = self.destination_format.format(*[ getattr(instance, 'tags').get(tag, '') for tag in self.destination_format_tags ])
-        elif instance.subnet_id:
-            dest = getattr(instance, self.vpc_destination_variable, None)
-            if dest is None:
-                dest = getattr(instance, 'tags').get(self.vpc_destination_variable, None)
-        else:
-            dest = getattr(instance, self.destination_variable, None)
-            if dest is None:
-                dest = getattr(instance, 'tags').get(self.destination_variable, None)
-
-        if not dest:
-            # Skip instances we cannot address (e.g. private VPC subnet)
-            return
-
-        # Set the inventory name
-        hostname = None
-        if self.hostname_variable:
-            if self.hostname_variable.startswith('tag_'):
-                hostname = instance.tags.get(self.hostname_variable[4:], None)
-            else:
-                hostname = getattr(instance, self.hostname_variable)
-
-        # If we can't get a nice hostname, use the destination address
-        if not hostname:
-            hostname = dest
-        else:
-            hostname = self.to_safe(hostname).lower()
-
-        # if we only want to include hosts that match a pattern, skip those that don't
-        if self.pattern_include and not self.pattern_include.match(hostname):
-            return
-
-        # if we need to exclude hosts that match a pattern, skip those
-        if self.pattern_exclude and self.pattern_exclude.match(hostname):
-            return
-
-        # Add to index
-        self.index[hostname] = [region, instance.id]
-
-        # Inventory: Group by instance ID (always a group of 1)
-        if self.group_by_instance_id:
-            self.inventory[instance.id] = [hostname]
-            if self.nested_groups:
-                self.push_group(self.inventory, 'instances', instance.id)
-
-        # Inventory: Group by region
-        if self.group_by_region:
-            self.push(self.inventory, region, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'regions', region)
-
-        # Inventory: Group by availability zone
-        if self.group_by_availability_zone:
-            self.push(self.inventory, instance.placement, hostname)
-            if self.nested_groups:
-                if self.group_by_region:
-                    self.push_group(self.inventory, region, instance.placement)
-                self.push_group(self.inventory, 'zones', instance.placement)
-
-        # Inventory: Group by Amazon Machine Image (AMI) ID
-        if self.group_by_ami_id:
-            ami_id = self.to_safe(instance.image_id)
-            self.push(self.inventory, ami_id, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'images', ami_id)
-
-        # Inventory: Group by instance type
-        if self.group_by_instance_type:
-            type_name = self.to_safe('type_' + instance.instance_type)
-            self.push(self.inventory, type_name, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'types', type_name)
-
-        # Inventory: Group by key pair
-        if self.group_by_key_pair and instance.key_name:
-            key_name = self.to_safe('key_' + instance.key_name)
-            self.push(self.inventory, key_name, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'keys', key_name)
-
-        # Inventory: Group by VPC
-        if self.group_by_vpc_id and instance.vpc_id:
-            vpc_id_name = self.to_safe('vpc_id_' + instance.vpc_id)
-            self.push(self.inventory, vpc_id_name, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'vpcs', vpc_id_name)
-
-        # Inventory: Group by security group
-        if self.group_by_security_group:
-            try:
-                for group in instance.groups:
-                    key = self.to_safe("security_group_" + group.name)
-                    self.push(self.inventory, key, hostname)
-                    if self.nested_groups:
-                        self.push_group(self.inventory, 'security_groups', key)
-            except AttributeError:
-                self.fail_with_error('\n'.join(['Package boto seems a bit older.',
-                                                'Please upgrade boto >= 2.3.0.']))
-
-        # Inventory: Group by tag keys
-        if self.group_by_tag_keys:
-            for k, v in instance.tags.items():
-                if self.expand_csv_tags and v and ',' in v:
-                    values = map(lambda x: x.strip(), v.split(','))
-                else:
-                    values = [v]
-
-                for v in values:
-                    if v:
-                        key = self.to_safe("tag_" + k + "=" + v)
-                    else:
-                        key = self.to_safe("tag_" + k)
-                    self.push(self.inventory, key, hostname)
-                    if self.nested_groups:
-                        self.push_group(self.inventory, 'tags', self.to_safe("tag_" + k))
-                        if v:
-                            self.push_group(self.inventory, self.to_safe("tag_" + k), key)
-
-        # Inventory: Group by Route53 domain names if enabled
-        if self.route53_enabled and self.group_by_route53_names:
-            route53_names = self.get_instance_route53_names(instance)
-            for name in route53_names:
-                self.push(self.inventory, name, hostname)
-                if self.nested_groups:
-                    self.push_group(self.inventory, 'route53', name)
-
-        # Global Tag: instances without tags
-        if self.group_by_tag_none and len(instance.tags) == 0:
-            self.push(self.inventory, 'tag_none', hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'tags', 'tag_none')
-
-        # Global Tag: tag all EC2 instances
-        self.push(self.inventory, 'ec2', hostname)
-
-        self.inventory["_meta"]["hostvars"][hostname] = self.get_host_info_dict_from_instance(instance)
-        self.inventory["_meta"]["hostvars"][hostname]['ansible_ssh_host'] = dest
-
-
-    def add_rds_instance(self, instance, region):
-        ''' Adds an RDS instance to the inventory and index, as long as it is
-        addressable '''
-
-        # Only want available instances unless all_rds_instances is True
-        if not self.all_rds_instances and instance.status != 'available':
-            return
-
-        # Select the best destination address
-        dest = instance.endpoint[0]
-
-        if not dest:
-            # Skip instances we cannot address (e.g. private VPC subnet)
-            return
-
-        # Set the inventory name
-        hostname = None
-        if self.hostname_variable:
-            if self.hostname_variable.startswith('tag_'):
-                hostname = instance.tags.get(self.hostname_variable[4:], None)
-            else:
-                hostname = getattr(instance, self.hostname_variable)
-
-        # If we can't get a nice hostname, use the destination address
-        if not hostname:
-            hostname = dest
-
-        hostname = self.to_safe(hostname).lower()
-
-        # Add to index
-        self.index[hostname] = [region, instance.id]
-
-        # Inventory: Group by instance ID (always a group of 1)
-        if self.group_by_instance_id:
-            self.inventory[instance.id] = [hostname]
-            if self.nested_groups:
-                self.push_group(self.inventory, 'instances', instance.id)
-
-        # Inventory: Group by region
-        if self.group_by_region:
-            self.push(self.inventory, region, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'regions', region)
-
-        # Inventory: Group by availability zone
-        if self.group_by_availability_zone:
-            self.push(self.inventory, instance.availability_zone, hostname)
-            if self.nested_groups:
-                if self.group_by_region:
-                    self.push_group(self.inventory, region, instance.availability_zone)
-                self.push_group(self.inventory, 'zones', instance.availability_zone)
-
-        # Inventory: Group by instance type
-        if self.group_by_instance_type:
-            type_name = self.to_safe('type_' + instance.instance_class)
-            self.push(self.inventory, type_name, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'types', type_name)
-
-        # Inventory: Group by VPC
-        if self.group_by_vpc_id and instance.subnet_group and instance.subnet_group.vpc_id:
-            vpc_id_name = self.to_safe('vpc_id_' + instance.subnet_group.vpc_id)
-            self.push(self.inventory, vpc_id_name, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'vpcs', vpc_id_name)
-
-        # Inventory: Group by security group
-        if self.group_by_security_group:
-            try:
-                if instance.security_group:
-                    key = self.to_safe("security_group_" + instance.security_group.name)
-                    self.push(self.inventory, key, hostname)
-                    if self.nested_groups:
-                        self.push_group(self.inventory, 'security_groups', key)
-
-            except AttributeError:
-                self.fail_with_error('\n'.join(['Package boto seems a bit older.',
-                                                'Please upgrade boto >= 2.3.0.']))
-
-
-        # Inventory: Group by engine
-        if self.group_by_rds_engine:
-            self.push(self.inventory, self.to_safe("rds_" + instance.engine), hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'rds_engines', self.to_safe("rds_" + instance.engine))
-
-        # Inventory: Group by parameter group
-        if self.group_by_rds_parameter_group:
-            self.push(self.inventory, self.to_safe("rds_parameter_group_" + instance.parameter_group.name), hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'rds_parameter_groups', self.to_safe("rds_parameter_group_" + instance.parameter_group.name))
-
-        # Global Tag: all RDS instances
-        self.push(self.inventory, 'rds', hostname)
-
-        self.inventory["_meta"]["hostvars"][hostname] = self.get_host_info_dict_from_instance(instance)
-        self.inventory["_meta"]["hostvars"][hostname]['ansible_ssh_host'] = dest
-
-    def add_elasticache_cluster(self, cluster, region):
-        ''' Adds an ElastiCache cluster to the inventory and index, as long as
-        it's nodes are addressable '''
-
-        # Only want available clusters unless all_elasticache_clusters is True
-        if not self.all_elasticache_clusters and cluster['CacheClusterStatus'] != 'available':
-            return
-
-        # Select the best destination address
-        if 'ConfigurationEndpoint' in cluster and cluster['ConfigurationEndpoint']:
-            # Memcached cluster
-            dest = cluster['ConfigurationEndpoint']['Address']
-            is_redis = False
-        else:
-            # Redis sigle node cluster
-            # Because all Redis clusters are single nodes, we'll merge the
-            # info from the cluster with info about the node
-            dest = cluster['CacheNodes'][0]['Endpoint']['Address']
-            is_redis = True
-
-        if not dest:
-            # Skip clusters we cannot address (e.g. private VPC subnet)
-            return
-
-        # Add to index
-        self.index[dest] = [region, cluster['CacheClusterId']]
-
-        # Inventory: Group by instance ID (always a group of 1)
-        if self.group_by_instance_id:
-            self.inventory[cluster['CacheClusterId']] = [dest]
-            if self.nested_groups:
-                self.push_group(self.inventory, 'instances', cluster['CacheClusterId'])
-
-        # Inventory: Group by region
-        if self.group_by_region and not is_redis:
-            self.push(self.inventory, region, dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'regions', region)
-
-        # Inventory: Group by availability zone
-        if self.group_by_availability_zone and not is_redis:
-            self.push(self.inventory, cluster['PreferredAvailabilityZone'], dest)
-            if self.nested_groups:
-                if self.group_by_region:
-                    self.push_group(self.inventory, region, cluster['PreferredAvailabilityZone'])
-                self.push_group(self.inventory, 'zones', cluster['PreferredAvailabilityZone'])
-
-        # Inventory: Group by node type
-        if self.group_by_instance_type and not is_redis:
-            type_name = self.to_safe('type_' + cluster['CacheNodeType'])
-            self.push(self.inventory, type_name, dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'types', type_name)
-
-        # Inventory: Group by VPC (information not available in the current
-        # AWS API version for ElastiCache)
-
-        # Inventory: Group by security group
-        if self.group_by_security_group and not is_redis:
-
-            # Check for the existence of the 'SecurityGroups' key and also if
-            # this key has some value. When the cluster is not placed in a SG
-            # the query can return None here and cause an error.
-            if 'SecurityGroups' in cluster and cluster['SecurityGroups'] is not None:
-                for security_group in cluster['SecurityGroups']:
-                    key = self.to_safe("security_group_" + security_group['SecurityGroupId'])
-                    self.push(self.inventory, key, dest)
-                    if self.nested_groups:
-                        self.push_group(self.inventory, 'security_groups', key)
-
-        # Inventory: Group by engine
-        if self.group_by_elasticache_engine and not is_redis:
-            self.push(self.inventory, self.to_safe("elasticache_" + cluster['Engine']), dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'elasticache_engines', self.to_safe(cluster['Engine']))
-
-        # Inventory: Group by parameter group
-        if self.group_by_elasticache_parameter_group:
-            self.push(self.inventory, self.to_safe("elasticache_parameter_group_" + cluster['CacheParameterGroup']['CacheParameterGroupName']), dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'elasticache_parameter_groups', self.to_safe(cluster['CacheParameterGroup']['CacheParameterGroupName']))
-
-        # Inventory: Group by replication group
-        if self.group_by_elasticache_replication_group and 'ReplicationGroupId' in cluster and cluster['ReplicationGroupId']:
-            self.push(self.inventory, self.to_safe("elasticache_replication_group_" + cluster['ReplicationGroupId']), dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'elasticache_replication_groups', self.to_safe(cluster['ReplicationGroupId']))
-
-        # Global Tag: all ElastiCache clusters
-        self.push(self.inventory, 'elasticache_clusters', cluster['CacheClusterId'])
-
-        host_info = self.get_host_info_dict_from_describe_dict(cluster)
-
-        self.inventory["_meta"]["hostvars"][dest] = host_info
-
-        # Add the nodes
-        for node in cluster['CacheNodes']:
-            self.add_elasticache_node(node, cluster, region)
-
-    def add_elasticache_node(self, node, cluster, region):
-        ''' Adds an ElastiCache node to the inventory and index, as long as
-        it is addressable '''
-
-        # Only want available nodes unless all_elasticache_nodes is True
-        if not self.all_elasticache_nodes and node['CacheNodeStatus'] != 'available':
-            return
-
-        # Select the best destination address
-        dest = node['Endpoint']['Address']
-
-        if not dest:
-            # Skip nodes we cannot address (e.g. private VPC subnet)
-            return
-
-        node_id = self.to_safe(cluster['CacheClusterId'] + '_' + node['CacheNodeId'])
-
-        # Add to index
-        self.index[dest] = [region, node_id]
-
-        # Inventory: Group by node ID (always a group of 1)
-        if self.group_by_instance_id:
-            self.inventory[node_id] = [dest]
-            if self.nested_groups:
-                self.push_group(self.inventory, 'instances', node_id)
-
-        # Inventory: Group by region
-        if self.group_by_region:
-            self.push(self.inventory, region, dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'regions', region)
-
-        # Inventory: Group by availability zone
-        if self.group_by_availability_zone:
-            self.push(self.inventory, cluster['PreferredAvailabilityZone'], dest)
-            if self.nested_groups:
-                if self.group_by_region:
-                    self.push_group(self.inventory, region, cluster['PreferredAvailabilityZone'])
-                self.push_group(self.inventory, 'zones', cluster['PreferredAvailabilityZone'])
-
-        # Inventory: Group by node type
-        if self.group_by_instance_type:
-            type_name = self.to_safe('type_' + cluster['CacheNodeType'])
-            self.push(self.inventory, type_name, dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'types', type_name)
-
-        # Inventory: Group by VPC (information not available in the current
-        # AWS API version for ElastiCache)
-
-        # Inventory: Group by security group
-        if self.group_by_security_group:
-
-            # Check for the existence of the 'SecurityGroups' key and also if
-            # this key has some value. When the cluster is not placed in a SG
-            # the query can return None here and cause an error.
-            if 'SecurityGroups' in cluster and cluster['SecurityGroups'] is not None:
-                for security_group in cluster['SecurityGroups']:
-                    key = self.to_safe("security_group_" + security_group['SecurityGroupId'])
-                    self.push(self.inventory, key, dest)
-                    if self.nested_groups:
-                        self.push_group(self.inventory, 'security_groups', key)
-
-        # Inventory: Group by engine
-        if self.group_by_elasticache_engine:
-            self.push(self.inventory, self.to_safe("elasticache_" + cluster['Engine']), dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'elasticache_engines', self.to_safe("elasticache_" + cluster['Engine']))
-
-        # Inventory: Group by parameter group (done at cluster level)
-
-        # Inventory: Group by replication group (done at cluster level)
-
-        # Inventory: Group by ElastiCache Cluster
-        if self.group_by_elasticache_cluster:
-            self.push(self.inventory, self.to_safe("elasticache_cluster_" + cluster['CacheClusterId']), dest)
-
-        # Global Tag: all ElastiCache nodes
-        self.push(self.inventory, 'elasticache_nodes', dest)
-
-        host_info = self.get_host_info_dict_from_describe_dict(node)
-
-        if dest in self.inventory["_meta"]["hostvars"]:
-            self.inventory["_meta"]["hostvars"][dest].update(host_info)
-        else:
-            self.inventory["_meta"]["hostvars"][dest] = host_info
-
-    def add_elasticache_replication_group(self, replication_group, region):
-        ''' Adds an ElastiCache replication group to the inventory and index '''
-
-        # Only want available clusters unless all_elasticache_replication_groups is True
-        if not self.all_elasticache_replication_groups and replication_group['Status'] != 'available':
-            return
-
-        # Select the best destination address (PrimaryEndpoint)
-        dest = replication_group['NodeGroups'][0]['PrimaryEndpoint']['Address']
-
-        if not dest:
-            # Skip clusters we cannot address (e.g. private VPC subnet)
-            return
-
-        # Add to index
-        self.index[dest] = [region, replication_group['ReplicationGroupId']]
-
-        # Inventory: Group by ID (always a group of 1)
-        if self.group_by_instance_id:
-            self.inventory[replication_group['ReplicationGroupId']] = [dest]
-            if self.nested_groups:
-                self.push_group(self.inventory, 'instances', replication_group['ReplicationGroupId'])
-
-        # Inventory: Group by region
-        if self.group_by_region:
-            self.push(self.inventory, region, dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'regions', region)
-
-        # Inventory: Group by availability zone (doesn't apply to replication groups)
-
-        # Inventory: Group by node type (doesn't apply to replication groups)
-
-        # Inventory: Group by VPC (information not available in the current
-        # AWS API version for replication groups
-
-        # Inventory: Group by security group (doesn't apply to replication groups)
-        # Check this value in cluster level
-
-        # Inventory: Group by engine (replication groups are always Redis)
-        if self.group_by_elasticache_engine:
-            self.push(self.inventory, 'elasticache_redis', dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'elasticache_engines', 'redis')
-
-        # Global Tag: all ElastiCache clusters
-        self.push(self.inventory, 'elasticache_replication_groups', replication_group['ReplicationGroupId'])
-
-        host_info = self.get_host_info_dict_from_describe_dict(replication_group)
-
-        self.inventory["_meta"]["hostvars"][dest] = host_info
-
-    def get_route53_records(self):
-        ''' Get and store the map of resource records to domain names that
-        point to them. '''
-
-        r53_conn = route53.Route53Connection()
-        all_zones = r53_conn.get_zones()
-
-        route53_zones = [ zone for zone in all_zones if zone.name[:-1]
-                          not in self.route53_excluded_zones ]
-
-        self.route53_records = {}
-
-        for zone in route53_zones:
-            rrsets = r53_conn.get_all_rrsets(zone.id)
-
-            for record_set in rrsets:
-                record_name = record_set.name
-
-                if record_name.endswith('.'):
-                    record_name = record_name[:-1]
-
-                for resource in record_set.resource_records:
-                    self.route53_records.setdefault(resource, set())
-                    self.route53_records[resource].add(record_name)
-
-
-    def get_instance_route53_names(self, instance):
-        ''' Check if an instance is referenced in the records we have from
-        Route53. If it is, return the list of domain names pointing to said
-        instance. If nothing points to it, return an empty list. '''
-
-        instance_attributes = [ 'public_dns_name', 'private_dns_name',
-                                'ip_address', 'private_ip_address' ]
-
-        name_list = set()
-
-        for attrib in instance_attributes:
-            try:
-                value = getattr(instance, attrib)
-            except AttributeError:
-                continue
-
-            if value in self.route53_records:
-                name_list.update(self.route53_records[value])
-
-        return list(name_list)
-
-    def get_host_info_dict_from_instance(self, instance):
-        instance_vars = {}
-        for key in vars(instance):
-            value = getattr(instance, key)
-            key = self.to_safe('ec2_' + key)
-
-            # Handle complex types
-            # state/previous_state changed to properties in boto in https://github.com/boto/boto/commit/a23c379837f698212252720d2af8dec0325c9518
-            if key == 'ec2__state':
-                instance_vars['ec2_state'] = instance.state or ''
-                instance_vars['ec2_state_code'] = instance.state_code
-            elif key == 'ec2__previous_state':
-                instance_vars['ec2_previous_state'] = instance.previous_state or ''
-                instance_vars['ec2_previous_state_code'] = instance.previous_state_code
-            elif type(value) in [int, bool]:
-                instance_vars[key] = value
-            elif isinstance(value, six.string_types):
-                instance_vars[key] = value.strip()
-            elif type(value) == type(None):
-                instance_vars[key] = ''
-            elif key == 'ec2_region':
-                instance_vars[key] = value.name
-            elif key == 'ec2__placement':
-                instance_vars['ec2_placement'] = value.zone
-            elif key == 'ec2_tags':
-                for k, v in value.items():
-                    if self.expand_csv_tags and ',' in v:
-                        v = map(lambda x: x.strip(), v.split(','))
-                    key = self.to_safe('ec2_tag_' + k)
-                    instance_vars[key] = v
-            elif key == 'ec2_groups':
-                group_ids = []
-                group_names = []
-                for group in value:
-                    group_ids.append(group.id)
-                    group_names.append(group.name)
-                instance_vars["ec2_security_group_ids"] = ','.join([str(i) for i in group_ids])
-                instance_vars["ec2_security_group_names"] = ','.join([str(i) for i in group_names])
-            else:
-                pass
-                # TODO Product codes if someone finds them useful
-                #print key
-                #print type(value)
-                #print value
-
-        return instance_vars
-
-    def get_host_info_dict_from_describe_dict(self, describe_dict):
-        ''' Parses the dictionary returned by the API call into a flat list
-            of parameters. This method should be used only when 'describe' is
-            used directly because Boto doesn't provide specific classes. '''
-
-        # I really don't agree with prefixing everything with 'ec2'
-        # because EC2, RDS and ElastiCache are different services.
-        # I'm just following the pattern used until now to not break any
-        # compatibility.
-
-        host_info = {}
-        for key in describe_dict:
-            value = describe_dict[key]
-            key = self.to_safe('ec2_' + self.uncammelize(key))
-
-            # Handle complex types
-
-            # Target: Memcached Cache Clusters
-            if key == 'ec2_configuration_endpoint' and value:
-                host_info['ec2_configuration_endpoint_address'] = value['Address']
-                host_info['ec2_configuration_endpoint_port'] = value['Port']
-
-            # Target: Cache Nodes and Redis Cache Clusters (single node)
-            if key == 'ec2_endpoint' and value:
-                host_info['ec2_endpoint_address'] = value['Address']
-                host_info['ec2_endpoint_port'] = value['Port']
-
-            # Target: Redis Replication Groups
-            if key == 'ec2_node_groups' and value:
-                host_info['ec2_endpoint_address'] = value[0]['PrimaryEndpoint']['Address']
-                host_info['ec2_endpoint_port'] = value[0]['PrimaryEndpoint']['Port']
-                replica_count = 0
-                for node in value[0]['NodeGroupMembers']:
-                    if node['CurrentRole'] == 'primary':
-                        host_info['ec2_primary_cluster_address'] = node['ReadEndpoint']['Address']
-                        host_info['ec2_primary_cluster_port'] = node['ReadEndpoint']['Port']
-                        host_info['ec2_primary_cluster_id'] = node['CacheClusterId']
-                    elif node['CurrentRole'] == 'replica':
-                        host_info['ec2_replica_cluster_address_'+ str(replica_count)] = node['ReadEndpoint']['Address']
-                        host_info['ec2_replica_cluster_port_'+ str(replica_count)] = node['ReadEndpoint']['Port']
-                        host_info['ec2_replica_cluster_id_'+ str(replica_count)] = node['CacheClusterId']
-                        replica_count += 1
-
-            # Target: Redis Replication Groups
-            if key == 'ec2_member_clusters' and value:
-                host_info['ec2_member_clusters'] = ','.join([str(i) for i in value])
-
-            # Target: All Cache Clusters
-            elif key == 'ec2_cache_parameter_group':
-                host_info["ec2_cache_node_ids_to_reboot"] = ','.join([str(i) for i in value['CacheNodeIdsToReboot']])
-                host_info['ec2_cache_parameter_group_name'] = value['CacheParameterGroupName']
-                host_info['ec2_cache_parameter_apply_status'] = value['ParameterApplyStatus']
-
-            # Target: Almost everything
-            elif key == 'ec2_security_groups':
-
-                # Skip if SecurityGroups is None
-                # (it is possible to have the key defined but no value in it).
-                if value is not None:
-                    sg_ids = []
-                    for sg in value:
-                        sg_ids.append(sg['SecurityGroupId'])
-                    host_info["ec2_security_group_ids"] = ','.join([str(i) for i in sg_ids])
-
-            # Target: Everything
-            # Preserve booleans and integers
-            elif type(value) in [int, bool]:
-                host_info[key] = value
-
-            # Target: Everything
-            # Sanitize string values
-            elif isinstance(value, six.string_types):
-                host_info[key] = value.strip()
-
-            # Target: Everything
-            # Replace None by an empty string
-            elif type(value) == type(None):
-                host_info[key] = ''
-
-            else:
-                # Remove non-processed complex types
-                pass
-
-        return host_info
-
-    def get_host_info(self):
-        ''' Get variables about a specific host '''
-
-        if len(self.index) == 0:
-            # Need to load index from cache
-            self.load_index_from_cache()
-
-        if not self.args.host in self.index:
-            # try updating the cache
-            self.do_api_calls_update_cache()
-            if not self.args.host in self.index:
-                # host might not exist anymore
-                return self.json_format_dict({}, True)
-
-        (region, instance_id) = self.index[self.args.host]
-
-        instance = self.get_instance(region, instance_id)
-        return self.json_format_dict(self.get_host_info_dict_from_instance(instance), True)
-
-    def push(self, my_dict, key, element):
-        ''' Push an element onto an array that may not have been defined in
-        the dict '''
-        group_info = my_dict.setdefault(key, [])
-        if isinstance(group_info, dict):
-            host_list = group_info.setdefault('hosts', [])
-            host_list.append(element)
-        else:
-            group_info.append(element)
-
-    def push_group(self, my_dict, key, element):
-        ''' Push a group as a child of another group. '''
-        parent_group = my_dict.setdefault(key, {})
-        if not isinstance(parent_group, dict):
-            parent_group = my_dict[key] = {'hosts': parent_group}
-        child_groups = parent_group.setdefault('children', [])
-        if element not in child_groups:
-            child_groups.append(element)
-
-    def get_inventory_from_cache(self):
-        ''' Reads the inventory from the cache file and returns it as a JSON
-        object '''
-
-        cache = open(self.cache_path_cache, 'r')
-        json_inventory = cache.read()
-        return json_inventory
-
-
-    def load_index_from_cache(self):
-        ''' Reads the index from the cache file sets self.index '''
-
-        cache = open(self.cache_path_index, 'r')
-        json_index = cache.read()
-        self.index = json.loads(json_index)
-
-
-    def write_to_cache(self, data, filename):
-        ''' Writes data in JSON format to a file '''
-
-        json_data = self.json_format_dict(data, True)
-        cache = open(filename, 'w')
-        cache.write(json_data)
-        cache.close()
-
-    def uncammelize(self, key):
-        temp = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', key)
-        return re.sub('([a-z0-9])([A-Z])', r'\1_\2', temp).lower()
-
-    def to_safe(self, word):
-        ''' Converts 'bad' characters in a string to underscores so they can be used as Ansible groups '''
-        regex = "[^A-Za-z0-9\_"
-        if not self.replace_dash_in_groups:
-            regex += "\-"
-        return re.sub(regex + "]", "_", word)
-
-    def json_format_dict(self, data, pretty=False):
-        ''' Converts a dict to a JSON object and dumps it as a formatted
-        string '''
-
-        if pretty:
-            return json.dumps(data, sort_keys=True, indent=2)
-        else:
-            return json.dumps(data)
-
-
-# Run the script
-Ec2Inventory()
diff --git a/edge-1601-dc3-dc4/inventory-dc3 b/edge-1601-dc3-dc4/inventory-dc3
deleted file mode 100644
index 0b97282..0000000
--- a/edge-1601-dc3-dc4/inventory-dc3
+++ /dev/null
@@ -1,74 +0,0 @@
-[tag_Name_dc3_n1]
-[tag_Name_dc3_n2]
-[tag_Name_dc3_n3]
-[tag_Name_dc3_n4]
-[tag_Name_dc3_n5]
-
-[planet:children]
-dc-1
-
-[dc-1:children]
-tag_Name_dc3_n1
-tag_Name_dc3_n2
-tag_Name_dc3_n3
-tag_Name_dc3_n4
-tag_Name_dc3_n5
-
-[ds:children]
-dc-1-ds
-
-[dc-1-ds:children]
-tag_Name_dc3_n2
-tag_Name_dc3_n3
-tag_Name_dc3_n4
-
-[ms:children]
-dc-1-ms
-
-[dc-1-ms:children]
-tag_Name_dc3_n1
-
-[ui:children]
-dc-1-ui
-
-[dc-1-ui:children]
-tag_Name_dc3_n1
-
-[ldap:children]
-dc-1-ldap
-
-[dc-1-ldap:children]
-tag_Name_dc3_n1
-
-[rmp:children]
-dc-1-rmp
-
-[dc-1-rmp:children]
-tag_Name_dc3_n3
-tag_Name_dc3_n4
-
-[qpid:children]
-dc-1-qpid
-
-[dc-1-qpid:children]
-tag_Name_dc3_n4
-tag_Name_dc3_n5
-
-[pg:children]
-dc-1-pg
-
-[dc-1-pg:children]
-dc-1-pgmaster
-dc-1-pgstandby
-
-[pgmaster:children]
-dc-1-pgmaster
-
-[dc-1-pgmaster:children]
-tag_Name_dc3_n4
-
-[pgstandby:children]
-dc-1-pgstandby
-
-[dc-1-pgstandby:children]
-tag_Name_dc3_n5
diff --git a/edge-1601-dc3-dc4/inventory-dc4 b/edge-1601-dc3-dc4/inventory-dc4
deleted file mode 100644
index 93b42da..0000000
--- a/edge-1601-dc3-dc4/inventory-dc4
+++ /dev/null
@@ -1,74 +0,0 @@
-[tag_Name_dc4_n1]
-[tag_Name_dc4_n2]
-[tag_Name_dc4_n3]
-[tag_Name_dc4_n4]
-[tag_Name_dc4_n5]
-
-[planet:children]
-dc-2
-
-[dc-2:children]
-tag_Name_dc4_n1
-tag_Name_dc4_n2
-tag_Name_dc4_n3
-tag_Name_dc4_n4
-tag_Name_dc4_n5
-
-[ds:children]
-dc-2-ds
-
-[dc-2-ds:children]
-tag_Name_dc4_n2
-tag_Name_dc4_n3
-tag_Name_dc4_n4
-
-[ms:children]
-dc-2-ms
-
-[dc-2-ms:children]
-tag_Name_dc4_n1
-
-[ui:children]
-dc-2-ui
-
-[dc-2-ui:children]
-tag_Name_dc4_n1
-
-[ldap:children]
-dc-2-ldap
-
-[dc-2-ldap:children]
-tag_Name_dc4_n1
-
-[rmp:children]
-dc-2-rmp
-
-[dc-2-rmp:children]
-tag_Name_dc4_n3
-tag_Name_dc4_n4
-
-[qpid:children]
-dc-2-qpid
-
-[dc-2-qpid:children]
-tag_Name_dc4_n4
-tag_Name_dc4_n5
-
-[pg:children]
-dc-2-pg
-
-[dc-2-pg:children]
-dc-2-pgmaster
-dc-2-pgstandby
-
-[pgmaster:children]
-dc-2-pgmaster
-
-[dc-2-pgmaster:children]
-tag_Name_dc4_n4
-
-[pgstandby:children]
-dc-2-pgstandby
-
-[dc-2-pgstandby:children]
-tag_Name_dc4_n5
diff --git a/edge-1601-dc3/ec2.ini b/edge-1601-dc3/ec2.ini
deleted file mode 100644
index 36b3921..0000000
--- a/edge-1601-dc3/ec2.ini
+++ /dev/null
@@ -1,200 +0,0 @@
-# Ansible EC2 external inventory script settings
-#
-
-[ec2]
-
-# to talk to a private eucalyptus instance uncomment these lines
-# and edit edit eucalyptus_host to be the host name of your cloud controller
-#eucalyptus = True
-#eucalyptus_host = clc.cloud.domain.org
-
-# AWS regions to make calls to. Set this to 'all' to make request to all regions
-# in AWS and merge the results together. Alternatively, set this to a comma
-# separated list of regions. E.g. 'us-east-1,us-west-1,us-west-2'
-regions = all
-regions_exclude = us-gov-west-1,cn-north-1
-
-# When generating inventory, Ansible needs to know how to address a server.
-# Each EC2 instance has a lot of variables associated with it. Here is the list:
-#   http://docs.pythonboto.org/en/latest/ref/ec2.html#module-boto.ec2.instance
-# Below are 2 variables that are used as the address of a server:
-#   - destination_variable
-#   - vpc_destination_variable
-
-# This is the normal destination variable to use. If you are running Ansible
-# from outside EC2, then 'public_dns_name' makes the most sense. If you are
-# running Ansible from within EC2, then perhaps you want to use the internal
-# address, and should set this to 'private_dns_name'. The key of an EC2 tag
-# may optionally be used; however the boto instance variables hold precedence
-# in the event of a collision.
-destination_variable = public_dns_name
-
-# This allows you to override the inventory_name with an ec2 variable, instead
-# of using the destination_variable above. Addressing (aka ansible_ssh_host)
-# will still use destination_variable. Tags should be written as 'tag_TAGNAME'.
-#hostname_variable = tag_Name
-
-# For server inside a VPC, using DNS names may not make sense. When an instance
-# has 'subnet_id' set, this variable is used. If the subnet is public, setting
-# this to 'ip_address' will return the public IP address. For instances in a
-# private subnet, this should be set to 'private_ip_address', and Ansible must
-# be run from within EC2. The key of an EC2 tag may optionally be used; however
-# the boto instance variables hold precedence in the event of a collision.
-# WARNING: - instances that are in the private vpc, _without_ public ip address
-# will not be listed in the inventory until You set:
-# vpc_destination_variable = private_ip_address
-vpc_destination_variable = ip_address
-
-# The following two settings allow flexible ansible host naming based on a
-# python format string and a comma-separated list of ec2 tags.  Note that:
-#
-# 1) If the tags referenced are not present for some instances, empty strings
-#    will be substituted in the format string.
-# 2) This overrides both destination_variable and vpc_destination_variable.
-#
-#destination_format = {0}.{1}.example.com
-#destination_format_tags = Name,environment
-
-# To tag instances on EC2 with the resource records that point to them from
-# Route53, uncomment and set 'route53' to True.
-route53 = False
-
-# To exclude RDS instances from the inventory, uncomment and set to False.
-rds = False
-
-# To exclude ElastiCache instances from the inventory, uncomment and set to False.
-elasticache = False
-
-# Additionally, you can specify the list of zones to exclude looking up in
-# 'route53_excluded_zones' as a comma-separated list.
-# route53_excluded_zones = samplezone1.com, samplezone2.com
-
-# By default, only EC2 instances in the 'running' state are returned. Set
-# 'all_instances' to True to return all instances regardless of state.
-all_instances = True
-
-# By default, only EC2 instances in the 'running' state are returned. Specify
-# EC2 instance states to return as a comma-separated list. This
-# option is overriden when 'all_instances' is True.
-# instance_states = pending, running, shutting-down, terminated, stopping, stopped
-
-# By default, only RDS instances in the 'available' state are returned.  Set
-# 'all_rds_instances' to True return all RDS instances regardless of state.
-all_rds_instances = False
-
-# By default, only ElastiCache clusters and nodes in the 'available' state
-# are returned. Set 'all_elasticache_clusters' and/or 'all_elastic_nodes'
-# to True return all ElastiCache clusters and nodes, regardless of state.
-#
-# Note that all_elasticache_nodes only applies to listed clusters. That means
-# if you set all_elastic_clusters to false, no node will be return from
-# unavailable clusters, regardless of the state and to what you set for
-# all_elasticache_nodes.
-all_elasticache_replication_groups = False
-all_elasticache_clusters = False
-all_elasticache_nodes = False
-
-# API calls to EC2 are slow. For this reason, we cache the results of an API
-# call. Set this to the path you want cache files to be written to. Two files
-# will be written to this directory:
-#   - ansible-ec2.cache
-#   - ansible-ec2.index
-cache_path = ~/.ansible/tmp
-
-# The number of seconds a cache file is considered valid. After this many
-# seconds, a new API call will be made, and the cache file will be updated.
-# To disable the cache, set this value to 0
-cache_max_age = 300
-
-# Organize groups into a nested/hierarchy instead of a flat namespace.
-nested_groups = False
-
-# Replace - tags when creating groups to avoid issues with ansible
-replace_dash_in_groups = True
-
-# If set to true, any tag of the form "a,b,c" is expanded into a list
-# and the results are used to create additional tag_* inventory groups.
-expand_csv_tags = False
-
-# The EC2 inventory output can become very large. To manage its size,
-# configure which groups should be created.
-group_by_instance_id = True
-group_by_region = True
-group_by_availability_zone = True
-group_by_ami_id = True
-group_by_instance_type = True
-group_by_key_pair = True
-group_by_vpc_id = True
-group_by_security_group = True
-group_by_tag_keys = True
-group_by_tag_none = True
-group_by_route53_names = True
-group_by_rds_engine = False
-group_by_rds_parameter_group = False
-group_by_elasticache_engine = True
-group_by_elasticache_cluster = True
-group_by_elasticache_parameter_group = True
-group_by_elasticache_replication_group = True
-
-# If you only want to include hosts that match a certain regular expression
-# pattern_include = staging-*
-
-# If you want to exclude any hosts that match a certain regular expression
-# pattern_exclude = staging-*
-# Ansible EC2 external inventory script settings
-#
-
-##[ec2]
-##
-### to talk to a private eucalyptus instance uncomment these lines
-### and edit edit eucalyptus_host to be the host name of your cloud controller
-###eucalyptus = True
-###eucalyptus_host = clc.cloud.domain.org
-##
-### AWS regions to make calls to. Set this to 'all' to make request to all regions
-##
-### in AWS and merge the results together. Alternatively, set this to a comma
-### separated list of regions. E.g. 'us-east-1,us-west-1,us-west-2'
-##regions = all
-##regions_exclude = us-gov-west-1,cn-north-1
-##
-### When generating inventory, Ansible needs to know how to address a server.
-### Each EC2 instance has a lot of variables associated with it. Here is the list:
-###   http://docs.pythonboto.org/en/latest/ref/ec2.html#module-boto.ec2.instance
-### Below are 2 variables that are used as the address of a server:
-###   - destination_variable
-###   - vpc_destination_variable
-##
-### This is the normal destination variable to use. If you are running Ansible
-### from outside EC2, then 'public_dns_name' makes the most sense. If you are
-### running Ansible from within EC2, then perhaps you want to use the internal
-### address, and should set this to 'private_dns_name'. The key of an EC2 tag
-##...skipping...
-### pattern_include = staging-*
-##
-### If you want to exclude any hosts that match a certain regular expression
-### pattern_exclude = staging-*
-
-# Instance filters can be used to control which instances are retrieved for
-# inventory. For the full list of possible filters, please read the EC2 API
-# docs: http://docs.aws.amazon.com/AWSEC2/latest/APIReference/ApiReference-query-DescribeInstances.html#query-DescribeInstances-filters
-# Filters are key/value pairs separated by '=', to list multiple filters use
-# a list separated by commas. See examples below.
-
-# Retrieve only instances with (key=value) env=staging tag
-# instance_filters = tag:env=staging
-
-# Retrieve only instances with role=webservers OR role=dbservers tag
-# instance_filters = tag:role=webservers,tag:role=dbservers
-
-# Retrieve only t1.micro instances OR instances with tag env=staging
-# instance_filters = instance-type=t1.micro,tag:env=staging
-
-# You can use wildcards in filter values also. Below will list instances which
-# tag Name value matches webservers1*
-# (ex. webservers15, webservers1a, webservers123 etc)
-# instance_filters = tag:Name=webservers1*
-
-# A boto configuration profile may be used to separate out credentials
-# see http://boto.readthedocs.org/en/latest/boto_config_tut.html
-# boto_profile = some-boto-profile-name
diff --git a/edge-1601-dc3/ec2.py b/edge-1601-dc3/ec2.py
deleted file mode 100755
index f30958a..0000000
--- a/edge-1601-dc3/ec2.py
+++ /dev/null
@@ -1,1385 +0,0 @@
-#!/usr/bin/env python
-
-'''
-EC2 external inventory script
-=================================
-
-Generates inventory that Ansible can understand by making API request to
-AWS EC2 using the Boto library.
-
-NOTE: This script assumes Ansible is being executed where the environment
-variables needed for Boto have already been set:
-    export AWS_ACCESS_KEY_ID='AK123'
-    export AWS_SECRET_ACCESS_KEY='abc123'
-
-This script also assumes there is an ec2.ini file alongside it.  To specify a
-different path to ec2.ini, define the EC2_INI_PATH environment variable:
-
-    export EC2_INI_PATH=/path/to/my_ec2.ini
-
-If you're using eucalyptus you need to set the above variables and
-you need to define:
-
-    export EC2_URL=http://hostname_of_your_cc:port/services/Eucalyptus
-
-If you're using boto profiles (requires boto>=2.24.0) you can choose a profile
-using the --boto-profile command line argument (e.g. ec2.py --boto-profile prod) or using
-the AWS_PROFILE variable:
-
-    AWS_PROFILE=prod ansible-playbook -i ec2.py myplaybook.yml
-
-For more details, see: http://docs.pythonboto.org/en/latest/boto_config_tut.html
-
-When run against a specific host, this script returns the following variables:
- - ec2_ami_launch_index
- - ec2_architecture
- - ec2_association
- - ec2_attachTime
- - ec2_attachment
- - ec2_attachmentId
- - ec2_client_token
- - ec2_deleteOnTermination
- - ec2_description
- - ec2_deviceIndex
- - ec2_dns_name
- - ec2_eventsSet
- - ec2_group_name
- - ec2_hypervisor
- - ec2_id
- - ec2_image_id
- - ec2_instanceState
- - ec2_instance_type
- - ec2_ipOwnerId
- - ec2_ip_address
- - ec2_item
- - ec2_kernel
- - ec2_key_name
- - ec2_launch_time
- - ec2_monitored
- - ec2_monitoring
- - ec2_networkInterfaceId
- - ec2_ownerId
- - ec2_persistent
- - ec2_placement
- - ec2_platform
- - ec2_previous_state
- - ec2_private_dns_name
- - ec2_private_ip_address
- - ec2_publicIp
- - ec2_public_dns_name
- - ec2_ramdisk
- - ec2_reason
- - ec2_region
- - ec2_requester_id
- - ec2_root_device_name
- - ec2_root_device_type
- - ec2_security_group_ids
- - ec2_security_group_names
- - ec2_shutdown_state
- - ec2_sourceDestCheck
- - ec2_spot_instance_request_id
- - ec2_state
- - ec2_state_code
- - ec2_state_reason
- - ec2_status
- - ec2_subnet_id
- - ec2_tenancy
- - ec2_virtualization_type
- - ec2_vpc_id
-
-These variables are pulled out of a boto.ec2.instance object. There is a lack of
-consistency with variable spellings (camelCase and underscores) since this
-just loops through all variables the object exposes. It is preferred to use the
-ones with underscores when multiple exist.
-
-In addition, if an instance has AWS Tags associated with it, each tag is a new
-variable named:
- - ec2_tag_[Key] = [Value]
-
-Security groups are comma-separated in 'ec2_security_group_ids' and
-'ec2_security_group_names'.
-'''
-
-# (c) 2012, Peter Sankauskas
-#
-# This file is part of Ansible,
-#
-# Ansible is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# Ansible is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with Ansible.  If not, see <http://www.gnu.org/licenses/>.
-
-######################################################################
-
-import sys
-import os
-import argparse
-import re
-from time import time
-import boto
-from boto import ec2
-from boto import rds
-from boto import elasticache
-from boto import route53
-import six
-
-from six.moves import configparser
-from collections import defaultdict
-
-try:
-    import json
-except ImportError:
-    import simplejson as json
-
-
-class Ec2Inventory(object):
-
-    def _empty_inventory(self):
-        return {"_meta" : {"hostvars" : {}}}
-
-    def __init__(self):
-        ''' Main execution path '''
-
-        # Inventory grouped by instance IDs, tags, security groups, regions,
-        # and availability zones
-        self.inventory = self._empty_inventory()
-
-        # Index of hostname (address) to instance ID
-        self.index = {}
-
-        # Boto profile to use (if any)
-        self.boto_profile = None
-
-        # Read settings and parse CLI arguments
-        self.parse_cli_args()
-        self.read_settings()
-
-        # Make sure that profile_name is not passed at all if not set
-        # as pre 2.24 boto will fall over otherwise
-        if self.boto_profile:
-            if not hasattr(boto.ec2.EC2Connection, 'profile_name'):
-                self.fail_with_error("boto version must be >= 2.24 to use profile")
-
-        # Cache
-        if self.args.refresh_cache:
-            self.do_api_calls_update_cache()
-        elif not self.is_cache_valid():
-            self.do_api_calls_update_cache()
-
-        # Data to print
-        if self.args.host:
-            data_to_print = self.get_host_info()
-
-        elif self.args.list:
-            # Display list of instances for inventory
-            if self.inventory == self._empty_inventory():
-                data_to_print = self.get_inventory_from_cache()
-            else:
-                data_to_print = self.json_format_dict(self.inventory, True)
-
-        print(data_to_print)
-
-
-    def is_cache_valid(self):
-        ''' Determines if the cache files have expired, or if it is still valid '''
-
-        if os.path.isfile(self.cache_path_cache):
-            mod_time = os.path.getmtime(self.cache_path_cache)
-            current_time = time()
-            if (mod_time + self.cache_max_age) > current_time:
-                if os.path.isfile(self.cache_path_index):
-                    return True
-
-        return False
-
-
-    def read_settings(self):
-        ''' Reads the settings from the ec2.ini file '''
-        if six.PY3:
-            config = configparser.ConfigParser()
-        else:
-            config = configparser.SafeConfigParser()
-        ec2_default_ini_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'ec2.ini')
-        ec2_ini_path = os.path.expanduser(os.path.expandvars(os.environ.get('EC2_INI_PATH', ec2_default_ini_path)))
-        config.read(ec2_ini_path)
-
-        # is eucalyptus?
-        self.eucalyptus_host = None
-        self.eucalyptus = False
-        if config.has_option('ec2', 'eucalyptus'):
-            self.eucalyptus = config.getboolean('ec2', 'eucalyptus')
-        if self.eucalyptus and config.has_option('ec2', 'eucalyptus_host'):
-            self.eucalyptus_host = config.get('ec2', 'eucalyptus_host')
-
-        # Regions
-        self.regions = []
-        configRegions = config.get('ec2', 'regions')
-        configRegions_exclude = config.get('ec2', 'regions_exclude')
-        if (configRegions == 'all'):
-            if self.eucalyptus_host:
-                self.regions.append(boto.connect_euca(host=self.eucalyptus_host).region.name)
-            else:
-                for regionInfo in ec2.regions():
-                    if regionInfo.name not in configRegions_exclude:
-                        self.regions.append(regionInfo.name)
-        else:
-            self.regions = configRegions.split(",")
-
-        # Destination addresses
-        self.destination_variable = config.get('ec2', 'destination_variable')
-        self.vpc_destination_variable = config.get('ec2', 'vpc_destination_variable')
-
-        if config.has_option('ec2', 'hostname_variable'):
-            self.hostname_variable = config.get('ec2', 'hostname_variable')
-        else:
-            self.hostname_variable = None
-
-        if config.has_option('ec2', 'destination_format') and \
-                config.has_option('ec2', 'destination_format_tags'):
-            self.destination_format = config.get('ec2', 'destination_format')
-            self.destination_format_tags = config.get('ec2', 'destination_format_tags').split(',')
-        else:
-            self.destination_format = None
-            self.destination_format_tags = None
-
-        # Route53
-        self.route53_enabled = config.getboolean('ec2', 'route53')
-        self.route53_excluded_zones = []
-        if config.has_option('ec2', 'route53_excluded_zones'):
-            self.route53_excluded_zones.extend(
-                    config.get('ec2', 'route53_excluded_zones', '').split(','))
-
-        # Include RDS instances?
-        self.rds_enabled = True
-        if config.has_option('ec2', 'rds'):
-            self.rds_enabled = config.getboolean('ec2', 'rds')
-
-        # Include ElastiCache instances?
-        self.elasticache_enabled = True
-        if config.has_option('ec2', 'elasticache'):
-            self.elasticache_enabled = config.getboolean('ec2', 'elasticache')
-
-        # Return all EC2 instances?
-        if config.has_option('ec2', 'all_instances'):
-            self.all_instances = config.getboolean('ec2', 'all_instances')
-        else:
-            self.all_instances = False
-
-        # Instance states to be gathered in inventory. Default is 'running'.
-        # Setting 'all_instances' to 'yes' overrides this option.
-        ec2_valid_instance_states = [
-            'pending',
-            'running',
-            'shutting-down',
-            'terminated',
-            'stopping',
-            'stopped'
-        ]
-        self.ec2_instance_states = []
-        if self.all_instances:
-            self.ec2_instance_states = ec2_valid_instance_states
-        elif config.has_option('ec2', 'instance_states'):
-            for instance_state in config.get('ec2', 'instance_states').split(','):
-                instance_state = instance_state.strip()
-                if instance_state not in ec2_valid_instance_states:
-                    continue
-                self.ec2_instance_states.append(instance_state)
-        else:
-            self.ec2_instance_states = ['running']
-
-        # Return all RDS instances? (if RDS is enabled)
-        if config.has_option('ec2', 'all_rds_instances') and self.rds_enabled:
-            self.all_rds_instances = config.getboolean('ec2', 'all_rds_instances')
-        else:
-            self.all_rds_instances = False
-
-        # Return all ElastiCache replication groups? (if ElastiCache is enabled)
-        if config.has_option('ec2', 'all_elasticache_replication_groups') and self.elasticache_enabled:
-            self.all_elasticache_replication_groups = config.getboolean('ec2', 'all_elasticache_replication_groups')
-        else:
-            self.all_elasticache_replication_groups = False
-
-        # Return all ElastiCache clusters? (if ElastiCache is enabled)
-        if config.has_option('ec2', 'all_elasticache_clusters') and self.elasticache_enabled:
-            self.all_elasticache_clusters = config.getboolean('ec2', 'all_elasticache_clusters')
-        else:
-            self.all_elasticache_clusters = False
-
-        # Return all ElastiCache nodes? (if ElastiCache is enabled)
-        if config.has_option('ec2', 'all_elasticache_nodes') and self.elasticache_enabled:
-            self.all_elasticache_nodes = config.getboolean('ec2', 'all_elasticache_nodes')
-        else:
-            self.all_elasticache_nodes = False
-
-        # boto configuration profile (prefer CLI argument)
-        self.boto_profile = self.args.boto_profile
-        if config.has_option('ec2', 'boto_profile') and not self.boto_profile:
-            self.boto_profile = config.get('ec2', 'boto_profile')
-
-        # Cache related
-        cache_dir = os.path.expanduser(config.get('ec2', 'cache_path'))
-        if self.boto_profile:
-            cache_dir = os.path.join(cache_dir, 'profile_' + self.boto_profile)
-        if not os.path.exists(cache_dir):
-            os.makedirs(cache_dir)
-
-        cache_name = 'ansible-ec2'
-        aws_profile = lambda: (self.boto_profile or
-                               os.environ.get('AWS_PROFILE') or
-                               os.environ.get('AWS_ACCESS_KEY_ID'))
-        if aws_profile():
-            cache_name = '%s-%s' % (cache_name, aws_profile())
-        self.cache_path_cache = cache_dir + "/%s.cache" % cache_name
-        self.cache_path_index = cache_dir + "/%s.index" % cache_name
-        self.cache_max_age = config.getint('ec2', 'cache_max_age')
-
-        if config.has_option('ec2', 'expand_csv_tags'):
-            self.expand_csv_tags = config.getboolean('ec2', 'expand_csv_tags')
-        else:
-            self.expand_csv_tags = False
-
-        # Configure nested groups instead of flat namespace.
-        if config.has_option('ec2', 'nested_groups'):
-            self.nested_groups = config.getboolean('ec2', 'nested_groups')
-        else:
-            self.nested_groups = False
-
-        # Replace dash or not in group names
-        if config.has_option('ec2', 'replace_dash_in_groups'):
-            self.replace_dash_in_groups = config.getboolean('ec2', 'replace_dash_in_groups')
-        else:
-            self.replace_dash_in_groups = True
-
-        # Configure which groups should be created.
-        group_by_options = [
-            'group_by_instance_id',
-            'group_by_region',
-            'group_by_availability_zone',
-            'group_by_ami_id',
-            'group_by_instance_type',
-            'group_by_key_pair',
-            'group_by_vpc_id',
-            'group_by_security_group',
-            'group_by_tag_keys',
-            'group_by_tag_none',
-            'group_by_route53_names',
-            'group_by_rds_engine',
-            'group_by_rds_parameter_group',
-            'group_by_elasticache_engine',
-            'group_by_elasticache_cluster',
-            'group_by_elasticache_parameter_group',
-            'group_by_elasticache_replication_group',
-        ]
-        for option in group_by_options:
-            if config.has_option('ec2', option):
-                setattr(self, option, config.getboolean('ec2', option))
-            else:
-                setattr(self, option, True)
-
-        # Do we need to just include hosts that match a pattern?
-        try:
-            pattern_include = config.get('ec2', 'pattern_include')
-            if pattern_include and len(pattern_include) > 0:
-                self.pattern_include = re.compile(pattern_include)
-            else:
-                self.pattern_include = None
-        except configparser.NoOptionError:
-            self.pattern_include = None
-
-        # Do we need to exclude hosts that match a pattern?
-        try:
-            pattern_exclude = config.get('ec2', 'pattern_exclude');
-            if pattern_exclude and len(pattern_exclude) > 0:
-                self.pattern_exclude = re.compile(pattern_exclude)
-            else:
-                self.pattern_exclude = None
-        except configparser.NoOptionError:
-            self.pattern_exclude = None
-
-        # Instance filters (see boto and EC2 API docs). Ignore invalid filters.
-        self.ec2_instance_filters = defaultdict(list)
-        if config.has_option('ec2', 'instance_filters'):
-
-            filters = [f for f in config.get('ec2', 'instance_filters').split(',') if f]
-
-            for instance_filter in filters:
-                instance_filter = instance_filter.strip()
-                if not instance_filter or '=' not in instance_filter:
-                    continue
-                filter_key, filter_value = [x.strip() for x in instance_filter.split('=', 1)]
-                if not filter_key:
-                    continue
-                self.ec2_instance_filters[filter_key].append(filter_value)
-
-    def parse_cli_args(self):
-        ''' Command line argument processing '''
-
-        parser = argparse.ArgumentParser(description='Produce an Ansible Inventory file based on EC2')
-        parser.add_argument('--list', action='store_true', default=True,
-                            help='List instances (default: True)')
-        parser.add_argument('--host', action='store',
-                            help='Get all the variables about a specific instance')
-        parser.add_argument('--refresh-cache', action='store_true', default=False,
-                            help='Force refresh of cache by making API requests to EC2 (default: False - use cache files)')
-        parser.add_argument('--profile', '--boto-profile', action='store', dest='boto_profile',
-                            help='Use boto profile for connections to EC2')
-        self.args = parser.parse_args()
-
-
-    def do_api_calls_update_cache(self):
-        ''' Do API calls to each region, and save data in cache files '''
-
-        if self.route53_enabled:
-            self.get_route53_records()
-
-        for region in self.regions:
-            self.get_instances_by_region(region)
-            if self.rds_enabled:
-                self.get_rds_instances_by_region(region)
-            if self.elasticache_enabled:
-                self.get_elasticache_clusters_by_region(region)
-                self.get_elasticache_replication_groups_by_region(region)
-
-        self.write_to_cache(self.inventory, self.cache_path_cache)
-        self.write_to_cache(self.index, self.cache_path_index)
-
-    def connect(self, region):
-        ''' create connection to api server'''
-        if self.eucalyptus:
-            conn = boto.connect_euca(host=self.eucalyptus_host)
-            conn.APIVersion = '2010-08-31'
-        else:
-            conn = self.connect_to_aws(ec2, region)
-        return conn
-
-    def boto_fix_security_token_in_profile(self, connect_args):
-        ''' monkey patch for boto issue boto/boto#2100 '''
-        profile = 'profile ' + self.boto_profile
-        if boto.config.has_option(profile, 'aws_security_token'):
-            connect_args['security_token'] = boto.config.get(profile, 'aws_security_token')
-        return connect_args
-
-    def connect_to_aws(self, module, region):
-        connect_args = {}
-
-        # only pass the profile name if it's set (as it is not supported by older boto versions)
-        if self.boto_profile:
-            connect_args['profile_name'] = self.boto_profile
-            self.boto_fix_security_token_in_profile(connect_args)
-
-        conn = module.connect_to_region(region, **connect_args)
-        # connect_to_region will fail "silently" by returning None if the region name is wrong or not supported
-        if conn is None:
-            self.fail_with_error("region name: %s likely not supported, or AWS is down.  connection to region failed." % region)
-        return conn
-
-    def get_instances_by_region(self, region):
-        ''' Makes an AWS EC2 API call to the list of instances in a particular
-        region '''
-
-        try:
-            conn = self.connect(region)
-            reservations = []
-            if self.ec2_instance_filters:
-                for filter_key, filter_values in self.ec2_instance_filters.items():
-                    reservations.extend(conn.get_all_instances(filters = { filter_key : filter_values }))
-            else:
-                reservations = conn.get_all_instances()
-
-            for reservation in reservations:
-                for instance in reservation.instances:
-                    self.add_instance(instance, region)
-
-        except boto.exception.BotoServerError as e:
-            if e.error_code == 'AuthFailure':
-                error = self.get_auth_error_message()
-            else:
-                backend = 'Eucalyptus' if self.eucalyptus else 'AWS'
-                error = "Error connecting to %s backend.\n%s" % (backend, e.message)
-            self.fail_with_error(error, 'getting EC2 instances')
-
-    def get_rds_instances_by_region(self, region):
-        ''' Makes an AWS API call to the list of RDS instances in a particular
-        region '''
-
-        try:
-            conn = self.connect_to_aws(rds, region)
-            if conn:
-                marker = None
-                while True:
-                    instances = conn.get_all_dbinstances(marker=marker)
-                    marker = instances.marker
-                    for instance in instances:
-                        self.add_rds_instance(instance, region)
-                    if not marker:
-                        break
-        except boto.exception.BotoServerError as e:
-            error = e.reason
-
-            if e.error_code == 'AuthFailure':
-                error = self.get_auth_error_message()
-            if not e.reason == "Forbidden":
-                error = "Looks like AWS RDS is down:\n%s" % e.message
-            self.fail_with_error(error, 'getting RDS instances')
-
-    def get_elasticache_clusters_by_region(self, region):
-        ''' Makes an AWS API call to the list of ElastiCache clusters (with
-        nodes' info) in a particular region.'''
-
-        # ElastiCache boto module doesn't provide a get_all_intances method,
-        # that's why we need to call describe directly (it would be called by
-        # the shorthand method anyway...)
-        try:
-            conn = self.connect_to_aws(elasticache, region)
-            if conn:
-                # show_cache_node_info = True
-                # because we also want nodes' information
-                response = conn.describe_cache_clusters(None, None, None, True)
-
-        except boto.exception.BotoServerError as e:
-            error = e.reason
-
-            if e.error_code == 'AuthFailure':
-                error = self.get_auth_error_message()
-            if not e.reason == "Forbidden":
-                error = "Looks like AWS ElastiCache is down:\n%s" % e.message
-            self.fail_with_error(error, 'getting ElastiCache clusters')
-
-        try:
-            # Boto also doesn't provide wrapper classes to CacheClusters or
-            # CacheNodes. Because of that wo can't make use of the get_list
-            # method in the AWSQueryConnection. Let's do the work manually
-            clusters = response['DescribeCacheClustersResponse']['DescribeCacheClustersResult']['CacheClusters']
-
-        except KeyError as e:
-            error = "ElastiCache query to AWS failed (unexpected format)."
-            self.fail_with_error(error, 'getting ElastiCache clusters')
-
-        for cluster in clusters:
-            self.add_elasticache_cluster(cluster, region)
-
-    def get_elasticache_replication_groups_by_region(self, region):
-        ''' Makes an AWS API call to the list of ElastiCache replication groups
-        in a particular region.'''
-
-        # ElastiCache boto module doesn't provide a get_all_intances method,
-        # that's why we need to call describe directly (it would be called by
-        # the shorthand method anyway...)
-        try:
-            conn = self.connect_to_aws(elasticache, region)
-            if conn:
-                response = conn.describe_replication_groups()
-
-        except boto.exception.BotoServerError as e:
-            error = e.reason
-
-            if e.error_code == 'AuthFailure':
-                error = self.get_auth_error_message()
-            if not e.reason == "Forbidden":
-                error = "Looks like AWS ElastiCache [Replication Groups] is down:\n%s" % e.message
-            self.fail_with_error(error, 'getting ElastiCache clusters')
-
-        try:
-            # Boto also doesn't provide wrapper classes to ReplicationGroups
-            # Because of that wo can't make use of the get_list method in the
-            # AWSQueryConnection. Let's do the work manually
-            replication_groups = response['DescribeReplicationGroupsResponse']['DescribeReplicationGroupsResult']['ReplicationGroups']
-
-        except KeyError as e:
-            error = "ElastiCache [Replication Groups] query to AWS failed (unexpected format)."
-            self.fail_with_error(error, 'getting ElastiCache clusters')
-
-        for replication_group in replication_groups:
-            self.add_elasticache_replication_group(replication_group, region)
-
-    def get_auth_error_message(self):
-        ''' create an informative error message if there is an issue authenticating'''
-        errors = ["Authentication error retrieving ec2 inventory."]
-        if None in [os.environ.get('AWS_ACCESS_KEY_ID'), os.environ.get('AWS_SECRET_ACCESS_KEY')]:
-            errors.append(' - No AWS_ACCESS_KEY_ID or AWS_SECRET_ACCESS_KEY environment vars found')
-        else:
-            errors.append(' - AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY environment vars found but may not be correct')
-
-        boto_paths = ['/etc/boto.cfg', '~/.boto', '~/.aws/credentials']
-        boto_config_found = list(p for p in boto_paths if os.path.isfile(os.path.expanduser(p)))
-        if len(boto_config_found) > 0:
-            errors.append(" - Boto configs found at '%s', but the credentials contained may not be correct" % ', '.join(boto_config_found))
-        else:
-            errors.append(" - No Boto config found at any expected location '%s'" % ', '.join(boto_paths))
-
-        return '\n'.join(errors)
-
-    def fail_with_error(self, err_msg, err_operation=None):
-        '''log an error to std err for ansible-playbook to consume and exit'''
-        if err_operation:
-            err_msg = 'ERROR: "{err_msg}", while: {err_operation}'.format(
-                    err_msg=err_msg, err_operation=err_operation)
-        sys.stderr.write(err_msg)
-        sys.exit(1)
-
-    def get_instance(self, region, instance_id):
-        conn = self.connect(region)
-
-        reservations = conn.get_all_instances([instance_id])
-        for reservation in reservations:
-            for instance in reservation.instances:
-                return instance
-
-    def add_instance(self, instance, region):
-        ''' Adds an instance to the inventory and index, as long as it is
-        addressable '''
-
-        # Only return instances with desired instance states
-        if instance.state not in self.ec2_instance_states:
-            return
-
-        # Select the best destination address
-        if self.destination_format and self.destination_format_tags:
-            dest = self.destination_format.format(*[ getattr(instance, 'tags').get(tag, '') for tag in self.destination_format_tags ])
-        elif instance.subnet_id:
-            dest = getattr(instance, self.vpc_destination_variable, None)
-            if dest is None:
-                dest = getattr(instance, 'tags').get(self.vpc_destination_variable, None)
-        else:
-            dest = getattr(instance, self.destination_variable, None)
-            if dest is None:
-                dest = getattr(instance, 'tags').get(self.destination_variable, None)
-
-        if not dest:
-            # Skip instances we cannot address (e.g. private VPC subnet)
-            return
-
-        # Set the inventory name
-        hostname = None
-        if self.hostname_variable:
-            if self.hostname_variable.startswith('tag_'):
-                hostname = instance.tags.get(self.hostname_variable[4:], None)
-            else:
-                hostname = getattr(instance, self.hostname_variable)
-
-        # If we can't get a nice hostname, use the destination address
-        if not hostname:
-            hostname = dest
-        else:
-            hostname = self.to_safe(hostname).lower()
-
-        # if we only want to include hosts that match a pattern, skip those that don't
-        if self.pattern_include and not self.pattern_include.match(hostname):
-            return
-
-        # if we need to exclude hosts that match a pattern, skip those
-        if self.pattern_exclude and self.pattern_exclude.match(hostname):
-            return
-
-        # Add to index
-        self.index[hostname] = [region, instance.id]
-
-        # Inventory: Group by instance ID (always a group of 1)
-        if self.group_by_instance_id:
-            self.inventory[instance.id] = [hostname]
-            if self.nested_groups:
-                self.push_group(self.inventory, 'instances', instance.id)
-
-        # Inventory: Group by region
-        if self.group_by_region:
-            self.push(self.inventory, region, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'regions', region)
-
-        # Inventory: Group by availability zone
-        if self.group_by_availability_zone:
-            self.push(self.inventory, instance.placement, hostname)
-            if self.nested_groups:
-                if self.group_by_region:
-                    self.push_group(self.inventory, region, instance.placement)
-                self.push_group(self.inventory, 'zones', instance.placement)
-
-        # Inventory: Group by Amazon Machine Image (AMI) ID
-        if self.group_by_ami_id:
-            ami_id = self.to_safe(instance.image_id)
-            self.push(self.inventory, ami_id, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'images', ami_id)
-
-        # Inventory: Group by instance type
-        if self.group_by_instance_type:
-            type_name = self.to_safe('type_' + instance.instance_type)
-            self.push(self.inventory, type_name, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'types', type_name)
-
-        # Inventory: Group by key pair
-        if self.group_by_key_pair and instance.key_name:
-            key_name = self.to_safe('key_' + instance.key_name)
-            self.push(self.inventory, key_name, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'keys', key_name)
-
-        # Inventory: Group by VPC
-        if self.group_by_vpc_id and instance.vpc_id:
-            vpc_id_name = self.to_safe('vpc_id_' + instance.vpc_id)
-            self.push(self.inventory, vpc_id_name, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'vpcs', vpc_id_name)
-
-        # Inventory: Group by security group
-        if self.group_by_security_group:
-            try:
-                for group in instance.groups:
-                    key = self.to_safe("security_group_" + group.name)
-                    self.push(self.inventory, key, hostname)
-                    if self.nested_groups:
-                        self.push_group(self.inventory, 'security_groups', key)
-            except AttributeError:
-                self.fail_with_error('\n'.join(['Package boto seems a bit older.',
-                                                'Please upgrade boto >= 2.3.0.']))
-
-        # Inventory: Group by tag keys
-        if self.group_by_tag_keys:
-            for k, v in instance.tags.items():
-                if self.expand_csv_tags and v and ',' in v:
-                    values = map(lambda x: x.strip(), v.split(','))
-                else:
-                    values = [v]
-
-                for v in values:
-                    if v:
-                        key = self.to_safe("tag_" + k + "=" + v)
-                    else:
-                        key = self.to_safe("tag_" + k)
-                    self.push(self.inventory, key, hostname)
-                    if self.nested_groups:
-                        self.push_group(self.inventory, 'tags', self.to_safe("tag_" + k))
-                        if v:
-                            self.push_group(self.inventory, self.to_safe("tag_" + k), key)
-
-        # Inventory: Group by Route53 domain names if enabled
-        if self.route53_enabled and self.group_by_route53_names:
-            route53_names = self.get_instance_route53_names(instance)
-            for name in route53_names:
-                self.push(self.inventory, name, hostname)
-                if self.nested_groups:
-                    self.push_group(self.inventory, 'route53', name)
-
-        # Global Tag: instances without tags
-        if self.group_by_tag_none and len(instance.tags) == 0:
-            self.push(self.inventory, 'tag_none', hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'tags', 'tag_none')
-
-        # Global Tag: tag all EC2 instances
-        self.push(self.inventory, 'ec2', hostname)
-
-        self.inventory["_meta"]["hostvars"][hostname] = self.get_host_info_dict_from_instance(instance)
-        self.inventory["_meta"]["hostvars"][hostname]['ansible_ssh_host'] = dest
-
-
-    def add_rds_instance(self, instance, region):
-        ''' Adds an RDS instance to the inventory and index, as long as it is
-        addressable '''
-
-        # Only want available instances unless all_rds_instances is True
-        if not self.all_rds_instances and instance.status != 'available':
-            return
-
-        # Select the best destination address
-        dest = instance.endpoint[0]
-
-        if not dest:
-            # Skip instances we cannot address (e.g. private VPC subnet)
-            return
-
-        # Set the inventory name
-        hostname = None
-        if self.hostname_variable:
-            if self.hostname_variable.startswith('tag_'):
-                hostname = instance.tags.get(self.hostname_variable[4:], None)
-            else:
-                hostname = getattr(instance, self.hostname_variable)
-
-        # If we can't get a nice hostname, use the destination address
-        if not hostname:
-            hostname = dest
-
-        hostname = self.to_safe(hostname).lower()
-
-        # Add to index
-        self.index[hostname] = [region, instance.id]
-
-        # Inventory: Group by instance ID (always a group of 1)
-        if self.group_by_instance_id:
-            self.inventory[instance.id] = [hostname]
-            if self.nested_groups:
-                self.push_group(self.inventory, 'instances', instance.id)
-
-        # Inventory: Group by region
-        if self.group_by_region:
-            self.push(self.inventory, region, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'regions', region)
-
-        # Inventory: Group by availability zone
-        if self.group_by_availability_zone:
-            self.push(self.inventory, instance.availability_zone, hostname)
-            if self.nested_groups:
-                if self.group_by_region:
-                    self.push_group(self.inventory, region, instance.availability_zone)
-                self.push_group(self.inventory, 'zones', instance.availability_zone)
-
-        # Inventory: Group by instance type
-        if self.group_by_instance_type:
-            type_name = self.to_safe('type_' + instance.instance_class)
-            self.push(self.inventory, type_name, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'types', type_name)
-
-        # Inventory: Group by VPC
-        if self.group_by_vpc_id and instance.subnet_group and instance.subnet_group.vpc_id:
-            vpc_id_name = self.to_safe('vpc_id_' + instance.subnet_group.vpc_id)
-            self.push(self.inventory, vpc_id_name, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'vpcs', vpc_id_name)
-
-        # Inventory: Group by security group
-        if self.group_by_security_group:
-            try:
-                if instance.security_group:
-                    key = self.to_safe("security_group_" + instance.security_group.name)
-                    self.push(self.inventory, key, hostname)
-                    if self.nested_groups:
-                        self.push_group(self.inventory, 'security_groups', key)
-
-            except AttributeError:
-                self.fail_with_error('\n'.join(['Package boto seems a bit older.',
-                                                'Please upgrade boto >= 2.3.0.']))
-
-
-        # Inventory: Group by engine
-        if self.group_by_rds_engine:
-            self.push(self.inventory, self.to_safe("rds_" + instance.engine), hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'rds_engines', self.to_safe("rds_" + instance.engine))
-
-        # Inventory: Group by parameter group
-        if self.group_by_rds_parameter_group:
-            self.push(self.inventory, self.to_safe("rds_parameter_group_" + instance.parameter_group.name), hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'rds_parameter_groups', self.to_safe("rds_parameter_group_" + instance.parameter_group.name))
-
-        # Global Tag: all RDS instances
-        self.push(self.inventory, 'rds', hostname)
-
-        self.inventory["_meta"]["hostvars"][hostname] = self.get_host_info_dict_from_instance(instance)
-        self.inventory["_meta"]["hostvars"][hostname]['ansible_ssh_host'] = dest
-
-    def add_elasticache_cluster(self, cluster, region):
-        ''' Adds an ElastiCache cluster to the inventory and index, as long as
-        it's nodes are addressable '''
-
-        # Only want available clusters unless all_elasticache_clusters is True
-        if not self.all_elasticache_clusters and cluster['CacheClusterStatus'] != 'available':
-            return
-
-        # Select the best destination address
-        if 'ConfigurationEndpoint' in cluster and cluster['ConfigurationEndpoint']:
-            # Memcached cluster
-            dest = cluster['ConfigurationEndpoint']['Address']
-            is_redis = False
-        else:
-            # Redis sigle node cluster
-            # Because all Redis clusters are single nodes, we'll merge the
-            # info from the cluster with info about the node
-            dest = cluster['CacheNodes'][0]['Endpoint']['Address']
-            is_redis = True
-
-        if not dest:
-            # Skip clusters we cannot address (e.g. private VPC subnet)
-            return
-
-        # Add to index
-        self.index[dest] = [region, cluster['CacheClusterId']]
-
-        # Inventory: Group by instance ID (always a group of 1)
-        if self.group_by_instance_id:
-            self.inventory[cluster['CacheClusterId']] = [dest]
-            if self.nested_groups:
-                self.push_group(self.inventory, 'instances', cluster['CacheClusterId'])
-
-        # Inventory: Group by region
-        if self.group_by_region and not is_redis:
-            self.push(self.inventory, region, dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'regions', region)
-
-        # Inventory: Group by availability zone
-        if self.group_by_availability_zone and not is_redis:
-            self.push(self.inventory, cluster['PreferredAvailabilityZone'], dest)
-            if self.nested_groups:
-                if self.group_by_region:
-                    self.push_group(self.inventory, region, cluster['PreferredAvailabilityZone'])
-                self.push_group(self.inventory, 'zones', cluster['PreferredAvailabilityZone'])
-
-        # Inventory: Group by node type
-        if self.group_by_instance_type and not is_redis:
-            type_name = self.to_safe('type_' + cluster['CacheNodeType'])
-            self.push(self.inventory, type_name, dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'types', type_name)
-
-        # Inventory: Group by VPC (information not available in the current
-        # AWS API version for ElastiCache)
-
-        # Inventory: Group by security group
-        if self.group_by_security_group and not is_redis:
-
-            # Check for the existence of the 'SecurityGroups' key and also if
-            # this key has some value. When the cluster is not placed in a SG
-            # the query can return None here and cause an error.
-            if 'SecurityGroups' in cluster and cluster['SecurityGroups'] is not None:
-                for security_group in cluster['SecurityGroups']:
-                    key = self.to_safe("security_group_" + security_group['SecurityGroupId'])
-                    self.push(self.inventory, key, dest)
-                    if self.nested_groups:
-                        self.push_group(self.inventory, 'security_groups', key)
-
-        # Inventory: Group by engine
-        if self.group_by_elasticache_engine and not is_redis:
-            self.push(self.inventory, self.to_safe("elasticache_" + cluster['Engine']), dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'elasticache_engines', self.to_safe(cluster['Engine']))
-
-        # Inventory: Group by parameter group
-        if self.group_by_elasticache_parameter_group:
-            self.push(self.inventory, self.to_safe("elasticache_parameter_group_" + cluster['CacheParameterGroup']['CacheParameterGroupName']), dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'elasticache_parameter_groups', self.to_safe(cluster['CacheParameterGroup']['CacheParameterGroupName']))
-
-        # Inventory: Group by replication group
-        if self.group_by_elasticache_replication_group and 'ReplicationGroupId' in cluster and cluster['ReplicationGroupId']:
-            self.push(self.inventory, self.to_safe("elasticache_replication_group_" + cluster['ReplicationGroupId']), dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'elasticache_replication_groups', self.to_safe(cluster['ReplicationGroupId']))
-
-        # Global Tag: all ElastiCache clusters
-        self.push(self.inventory, 'elasticache_clusters', cluster['CacheClusterId'])
-
-        host_info = self.get_host_info_dict_from_describe_dict(cluster)
-
-        self.inventory["_meta"]["hostvars"][dest] = host_info
-
-        # Add the nodes
-        for node in cluster['CacheNodes']:
-            self.add_elasticache_node(node, cluster, region)
-
-    def add_elasticache_node(self, node, cluster, region):
-        ''' Adds an ElastiCache node to the inventory and index, as long as
-        it is addressable '''
-
-        # Only want available nodes unless all_elasticache_nodes is True
-        if not self.all_elasticache_nodes and node['CacheNodeStatus'] != 'available':
-            return
-
-        # Select the best destination address
-        dest = node['Endpoint']['Address']
-
-        if not dest:
-            # Skip nodes we cannot address (e.g. private VPC subnet)
-            return
-
-        node_id = self.to_safe(cluster['CacheClusterId'] + '_' + node['CacheNodeId'])
-
-        # Add to index
-        self.index[dest] = [region, node_id]
-
-        # Inventory: Group by node ID (always a group of 1)
-        if self.group_by_instance_id:
-            self.inventory[node_id] = [dest]
-            if self.nested_groups:
-                self.push_group(self.inventory, 'instances', node_id)
-
-        # Inventory: Group by region
-        if self.group_by_region:
-            self.push(self.inventory, region, dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'regions', region)
-
-        # Inventory: Group by availability zone
-        if self.group_by_availability_zone:
-            self.push(self.inventory, cluster['PreferredAvailabilityZone'], dest)
-            if self.nested_groups:
-                if self.group_by_region:
-                    self.push_group(self.inventory, region, cluster['PreferredAvailabilityZone'])
-                self.push_group(self.inventory, 'zones', cluster['PreferredAvailabilityZone'])
-
-        # Inventory: Group by node type
-        if self.group_by_instance_type:
-            type_name = self.to_safe('type_' + cluster['CacheNodeType'])
-            self.push(self.inventory, type_name, dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'types', type_name)
-
-        # Inventory: Group by VPC (information not available in the current
-        # AWS API version for ElastiCache)
-
-        # Inventory: Group by security group
-        if self.group_by_security_group:
-
-            # Check for the existence of the 'SecurityGroups' key and also if
-            # this key has some value. When the cluster is not placed in a SG
-            # the query can return None here and cause an error.
-            if 'SecurityGroups' in cluster and cluster['SecurityGroups'] is not None:
-                for security_group in cluster['SecurityGroups']:
-                    key = self.to_safe("security_group_" + security_group['SecurityGroupId'])
-                    self.push(self.inventory, key, dest)
-                    if self.nested_groups:
-                        self.push_group(self.inventory, 'security_groups', key)
-
-        # Inventory: Group by engine
-        if self.group_by_elasticache_engine:
-            self.push(self.inventory, self.to_safe("elasticache_" + cluster['Engine']), dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'elasticache_engines', self.to_safe("elasticache_" + cluster['Engine']))
-
-        # Inventory: Group by parameter group (done at cluster level)
-
-        # Inventory: Group by replication group (done at cluster level)
-
-        # Inventory: Group by ElastiCache Cluster
-        if self.group_by_elasticache_cluster:
-            self.push(self.inventory, self.to_safe("elasticache_cluster_" + cluster['CacheClusterId']), dest)
-
-        # Global Tag: all ElastiCache nodes
-        self.push(self.inventory, 'elasticache_nodes', dest)
-
-        host_info = self.get_host_info_dict_from_describe_dict(node)
-
-        if dest in self.inventory["_meta"]["hostvars"]:
-            self.inventory["_meta"]["hostvars"][dest].update(host_info)
-        else:
-            self.inventory["_meta"]["hostvars"][dest] = host_info
-
-    def add_elasticache_replication_group(self, replication_group, region):
-        ''' Adds an ElastiCache replication group to the inventory and index '''
-
-        # Only want available clusters unless all_elasticache_replication_groups is True
-        if not self.all_elasticache_replication_groups and replication_group['Status'] != 'available':
-            return
-
-        # Select the best destination address (PrimaryEndpoint)
-        dest = replication_group['NodeGroups'][0]['PrimaryEndpoint']['Address']
-
-        if not dest:
-            # Skip clusters we cannot address (e.g. private VPC subnet)
-            return
-
-        # Add to index
-        self.index[dest] = [region, replication_group['ReplicationGroupId']]
-
-        # Inventory: Group by ID (always a group of 1)
-        if self.group_by_instance_id:
-            self.inventory[replication_group['ReplicationGroupId']] = [dest]
-            if self.nested_groups:
-                self.push_group(self.inventory, 'instances', replication_group['ReplicationGroupId'])
-
-        # Inventory: Group by region
-        if self.group_by_region:
-            self.push(self.inventory, region, dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'regions', region)
-
-        # Inventory: Group by availability zone (doesn't apply to replication groups)
-
-        # Inventory: Group by node type (doesn't apply to replication groups)
-
-        # Inventory: Group by VPC (information not available in the current
-        # AWS API version for replication groups
-
-        # Inventory: Group by security group (doesn't apply to replication groups)
-        # Check this value in cluster level
-
-        # Inventory: Group by engine (replication groups are always Redis)
-        if self.group_by_elasticache_engine:
-            self.push(self.inventory, 'elasticache_redis', dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'elasticache_engines', 'redis')
-
-        # Global Tag: all ElastiCache clusters
-        self.push(self.inventory, 'elasticache_replication_groups', replication_group['ReplicationGroupId'])
-
-        host_info = self.get_host_info_dict_from_describe_dict(replication_group)
-
-        self.inventory["_meta"]["hostvars"][dest] = host_info
-
-    def get_route53_records(self):
-        ''' Get and store the map of resource records to domain names that
-        point to them. '''
-
-        r53_conn = route53.Route53Connection()
-        all_zones = r53_conn.get_zones()
-
-        route53_zones = [ zone for zone in all_zones if zone.name[:-1]
-                          not in self.route53_excluded_zones ]
-
-        self.route53_records = {}
-
-        for zone in route53_zones:
-            rrsets = r53_conn.get_all_rrsets(zone.id)
-
-            for record_set in rrsets:
-                record_name = record_set.name
-
-                if record_name.endswith('.'):
-                    record_name = record_name[:-1]
-
-                for resource in record_set.resource_records:
-                    self.route53_records.setdefault(resource, set())
-                    self.route53_records[resource].add(record_name)
-
-
-    def get_instance_route53_names(self, instance):
-        ''' Check if an instance is referenced in the records we have from
-        Route53. If it is, return the list of domain names pointing to said
-        instance. If nothing points to it, return an empty list. '''
-
-        instance_attributes = [ 'public_dns_name', 'private_dns_name',
-                                'ip_address', 'private_ip_address' ]
-
-        name_list = set()
-
-        for attrib in instance_attributes:
-            try:
-                value = getattr(instance, attrib)
-            except AttributeError:
-                continue
-
-            if value in self.route53_records:
-                name_list.update(self.route53_records[value])
-
-        return list(name_list)
-
-    def get_host_info_dict_from_instance(self, instance):
-        instance_vars = {}
-        for key in vars(instance):
-            value = getattr(instance, key)
-            key = self.to_safe('ec2_' + key)
-
-            # Handle complex types
-            # state/previous_state changed to properties in boto in https://github.com/boto/boto/commit/a23c379837f698212252720d2af8dec0325c9518
-            if key == 'ec2__state':
-                instance_vars['ec2_state'] = instance.state or ''
-                instance_vars['ec2_state_code'] = instance.state_code
-            elif key == 'ec2__previous_state':
-                instance_vars['ec2_previous_state'] = instance.previous_state or ''
-                instance_vars['ec2_previous_state_code'] = instance.previous_state_code
-            elif type(value) in [int, bool]:
-                instance_vars[key] = value
-            elif isinstance(value, six.string_types):
-                instance_vars[key] = value.strip()
-            elif type(value) == type(None):
-                instance_vars[key] = ''
-            elif key == 'ec2_region':
-                instance_vars[key] = value.name
-            elif key == 'ec2__placement':
-                instance_vars['ec2_placement'] = value.zone
-            elif key == 'ec2_tags':
-                for k, v in value.items():
-                    if self.expand_csv_tags and ',' in v:
-                        v = map(lambda x: x.strip(), v.split(','))
-                    key = self.to_safe('ec2_tag_' + k)
-                    instance_vars[key] = v
-            elif key == 'ec2_groups':
-                group_ids = []
-                group_names = []
-                for group in value:
-                    group_ids.append(group.id)
-                    group_names.append(group.name)
-                instance_vars["ec2_security_group_ids"] = ','.join([str(i) for i in group_ids])
-                instance_vars["ec2_security_group_names"] = ','.join([str(i) for i in group_names])
-            else:
-                pass
-                # TODO Product codes if someone finds them useful
-                #print key
-                #print type(value)
-                #print value
-
-        return instance_vars
-
-    def get_host_info_dict_from_describe_dict(self, describe_dict):
-        ''' Parses the dictionary returned by the API call into a flat list
-            of parameters. This method should be used only when 'describe' is
-            used directly because Boto doesn't provide specific classes. '''
-
-        # I really don't agree with prefixing everything with 'ec2'
-        # because EC2, RDS and ElastiCache are different services.
-        # I'm just following the pattern used until now to not break any
-        # compatibility.
-
-        host_info = {}
-        for key in describe_dict:
-            value = describe_dict[key]
-            key = self.to_safe('ec2_' + self.uncammelize(key))
-
-            # Handle complex types
-
-            # Target: Memcached Cache Clusters
-            if key == 'ec2_configuration_endpoint' and value:
-                host_info['ec2_configuration_endpoint_address'] = value['Address']
-                host_info['ec2_configuration_endpoint_port'] = value['Port']
-
-            # Target: Cache Nodes and Redis Cache Clusters (single node)
-            if key == 'ec2_endpoint' and value:
-                host_info['ec2_endpoint_address'] = value['Address']
-                host_info['ec2_endpoint_port'] = value['Port']
-
-            # Target: Redis Replication Groups
-            if key == 'ec2_node_groups' and value:
-                host_info['ec2_endpoint_address'] = value[0]['PrimaryEndpoint']['Address']
-                host_info['ec2_endpoint_port'] = value[0]['PrimaryEndpoint']['Port']
-                replica_count = 0
-                for node in value[0]['NodeGroupMembers']:
-                    if node['CurrentRole'] == 'primary':
-                        host_info['ec2_primary_cluster_address'] = node['ReadEndpoint']['Address']
-                        host_info['ec2_primary_cluster_port'] = node['ReadEndpoint']['Port']
-                        host_info['ec2_primary_cluster_id'] = node['CacheClusterId']
-                    elif node['CurrentRole'] == 'replica':
-                        host_info['ec2_replica_cluster_address_'+ str(replica_count)] = node['ReadEndpoint']['Address']
-                        host_info['ec2_replica_cluster_port_'+ str(replica_count)] = node['ReadEndpoint']['Port']
-                        host_info['ec2_replica_cluster_id_'+ str(replica_count)] = node['CacheClusterId']
-                        replica_count += 1
-
-            # Target: Redis Replication Groups
-            if key == 'ec2_member_clusters' and value:
-                host_info['ec2_member_clusters'] = ','.join([str(i) for i in value])
-
-            # Target: All Cache Clusters
-            elif key == 'ec2_cache_parameter_group':
-                host_info["ec2_cache_node_ids_to_reboot"] = ','.join([str(i) for i in value['CacheNodeIdsToReboot']])
-                host_info['ec2_cache_parameter_group_name'] = value['CacheParameterGroupName']
-                host_info['ec2_cache_parameter_apply_status'] = value['ParameterApplyStatus']
-
-            # Target: Almost everything
-            elif key == 'ec2_security_groups':
-
-                # Skip if SecurityGroups is None
-                # (it is possible to have the key defined but no value in it).
-                if value is not None:
-                    sg_ids = []
-                    for sg in value:
-                        sg_ids.append(sg['SecurityGroupId'])
-                    host_info["ec2_security_group_ids"] = ','.join([str(i) for i in sg_ids])
-
-            # Target: Everything
-            # Preserve booleans and integers
-            elif type(value) in [int, bool]:
-                host_info[key] = value
-
-            # Target: Everything
-            # Sanitize string values
-            elif isinstance(value, six.string_types):
-                host_info[key] = value.strip()
-
-            # Target: Everything
-            # Replace None by an empty string
-            elif type(value) == type(None):
-                host_info[key] = ''
-
-            else:
-                # Remove non-processed complex types
-                pass
-
-        return host_info
-
-    def get_host_info(self):
-        ''' Get variables about a specific host '''
-
-        if len(self.index) == 0:
-            # Need to load index from cache
-            self.load_index_from_cache()
-
-        if not self.args.host in self.index:
-            # try updating the cache
-            self.do_api_calls_update_cache()
-            if not self.args.host in self.index:
-                # host might not exist anymore
-                return self.json_format_dict({}, True)
-
-        (region, instance_id) = self.index[self.args.host]
-
-        instance = self.get_instance(region, instance_id)
-        return self.json_format_dict(self.get_host_info_dict_from_instance(instance), True)
-
-    def push(self, my_dict, key, element):
-        ''' Push an element onto an array that may not have been defined in
-        the dict '''
-        group_info = my_dict.setdefault(key, [])
-        if isinstance(group_info, dict):
-            host_list = group_info.setdefault('hosts', [])
-            host_list.append(element)
-        else:
-            group_info.append(element)
-
-    def push_group(self, my_dict, key, element):
-        ''' Push a group as a child of another group. '''
-        parent_group = my_dict.setdefault(key, {})
-        if not isinstance(parent_group, dict):
-            parent_group = my_dict[key] = {'hosts': parent_group}
-        child_groups = parent_group.setdefault('children', [])
-        if element not in child_groups:
-            child_groups.append(element)
-
-    def get_inventory_from_cache(self):
-        ''' Reads the inventory from the cache file and returns it as a JSON
-        object '''
-
-        cache = open(self.cache_path_cache, 'r')
-        json_inventory = cache.read()
-        return json_inventory
-
-
-    def load_index_from_cache(self):
-        ''' Reads the index from the cache file sets self.index '''
-
-        cache = open(self.cache_path_index, 'r')
-        json_index = cache.read()
-        self.index = json.loads(json_index)
-
-
-    def write_to_cache(self, data, filename):
-        ''' Writes data in JSON format to a file '''
-
-        json_data = self.json_format_dict(data, True)
-        cache = open(filename, 'w')
-        cache.write(json_data)
-        cache.close()
-
-    def uncammelize(self, key):
-        temp = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', key)
-        return re.sub('([a-z0-9])([A-Z])', r'\1_\2', temp).lower()
-
-    def to_safe(self, word):
-        ''' Converts 'bad' characters in a string to underscores so they can be used as Ansible groups '''
-        regex = "[^A-Za-z0-9\_"
-        if not self.replace_dash_in_groups:
-            regex += "\-"
-        return re.sub(regex + "]", "_", word)
-
-    def json_format_dict(self, data, pretty=False):
-        ''' Converts a dict to a JSON object and dumps it as a formatted
-        string '''
-
-        if pretty:
-            return json.dumps(data, sort_keys=True, indent=2)
-        else:
-            return json.dumps(data)
-
-
-# Run the script
-Ec2Inventory()
diff --git a/edge-1601-dc3/inventory b/edge-1601-dc3/inventory
deleted file mode 100644
index 0b97282..0000000
--- a/edge-1601-dc3/inventory
+++ /dev/null
@@ -1,74 +0,0 @@
-[tag_Name_dc3_n1]
-[tag_Name_dc3_n2]
-[tag_Name_dc3_n3]
-[tag_Name_dc3_n4]
-[tag_Name_dc3_n5]
-
-[planet:children]
-dc-1
-
-[dc-1:children]
-tag_Name_dc3_n1
-tag_Name_dc3_n2
-tag_Name_dc3_n3
-tag_Name_dc3_n4
-tag_Name_dc3_n5
-
-[ds:children]
-dc-1-ds
-
-[dc-1-ds:children]
-tag_Name_dc3_n2
-tag_Name_dc3_n3
-tag_Name_dc3_n4
-
-[ms:children]
-dc-1-ms
-
-[dc-1-ms:children]
-tag_Name_dc3_n1
-
-[ui:children]
-dc-1-ui
-
-[dc-1-ui:children]
-tag_Name_dc3_n1
-
-[ldap:children]
-dc-1-ldap
-
-[dc-1-ldap:children]
-tag_Name_dc3_n1
-
-[rmp:children]
-dc-1-rmp
-
-[dc-1-rmp:children]
-tag_Name_dc3_n3
-tag_Name_dc3_n4
-
-[qpid:children]
-dc-1-qpid
-
-[dc-1-qpid:children]
-tag_Name_dc3_n4
-tag_Name_dc3_n5
-
-[pg:children]
-dc-1-pg
-
-[dc-1-pg:children]
-dc-1-pgmaster
-dc-1-pgstandby
-
-[pgmaster:children]
-dc-1-pgmaster
-
-[dc-1-pgmaster:children]
-tag_Name_dc3_n4
-
-[pgstandby:children]
-dc-1-pgstandby
-
-[dc-1-pgstandby:children]
-tag_Name_dc3_n5
diff --git a/edge-1601-dc4/ec2.ini b/edge-1601-dc4/ec2.ini
deleted file mode 100644
index 36b3921..0000000
--- a/edge-1601-dc4/ec2.ini
+++ /dev/null
@@ -1,200 +0,0 @@
-# Ansible EC2 external inventory script settings
-#
-
-[ec2]
-
-# to talk to a private eucalyptus instance uncomment these lines
-# and edit edit eucalyptus_host to be the host name of your cloud controller
-#eucalyptus = True
-#eucalyptus_host = clc.cloud.domain.org
-
-# AWS regions to make calls to. Set this to 'all' to make request to all regions
-# in AWS and merge the results together. Alternatively, set this to a comma
-# separated list of regions. E.g. 'us-east-1,us-west-1,us-west-2'
-regions = all
-regions_exclude = us-gov-west-1,cn-north-1
-
-# When generating inventory, Ansible needs to know how to address a server.
-# Each EC2 instance has a lot of variables associated with it. Here is the list:
-#   http://docs.pythonboto.org/en/latest/ref/ec2.html#module-boto.ec2.instance
-# Below are 2 variables that are used as the address of a server:
-#   - destination_variable
-#   - vpc_destination_variable
-
-# This is the normal destination variable to use. If you are running Ansible
-# from outside EC2, then 'public_dns_name' makes the most sense. If you are
-# running Ansible from within EC2, then perhaps you want to use the internal
-# address, and should set this to 'private_dns_name'. The key of an EC2 tag
-# may optionally be used; however the boto instance variables hold precedence
-# in the event of a collision.
-destination_variable = public_dns_name
-
-# This allows you to override the inventory_name with an ec2 variable, instead
-# of using the destination_variable above. Addressing (aka ansible_ssh_host)
-# will still use destination_variable. Tags should be written as 'tag_TAGNAME'.
-#hostname_variable = tag_Name
-
-# For server inside a VPC, using DNS names may not make sense. When an instance
-# has 'subnet_id' set, this variable is used. If the subnet is public, setting
-# this to 'ip_address' will return the public IP address. For instances in a
-# private subnet, this should be set to 'private_ip_address', and Ansible must
-# be run from within EC2. The key of an EC2 tag may optionally be used; however
-# the boto instance variables hold precedence in the event of a collision.
-# WARNING: - instances that are in the private vpc, _without_ public ip address
-# will not be listed in the inventory until You set:
-# vpc_destination_variable = private_ip_address
-vpc_destination_variable = ip_address
-
-# The following two settings allow flexible ansible host naming based on a
-# python format string and a comma-separated list of ec2 tags.  Note that:
-#
-# 1) If the tags referenced are not present for some instances, empty strings
-#    will be substituted in the format string.
-# 2) This overrides both destination_variable and vpc_destination_variable.
-#
-#destination_format = {0}.{1}.example.com
-#destination_format_tags = Name,environment
-
-# To tag instances on EC2 with the resource records that point to them from
-# Route53, uncomment and set 'route53' to True.
-route53 = False
-
-# To exclude RDS instances from the inventory, uncomment and set to False.
-rds = False
-
-# To exclude ElastiCache instances from the inventory, uncomment and set to False.
-elasticache = False
-
-# Additionally, you can specify the list of zones to exclude looking up in
-# 'route53_excluded_zones' as a comma-separated list.
-# route53_excluded_zones = samplezone1.com, samplezone2.com
-
-# By default, only EC2 instances in the 'running' state are returned. Set
-# 'all_instances' to True to return all instances regardless of state.
-all_instances = True
-
-# By default, only EC2 instances in the 'running' state are returned. Specify
-# EC2 instance states to return as a comma-separated list. This
-# option is overriden when 'all_instances' is True.
-# instance_states = pending, running, shutting-down, terminated, stopping, stopped
-
-# By default, only RDS instances in the 'available' state are returned.  Set
-# 'all_rds_instances' to True return all RDS instances regardless of state.
-all_rds_instances = False
-
-# By default, only ElastiCache clusters and nodes in the 'available' state
-# are returned. Set 'all_elasticache_clusters' and/or 'all_elastic_nodes'
-# to True return all ElastiCache clusters and nodes, regardless of state.
-#
-# Note that all_elasticache_nodes only applies to listed clusters. That means
-# if you set all_elastic_clusters to false, no node will be return from
-# unavailable clusters, regardless of the state and to what you set for
-# all_elasticache_nodes.
-all_elasticache_replication_groups = False
-all_elasticache_clusters = False
-all_elasticache_nodes = False
-
-# API calls to EC2 are slow. For this reason, we cache the results of an API
-# call. Set this to the path you want cache files to be written to. Two files
-# will be written to this directory:
-#   - ansible-ec2.cache
-#   - ansible-ec2.index
-cache_path = ~/.ansible/tmp
-
-# The number of seconds a cache file is considered valid. After this many
-# seconds, a new API call will be made, and the cache file will be updated.
-# To disable the cache, set this value to 0
-cache_max_age = 300
-
-# Organize groups into a nested/hierarchy instead of a flat namespace.
-nested_groups = False
-
-# Replace - tags when creating groups to avoid issues with ansible
-replace_dash_in_groups = True
-
-# If set to true, any tag of the form "a,b,c" is expanded into a list
-# and the results are used to create additional tag_* inventory groups.
-expand_csv_tags = False
-
-# The EC2 inventory output can become very large. To manage its size,
-# configure which groups should be created.
-group_by_instance_id = True
-group_by_region = True
-group_by_availability_zone = True
-group_by_ami_id = True
-group_by_instance_type = True
-group_by_key_pair = True
-group_by_vpc_id = True
-group_by_security_group = True
-group_by_tag_keys = True
-group_by_tag_none = True
-group_by_route53_names = True
-group_by_rds_engine = False
-group_by_rds_parameter_group = False
-group_by_elasticache_engine = True
-group_by_elasticache_cluster = True
-group_by_elasticache_parameter_group = True
-group_by_elasticache_replication_group = True
-
-# If you only want to include hosts that match a certain regular expression
-# pattern_include = staging-*
-
-# If you want to exclude any hosts that match a certain regular expression
-# pattern_exclude = staging-*
-# Ansible EC2 external inventory script settings
-#
-
-##[ec2]
-##
-### to talk to a private eucalyptus instance uncomment these lines
-### and edit edit eucalyptus_host to be the host name of your cloud controller
-###eucalyptus = True
-###eucalyptus_host = clc.cloud.domain.org
-##
-### AWS regions to make calls to. Set this to 'all' to make request to all regions
-##
-### in AWS and merge the results together. Alternatively, set this to a comma
-### separated list of regions. E.g. 'us-east-1,us-west-1,us-west-2'
-##regions = all
-##regions_exclude = us-gov-west-1,cn-north-1
-##
-### When generating inventory, Ansible needs to know how to address a server.
-### Each EC2 instance has a lot of variables associated with it. Here is the list:
-###   http://docs.pythonboto.org/en/latest/ref/ec2.html#module-boto.ec2.instance
-### Below are 2 variables that are used as the address of a server:
-###   - destination_variable
-###   - vpc_destination_variable
-##
-### This is the normal destination variable to use. If you are running Ansible
-### from outside EC2, then 'public_dns_name' makes the most sense. If you are
-### running Ansible from within EC2, then perhaps you want to use the internal
-### address, and should set this to 'private_dns_name'. The key of an EC2 tag
-##...skipping...
-### pattern_include = staging-*
-##
-### If you want to exclude any hosts that match a certain regular expression
-### pattern_exclude = staging-*
-
-# Instance filters can be used to control which instances are retrieved for
-# inventory. For the full list of possible filters, please read the EC2 API
-# docs: http://docs.aws.amazon.com/AWSEC2/latest/APIReference/ApiReference-query-DescribeInstances.html#query-DescribeInstances-filters
-# Filters are key/value pairs separated by '=', to list multiple filters use
-# a list separated by commas. See examples below.
-
-# Retrieve only instances with (key=value) env=staging tag
-# instance_filters = tag:env=staging
-
-# Retrieve only instances with role=webservers OR role=dbservers tag
-# instance_filters = tag:role=webservers,tag:role=dbservers
-
-# Retrieve only t1.micro instances OR instances with tag env=staging
-# instance_filters = instance-type=t1.micro,tag:env=staging
-
-# You can use wildcards in filter values also. Below will list instances which
-# tag Name value matches webservers1*
-# (ex. webservers15, webservers1a, webservers123 etc)
-# instance_filters = tag:Name=webservers1*
-
-# A boto configuration profile may be used to separate out credentials
-# see http://boto.readthedocs.org/en/latest/boto_config_tut.html
-# boto_profile = some-boto-profile-name
diff --git a/edge-1601-dc4/ec2.py b/edge-1601-dc4/ec2.py
deleted file mode 100755
index f30958a..0000000
--- a/edge-1601-dc4/ec2.py
+++ /dev/null
@@ -1,1385 +0,0 @@
-#!/usr/bin/env python
-
-'''
-EC2 external inventory script
-=================================
-
-Generates inventory that Ansible can understand by making API request to
-AWS EC2 using the Boto library.
-
-NOTE: This script assumes Ansible is being executed where the environment
-variables needed for Boto have already been set:
-    export AWS_ACCESS_KEY_ID='AK123'
-    export AWS_SECRET_ACCESS_KEY='abc123'
-
-This script also assumes there is an ec2.ini file alongside it.  To specify a
-different path to ec2.ini, define the EC2_INI_PATH environment variable:
-
-    export EC2_INI_PATH=/path/to/my_ec2.ini
-
-If you're using eucalyptus you need to set the above variables and
-you need to define:
-
-    export EC2_URL=http://hostname_of_your_cc:port/services/Eucalyptus
-
-If you're using boto profiles (requires boto>=2.24.0) you can choose a profile
-using the --boto-profile command line argument (e.g. ec2.py --boto-profile prod) or using
-the AWS_PROFILE variable:
-
-    AWS_PROFILE=prod ansible-playbook -i ec2.py myplaybook.yml
-
-For more details, see: http://docs.pythonboto.org/en/latest/boto_config_tut.html
-
-When run against a specific host, this script returns the following variables:
- - ec2_ami_launch_index
- - ec2_architecture
- - ec2_association
- - ec2_attachTime
- - ec2_attachment
- - ec2_attachmentId
- - ec2_client_token
- - ec2_deleteOnTermination
- - ec2_description
- - ec2_deviceIndex
- - ec2_dns_name
- - ec2_eventsSet
- - ec2_group_name
- - ec2_hypervisor
- - ec2_id
- - ec2_image_id
- - ec2_instanceState
- - ec2_instance_type
- - ec2_ipOwnerId
- - ec2_ip_address
- - ec2_item
- - ec2_kernel
- - ec2_key_name
- - ec2_launch_time
- - ec2_monitored
- - ec2_monitoring
- - ec2_networkInterfaceId
- - ec2_ownerId
- - ec2_persistent
- - ec2_placement
- - ec2_platform
- - ec2_previous_state
- - ec2_private_dns_name
- - ec2_private_ip_address
- - ec2_publicIp
- - ec2_public_dns_name
- - ec2_ramdisk
- - ec2_reason
- - ec2_region
- - ec2_requester_id
- - ec2_root_device_name
- - ec2_root_device_type
- - ec2_security_group_ids
- - ec2_security_group_names
- - ec2_shutdown_state
- - ec2_sourceDestCheck
- - ec2_spot_instance_request_id
- - ec2_state
- - ec2_state_code
- - ec2_state_reason
- - ec2_status
- - ec2_subnet_id
- - ec2_tenancy
- - ec2_virtualization_type
- - ec2_vpc_id
-
-These variables are pulled out of a boto.ec2.instance object. There is a lack of
-consistency with variable spellings (camelCase and underscores) since this
-just loops through all variables the object exposes. It is preferred to use the
-ones with underscores when multiple exist.
-
-In addition, if an instance has AWS Tags associated with it, each tag is a new
-variable named:
- - ec2_tag_[Key] = [Value]
-
-Security groups are comma-separated in 'ec2_security_group_ids' and
-'ec2_security_group_names'.
-'''
-
-# (c) 2012, Peter Sankauskas
-#
-# This file is part of Ansible,
-#
-# Ansible is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# Ansible is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with Ansible.  If not, see <http://www.gnu.org/licenses/>.
-
-######################################################################
-
-import sys
-import os
-import argparse
-import re
-from time import time
-import boto
-from boto import ec2
-from boto import rds
-from boto import elasticache
-from boto import route53
-import six
-
-from six.moves import configparser
-from collections import defaultdict
-
-try:
-    import json
-except ImportError:
-    import simplejson as json
-
-
-class Ec2Inventory(object):
-
-    def _empty_inventory(self):
-        return {"_meta" : {"hostvars" : {}}}
-
-    def __init__(self):
-        ''' Main execution path '''
-
-        # Inventory grouped by instance IDs, tags, security groups, regions,
-        # and availability zones
-        self.inventory = self._empty_inventory()
-
-        # Index of hostname (address) to instance ID
-        self.index = {}
-
-        # Boto profile to use (if any)
-        self.boto_profile = None
-
-        # Read settings and parse CLI arguments
-        self.parse_cli_args()
-        self.read_settings()
-
-        # Make sure that profile_name is not passed at all if not set
-        # as pre 2.24 boto will fall over otherwise
-        if self.boto_profile:
-            if not hasattr(boto.ec2.EC2Connection, 'profile_name'):
-                self.fail_with_error("boto version must be >= 2.24 to use profile")
-
-        # Cache
-        if self.args.refresh_cache:
-            self.do_api_calls_update_cache()
-        elif not self.is_cache_valid():
-            self.do_api_calls_update_cache()
-
-        # Data to print
-        if self.args.host:
-            data_to_print = self.get_host_info()
-
-        elif self.args.list:
-            # Display list of instances for inventory
-            if self.inventory == self._empty_inventory():
-                data_to_print = self.get_inventory_from_cache()
-            else:
-                data_to_print = self.json_format_dict(self.inventory, True)
-
-        print(data_to_print)
-
-
-    def is_cache_valid(self):
-        ''' Determines if the cache files have expired, or if it is still valid '''
-
-        if os.path.isfile(self.cache_path_cache):
-            mod_time = os.path.getmtime(self.cache_path_cache)
-            current_time = time()
-            if (mod_time + self.cache_max_age) > current_time:
-                if os.path.isfile(self.cache_path_index):
-                    return True
-
-        return False
-
-
-    def read_settings(self):
-        ''' Reads the settings from the ec2.ini file '''
-        if six.PY3:
-            config = configparser.ConfigParser()
-        else:
-            config = configparser.SafeConfigParser()
-        ec2_default_ini_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'ec2.ini')
-        ec2_ini_path = os.path.expanduser(os.path.expandvars(os.environ.get('EC2_INI_PATH', ec2_default_ini_path)))
-        config.read(ec2_ini_path)
-
-        # is eucalyptus?
-        self.eucalyptus_host = None
-        self.eucalyptus = False
-        if config.has_option('ec2', 'eucalyptus'):
-            self.eucalyptus = config.getboolean('ec2', 'eucalyptus')
-        if self.eucalyptus and config.has_option('ec2', 'eucalyptus_host'):
-            self.eucalyptus_host = config.get('ec2', 'eucalyptus_host')
-
-        # Regions
-        self.regions = []
-        configRegions = config.get('ec2', 'regions')
-        configRegions_exclude = config.get('ec2', 'regions_exclude')
-        if (configRegions == 'all'):
-            if self.eucalyptus_host:
-                self.regions.append(boto.connect_euca(host=self.eucalyptus_host).region.name)
-            else:
-                for regionInfo in ec2.regions():
-                    if regionInfo.name not in configRegions_exclude:
-                        self.regions.append(regionInfo.name)
-        else:
-            self.regions = configRegions.split(",")
-
-        # Destination addresses
-        self.destination_variable = config.get('ec2', 'destination_variable')
-        self.vpc_destination_variable = config.get('ec2', 'vpc_destination_variable')
-
-        if config.has_option('ec2', 'hostname_variable'):
-            self.hostname_variable = config.get('ec2', 'hostname_variable')
-        else:
-            self.hostname_variable = None
-
-        if config.has_option('ec2', 'destination_format') and \
-                config.has_option('ec2', 'destination_format_tags'):
-            self.destination_format = config.get('ec2', 'destination_format')
-            self.destination_format_tags = config.get('ec2', 'destination_format_tags').split(',')
-        else:
-            self.destination_format = None
-            self.destination_format_tags = None
-
-        # Route53
-        self.route53_enabled = config.getboolean('ec2', 'route53')
-        self.route53_excluded_zones = []
-        if config.has_option('ec2', 'route53_excluded_zones'):
-            self.route53_excluded_zones.extend(
-                    config.get('ec2', 'route53_excluded_zones', '').split(','))
-
-        # Include RDS instances?
-        self.rds_enabled = True
-        if config.has_option('ec2', 'rds'):
-            self.rds_enabled = config.getboolean('ec2', 'rds')
-
-        # Include ElastiCache instances?
-        self.elasticache_enabled = True
-        if config.has_option('ec2', 'elasticache'):
-            self.elasticache_enabled = config.getboolean('ec2', 'elasticache')
-
-        # Return all EC2 instances?
-        if config.has_option('ec2', 'all_instances'):
-            self.all_instances = config.getboolean('ec2', 'all_instances')
-        else:
-            self.all_instances = False
-
-        # Instance states to be gathered in inventory. Default is 'running'.
-        # Setting 'all_instances' to 'yes' overrides this option.
-        ec2_valid_instance_states = [
-            'pending',
-            'running',
-            'shutting-down',
-            'terminated',
-            'stopping',
-            'stopped'
-        ]
-        self.ec2_instance_states = []
-        if self.all_instances:
-            self.ec2_instance_states = ec2_valid_instance_states
-        elif config.has_option('ec2', 'instance_states'):
-            for instance_state in config.get('ec2', 'instance_states').split(','):
-                instance_state = instance_state.strip()
-                if instance_state not in ec2_valid_instance_states:
-                    continue
-                self.ec2_instance_states.append(instance_state)
-        else:
-            self.ec2_instance_states = ['running']
-
-        # Return all RDS instances? (if RDS is enabled)
-        if config.has_option('ec2', 'all_rds_instances') and self.rds_enabled:
-            self.all_rds_instances = config.getboolean('ec2', 'all_rds_instances')
-        else:
-            self.all_rds_instances = False
-
-        # Return all ElastiCache replication groups? (if ElastiCache is enabled)
-        if config.has_option('ec2', 'all_elasticache_replication_groups') and self.elasticache_enabled:
-            self.all_elasticache_replication_groups = config.getboolean('ec2', 'all_elasticache_replication_groups')
-        else:
-            self.all_elasticache_replication_groups = False
-
-        # Return all ElastiCache clusters? (if ElastiCache is enabled)
-        if config.has_option('ec2', 'all_elasticache_clusters') and self.elasticache_enabled:
-            self.all_elasticache_clusters = config.getboolean('ec2', 'all_elasticache_clusters')
-        else:
-            self.all_elasticache_clusters = False
-
-        # Return all ElastiCache nodes? (if ElastiCache is enabled)
-        if config.has_option('ec2', 'all_elasticache_nodes') and self.elasticache_enabled:
-            self.all_elasticache_nodes = config.getboolean('ec2', 'all_elasticache_nodes')
-        else:
-            self.all_elasticache_nodes = False
-
-        # boto configuration profile (prefer CLI argument)
-        self.boto_profile = self.args.boto_profile
-        if config.has_option('ec2', 'boto_profile') and not self.boto_profile:
-            self.boto_profile = config.get('ec2', 'boto_profile')
-
-        # Cache related
-        cache_dir = os.path.expanduser(config.get('ec2', 'cache_path'))
-        if self.boto_profile:
-            cache_dir = os.path.join(cache_dir, 'profile_' + self.boto_profile)
-        if not os.path.exists(cache_dir):
-            os.makedirs(cache_dir)
-
-        cache_name = 'ansible-ec2'
-        aws_profile = lambda: (self.boto_profile or
-                               os.environ.get('AWS_PROFILE') or
-                               os.environ.get('AWS_ACCESS_KEY_ID'))
-        if aws_profile():
-            cache_name = '%s-%s' % (cache_name, aws_profile())
-        self.cache_path_cache = cache_dir + "/%s.cache" % cache_name
-        self.cache_path_index = cache_dir + "/%s.index" % cache_name
-        self.cache_max_age = config.getint('ec2', 'cache_max_age')
-
-        if config.has_option('ec2', 'expand_csv_tags'):
-            self.expand_csv_tags = config.getboolean('ec2', 'expand_csv_tags')
-        else:
-            self.expand_csv_tags = False
-
-        # Configure nested groups instead of flat namespace.
-        if config.has_option('ec2', 'nested_groups'):
-            self.nested_groups = config.getboolean('ec2', 'nested_groups')
-        else:
-            self.nested_groups = False
-
-        # Replace dash or not in group names
-        if config.has_option('ec2', 'replace_dash_in_groups'):
-            self.replace_dash_in_groups = config.getboolean('ec2', 'replace_dash_in_groups')
-        else:
-            self.replace_dash_in_groups = True
-
-        # Configure which groups should be created.
-        group_by_options = [
-            'group_by_instance_id',
-            'group_by_region',
-            'group_by_availability_zone',
-            'group_by_ami_id',
-            'group_by_instance_type',
-            'group_by_key_pair',
-            'group_by_vpc_id',
-            'group_by_security_group',
-            'group_by_tag_keys',
-            'group_by_tag_none',
-            'group_by_route53_names',
-            'group_by_rds_engine',
-            'group_by_rds_parameter_group',
-            'group_by_elasticache_engine',
-            'group_by_elasticache_cluster',
-            'group_by_elasticache_parameter_group',
-            'group_by_elasticache_replication_group',
-        ]
-        for option in group_by_options:
-            if config.has_option('ec2', option):
-                setattr(self, option, config.getboolean('ec2', option))
-            else:
-                setattr(self, option, True)
-
-        # Do we need to just include hosts that match a pattern?
-        try:
-            pattern_include = config.get('ec2', 'pattern_include')
-            if pattern_include and len(pattern_include) > 0:
-                self.pattern_include = re.compile(pattern_include)
-            else:
-                self.pattern_include = None
-        except configparser.NoOptionError:
-            self.pattern_include = None
-
-        # Do we need to exclude hosts that match a pattern?
-        try:
-            pattern_exclude = config.get('ec2', 'pattern_exclude');
-            if pattern_exclude and len(pattern_exclude) > 0:
-                self.pattern_exclude = re.compile(pattern_exclude)
-            else:
-                self.pattern_exclude = None
-        except configparser.NoOptionError:
-            self.pattern_exclude = None
-
-        # Instance filters (see boto and EC2 API docs). Ignore invalid filters.
-        self.ec2_instance_filters = defaultdict(list)
-        if config.has_option('ec2', 'instance_filters'):
-
-            filters = [f for f in config.get('ec2', 'instance_filters').split(',') if f]
-
-            for instance_filter in filters:
-                instance_filter = instance_filter.strip()
-                if not instance_filter or '=' not in instance_filter:
-                    continue
-                filter_key, filter_value = [x.strip() for x in instance_filter.split('=', 1)]
-                if not filter_key:
-                    continue
-                self.ec2_instance_filters[filter_key].append(filter_value)
-
-    def parse_cli_args(self):
-        ''' Command line argument processing '''
-
-        parser = argparse.ArgumentParser(description='Produce an Ansible Inventory file based on EC2')
-        parser.add_argument('--list', action='store_true', default=True,
-                            help='List instances (default: True)')
-        parser.add_argument('--host', action='store',
-                            help='Get all the variables about a specific instance')
-        parser.add_argument('--refresh-cache', action='store_true', default=False,
-                            help='Force refresh of cache by making API requests to EC2 (default: False - use cache files)')
-        parser.add_argument('--profile', '--boto-profile', action='store', dest='boto_profile',
-                            help='Use boto profile for connections to EC2')
-        self.args = parser.parse_args()
-
-
-    def do_api_calls_update_cache(self):
-        ''' Do API calls to each region, and save data in cache files '''
-
-        if self.route53_enabled:
-            self.get_route53_records()
-
-        for region in self.regions:
-            self.get_instances_by_region(region)
-            if self.rds_enabled:
-                self.get_rds_instances_by_region(region)
-            if self.elasticache_enabled:
-                self.get_elasticache_clusters_by_region(region)
-                self.get_elasticache_replication_groups_by_region(region)
-
-        self.write_to_cache(self.inventory, self.cache_path_cache)
-        self.write_to_cache(self.index, self.cache_path_index)
-
-    def connect(self, region):
-        ''' create connection to api server'''
-        if self.eucalyptus:
-            conn = boto.connect_euca(host=self.eucalyptus_host)
-            conn.APIVersion = '2010-08-31'
-        else:
-            conn = self.connect_to_aws(ec2, region)
-        return conn
-
-    def boto_fix_security_token_in_profile(self, connect_args):
-        ''' monkey patch for boto issue boto/boto#2100 '''
-        profile = 'profile ' + self.boto_profile
-        if boto.config.has_option(profile, 'aws_security_token'):
-            connect_args['security_token'] = boto.config.get(profile, 'aws_security_token')
-        return connect_args
-
-    def connect_to_aws(self, module, region):
-        connect_args = {}
-
-        # only pass the profile name if it's set (as it is not supported by older boto versions)
-        if self.boto_profile:
-            connect_args['profile_name'] = self.boto_profile
-            self.boto_fix_security_token_in_profile(connect_args)
-
-        conn = module.connect_to_region(region, **connect_args)
-        # connect_to_region will fail "silently" by returning None if the region name is wrong or not supported
-        if conn is None:
-            self.fail_with_error("region name: %s likely not supported, or AWS is down.  connection to region failed." % region)
-        return conn
-
-    def get_instances_by_region(self, region):
-        ''' Makes an AWS EC2 API call to the list of instances in a particular
-        region '''
-
-        try:
-            conn = self.connect(region)
-            reservations = []
-            if self.ec2_instance_filters:
-                for filter_key, filter_values in self.ec2_instance_filters.items():
-                    reservations.extend(conn.get_all_instances(filters = { filter_key : filter_values }))
-            else:
-                reservations = conn.get_all_instances()
-
-            for reservation in reservations:
-                for instance in reservation.instances:
-                    self.add_instance(instance, region)
-
-        except boto.exception.BotoServerError as e:
-            if e.error_code == 'AuthFailure':
-                error = self.get_auth_error_message()
-            else:
-                backend = 'Eucalyptus' if self.eucalyptus else 'AWS'
-                error = "Error connecting to %s backend.\n%s" % (backend, e.message)
-            self.fail_with_error(error, 'getting EC2 instances')
-
-    def get_rds_instances_by_region(self, region):
-        ''' Makes an AWS API call to the list of RDS instances in a particular
-        region '''
-
-        try:
-            conn = self.connect_to_aws(rds, region)
-            if conn:
-                marker = None
-                while True:
-                    instances = conn.get_all_dbinstances(marker=marker)
-                    marker = instances.marker
-                    for instance in instances:
-                        self.add_rds_instance(instance, region)
-                    if not marker:
-                        break
-        except boto.exception.BotoServerError as e:
-            error = e.reason
-
-            if e.error_code == 'AuthFailure':
-                error = self.get_auth_error_message()
-            if not e.reason == "Forbidden":
-                error = "Looks like AWS RDS is down:\n%s" % e.message
-            self.fail_with_error(error, 'getting RDS instances')
-
-    def get_elasticache_clusters_by_region(self, region):
-        ''' Makes an AWS API call to the list of ElastiCache clusters (with
-        nodes' info) in a particular region.'''
-
-        # ElastiCache boto module doesn't provide a get_all_intances method,
-        # that's why we need to call describe directly (it would be called by
-        # the shorthand method anyway...)
-        try:
-            conn = self.connect_to_aws(elasticache, region)
-            if conn:
-                # show_cache_node_info = True
-                # because we also want nodes' information
-                response = conn.describe_cache_clusters(None, None, None, True)
-
-        except boto.exception.BotoServerError as e:
-            error = e.reason
-
-            if e.error_code == 'AuthFailure':
-                error = self.get_auth_error_message()
-            if not e.reason == "Forbidden":
-                error = "Looks like AWS ElastiCache is down:\n%s" % e.message
-            self.fail_with_error(error, 'getting ElastiCache clusters')
-
-        try:
-            # Boto also doesn't provide wrapper classes to CacheClusters or
-            # CacheNodes. Because of that wo can't make use of the get_list
-            # method in the AWSQueryConnection. Let's do the work manually
-            clusters = response['DescribeCacheClustersResponse']['DescribeCacheClustersResult']['CacheClusters']
-
-        except KeyError as e:
-            error = "ElastiCache query to AWS failed (unexpected format)."
-            self.fail_with_error(error, 'getting ElastiCache clusters')
-
-        for cluster in clusters:
-            self.add_elasticache_cluster(cluster, region)
-
-    def get_elasticache_replication_groups_by_region(self, region):
-        ''' Makes an AWS API call to the list of ElastiCache replication groups
-        in a particular region.'''
-
-        # ElastiCache boto module doesn't provide a get_all_intances method,
-        # that's why we need to call describe directly (it would be called by
-        # the shorthand method anyway...)
-        try:
-            conn = self.connect_to_aws(elasticache, region)
-            if conn:
-                response = conn.describe_replication_groups()
-
-        except boto.exception.BotoServerError as e:
-            error = e.reason
-
-            if e.error_code == 'AuthFailure':
-                error = self.get_auth_error_message()
-            if not e.reason == "Forbidden":
-                error = "Looks like AWS ElastiCache [Replication Groups] is down:\n%s" % e.message
-            self.fail_with_error(error, 'getting ElastiCache clusters')
-
-        try:
-            # Boto also doesn't provide wrapper classes to ReplicationGroups
-            # Because of that wo can't make use of the get_list method in the
-            # AWSQueryConnection. Let's do the work manually
-            replication_groups = response['DescribeReplicationGroupsResponse']['DescribeReplicationGroupsResult']['ReplicationGroups']
-
-        except KeyError as e:
-            error = "ElastiCache [Replication Groups] query to AWS failed (unexpected format)."
-            self.fail_with_error(error, 'getting ElastiCache clusters')
-
-        for replication_group in replication_groups:
-            self.add_elasticache_replication_group(replication_group, region)
-
-    def get_auth_error_message(self):
-        ''' create an informative error message if there is an issue authenticating'''
-        errors = ["Authentication error retrieving ec2 inventory."]
-        if None in [os.environ.get('AWS_ACCESS_KEY_ID'), os.environ.get('AWS_SECRET_ACCESS_KEY')]:
-            errors.append(' - No AWS_ACCESS_KEY_ID or AWS_SECRET_ACCESS_KEY environment vars found')
-        else:
-            errors.append(' - AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY environment vars found but may not be correct')
-
-        boto_paths = ['/etc/boto.cfg', '~/.boto', '~/.aws/credentials']
-        boto_config_found = list(p for p in boto_paths if os.path.isfile(os.path.expanduser(p)))
-        if len(boto_config_found) > 0:
-            errors.append(" - Boto configs found at '%s', but the credentials contained may not be correct" % ', '.join(boto_config_found))
-        else:
-            errors.append(" - No Boto config found at any expected location '%s'" % ', '.join(boto_paths))
-
-        return '\n'.join(errors)
-
-    def fail_with_error(self, err_msg, err_operation=None):
-        '''log an error to std err for ansible-playbook to consume and exit'''
-        if err_operation:
-            err_msg = 'ERROR: "{err_msg}", while: {err_operation}'.format(
-                    err_msg=err_msg, err_operation=err_operation)
-        sys.stderr.write(err_msg)
-        sys.exit(1)
-
-    def get_instance(self, region, instance_id):
-        conn = self.connect(region)
-
-        reservations = conn.get_all_instances([instance_id])
-        for reservation in reservations:
-            for instance in reservation.instances:
-                return instance
-
-    def add_instance(self, instance, region):
-        ''' Adds an instance to the inventory and index, as long as it is
-        addressable '''
-
-        # Only return instances with desired instance states
-        if instance.state not in self.ec2_instance_states:
-            return
-
-        # Select the best destination address
-        if self.destination_format and self.destination_format_tags:
-            dest = self.destination_format.format(*[ getattr(instance, 'tags').get(tag, '') for tag in self.destination_format_tags ])
-        elif instance.subnet_id:
-            dest = getattr(instance, self.vpc_destination_variable, None)
-            if dest is None:
-                dest = getattr(instance, 'tags').get(self.vpc_destination_variable, None)
-        else:
-            dest = getattr(instance, self.destination_variable, None)
-            if dest is None:
-                dest = getattr(instance, 'tags').get(self.destination_variable, None)
-
-        if not dest:
-            # Skip instances we cannot address (e.g. private VPC subnet)
-            return
-
-        # Set the inventory name
-        hostname = None
-        if self.hostname_variable:
-            if self.hostname_variable.startswith('tag_'):
-                hostname = instance.tags.get(self.hostname_variable[4:], None)
-            else:
-                hostname = getattr(instance, self.hostname_variable)
-
-        # If we can't get a nice hostname, use the destination address
-        if not hostname:
-            hostname = dest
-        else:
-            hostname = self.to_safe(hostname).lower()
-
-        # if we only want to include hosts that match a pattern, skip those that don't
-        if self.pattern_include and not self.pattern_include.match(hostname):
-            return
-
-        # if we need to exclude hosts that match a pattern, skip those
-        if self.pattern_exclude and self.pattern_exclude.match(hostname):
-            return
-
-        # Add to index
-        self.index[hostname] = [region, instance.id]
-
-        # Inventory: Group by instance ID (always a group of 1)
-        if self.group_by_instance_id:
-            self.inventory[instance.id] = [hostname]
-            if self.nested_groups:
-                self.push_group(self.inventory, 'instances', instance.id)
-
-        # Inventory: Group by region
-        if self.group_by_region:
-            self.push(self.inventory, region, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'regions', region)
-
-        # Inventory: Group by availability zone
-        if self.group_by_availability_zone:
-            self.push(self.inventory, instance.placement, hostname)
-            if self.nested_groups:
-                if self.group_by_region:
-                    self.push_group(self.inventory, region, instance.placement)
-                self.push_group(self.inventory, 'zones', instance.placement)
-
-        # Inventory: Group by Amazon Machine Image (AMI) ID
-        if self.group_by_ami_id:
-            ami_id = self.to_safe(instance.image_id)
-            self.push(self.inventory, ami_id, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'images', ami_id)
-
-        # Inventory: Group by instance type
-        if self.group_by_instance_type:
-            type_name = self.to_safe('type_' + instance.instance_type)
-            self.push(self.inventory, type_name, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'types', type_name)
-
-        # Inventory: Group by key pair
-        if self.group_by_key_pair and instance.key_name:
-            key_name = self.to_safe('key_' + instance.key_name)
-            self.push(self.inventory, key_name, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'keys', key_name)
-
-        # Inventory: Group by VPC
-        if self.group_by_vpc_id and instance.vpc_id:
-            vpc_id_name = self.to_safe('vpc_id_' + instance.vpc_id)
-            self.push(self.inventory, vpc_id_name, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'vpcs', vpc_id_name)
-
-        # Inventory: Group by security group
-        if self.group_by_security_group:
-            try:
-                for group in instance.groups:
-                    key = self.to_safe("security_group_" + group.name)
-                    self.push(self.inventory, key, hostname)
-                    if self.nested_groups:
-                        self.push_group(self.inventory, 'security_groups', key)
-            except AttributeError:
-                self.fail_with_error('\n'.join(['Package boto seems a bit older.',
-                                                'Please upgrade boto >= 2.3.0.']))
-
-        # Inventory: Group by tag keys
-        if self.group_by_tag_keys:
-            for k, v in instance.tags.items():
-                if self.expand_csv_tags and v and ',' in v:
-                    values = map(lambda x: x.strip(), v.split(','))
-                else:
-                    values = [v]
-
-                for v in values:
-                    if v:
-                        key = self.to_safe("tag_" + k + "=" + v)
-                    else:
-                        key = self.to_safe("tag_" + k)
-                    self.push(self.inventory, key, hostname)
-                    if self.nested_groups:
-                        self.push_group(self.inventory, 'tags', self.to_safe("tag_" + k))
-                        if v:
-                            self.push_group(self.inventory, self.to_safe("tag_" + k), key)
-
-        # Inventory: Group by Route53 domain names if enabled
-        if self.route53_enabled and self.group_by_route53_names:
-            route53_names = self.get_instance_route53_names(instance)
-            for name in route53_names:
-                self.push(self.inventory, name, hostname)
-                if self.nested_groups:
-                    self.push_group(self.inventory, 'route53', name)
-
-        # Global Tag: instances without tags
-        if self.group_by_tag_none and len(instance.tags) == 0:
-            self.push(self.inventory, 'tag_none', hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'tags', 'tag_none')
-
-        # Global Tag: tag all EC2 instances
-        self.push(self.inventory, 'ec2', hostname)
-
-        self.inventory["_meta"]["hostvars"][hostname] = self.get_host_info_dict_from_instance(instance)
-        self.inventory["_meta"]["hostvars"][hostname]['ansible_ssh_host'] = dest
-
-
-    def add_rds_instance(self, instance, region):
-        ''' Adds an RDS instance to the inventory and index, as long as it is
-        addressable '''
-
-        # Only want available instances unless all_rds_instances is True
-        if not self.all_rds_instances and instance.status != 'available':
-            return
-
-        # Select the best destination address
-        dest = instance.endpoint[0]
-
-        if not dest:
-            # Skip instances we cannot address (e.g. private VPC subnet)
-            return
-
-        # Set the inventory name
-        hostname = None
-        if self.hostname_variable:
-            if self.hostname_variable.startswith('tag_'):
-                hostname = instance.tags.get(self.hostname_variable[4:], None)
-            else:
-                hostname = getattr(instance, self.hostname_variable)
-
-        # If we can't get a nice hostname, use the destination address
-        if not hostname:
-            hostname = dest
-
-        hostname = self.to_safe(hostname).lower()
-
-        # Add to index
-        self.index[hostname] = [region, instance.id]
-
-        # Inventory: Group by instance ID (always a group of 1)
-        if self.group_by_instance_id:
-            self.inventory[instance.id] = [hostname]
-            if self.nested_groups:
-                self.push_group(self.inventory, 'instances', instance.id)
-
-        # Inventory: Group by region
-        if self.group_by_region:
-            self.push(self.inventory, region, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'regions', region)
-
-        # Inventory: Group by availability zone
-        if self.group_by_availability_zone:
-            self.push(self.inventory, instance.availability_zone, hostname)
-            if self.nested_groups:
-                if self.group_by_region:
-                    self.push_group(self.inventory, region, instance.availability_zone)
-                self.push_group(self.inventory, 'zones', instance.availability_zone)
-
-        # Inventory: Group by instance type
-        if self.group_by_instance_type:
-            type_name = self.to_safe('type_' + instance.instance_class)
-            self.push(self.inventory, type_name, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'types', type_name)
-
-        # Inventory: Group by VPC
-        if self.group_by_vpc_id and instance.subnet_group and instance.subnet_group.vpc_id:
-            vpc_id_name = self.to_safe('vpc_id_' + instance.subnet_group.vpc_id)
-            self.push(self.inventory, vpc_id_name, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'vpcs', vpc_id_name)
-
-        # Inventory: Group by security group
-        if self.group_by_security_group:
-            try:
-                if instance.security_group:
-                    key = self.to_safe("security_group_" + instance.security_group.name)
-                    self.push(self.inventory, key, hostname)
-                    if self.nested_groups:
-                        self.push_group(self.inventory, 'security_groups', key)
-
-            except AttributeError:
-                self.fail_with_error('\n'.join(['Package boto seems a bit older.',
-                                                'Please upgrade boto >= 2.3.0.']))
-
-
-        # Inventory: Group by engine
-        if self.group_by_rds_engine:
-            self.push(self.inventory, self.to_safe("rds_" + instance.engine), hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'rds_engines', self.to_safe("rds_" + instance.engine))
-
-        # Inventory: Group by parameter group
-        if self.group_by_rds_parameter_group:
-            self.push(self.inventory, self.to_safe("rds_parameter_group_" + instance.parameter_group.name), hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'rds_parameter_groups', self.to_safe("rds_parameter_group_" + instance.parameter_group.name))
-
-        # Global Tag: all RDS instances
-        self.push(self.inventory, 'rds', hostname)
-
-        self.inventory["_meta"]["hostvars"][hostname] = self.get_host_info_dict_from_instance(instance)
-        self.inventory["_meta"]["hostvars"][hostname]['ansible_ssh_host'] = dest
-
-    def add_elasticache_cluster(self, cluster, region):
-        ''' Adds an ElastiCache cluster to the inventory and index, as long as
-        it's nodes are addressable '''
-
-        # Only want available clusters unless all_elasticache_clusters is True
-        if not self.all_elasticache_clusters and cluster['CacheClusterStatus'] != 'available':
-            return
-
-        # Select the best destination address
-        if 'ConfigurationEndpoint' in cluster and cluster['ConfigurationEndpoint']:
-            # Memcached cluster
-            dest = cluster['ConfigurationEndpoint']['Address']
-            is_redis = False
-        else:
-            # Redis sigle node cluster
-            # Because all Redis clusters are single nodes, we'll merge the
-            # info from the cluster with info about the node
-            dest = cluster['CacheNodes'][0]['Endpoint']['Address']
-            is_redis = True
-
-        if not dest:
-            # Skip clusters we cannot address (e.g. private VPC subnet)
-            return
-
-        # Add to index
-        self.index[dest] = [region, cluster['CacheClusterId']]
-
-        # Inventory: Group by instance ID (always a group of 1)
-        if self.group_by_instance_id:
-            self.inventory[cluster['CacheClusterId']] = [dest]
-            if self.nested_groups:
-                self.push_group(self.inventory, 'instances', cluster['CacheClusterId'])
-
-        # Inventory: Group by region
-        if self.group_by_region and not is_redis:
-            self.push(self.inventory, region, dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'regions', region)
-
-        # Inventory: Group by availability zone
-        if self.group_by_availability_zone and not is_redis:
-            self.push(self.inventory, cluster['PreferredAvailabilityZone'], dest)
-            if self.nested_groups:
-                if self.group_by_region:
-                    self.push_group(self.inventory, region, cluster['PreferredAvailabilityZone'])
-                self.push_group(self.inventory, 'zones', cluster['PreferredAvailabilityZone'])
-
-        # Inventory: Group by node type
-        if self.group_by_instance_type and not is_redis:
-            type_name = self.to_safe('type_' + cluster['CacheNodeType'])
-            self.push(self.inventory, type_name, dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'types', type_name)
-
-        # Inventory: Group by VPC (information not available in the current
-        # AWS API version for ElastiCache)
-
-        # Inventory: Group by security group
-        if self.group_by_security_group and not is_redis:
-
-            # Check for the existence of the 'SecurityGroups' key and also if
-            # this key has some value. When the cluster is not placed in a SG
-            # the query can return None here and cause an error.
-            if 'SecurityGroups' in cluster and cluster['SecurityGroups'] is not None:
-                for security_group in cluster['SecurityGroups']:
-                    key = self.to_safe("security_group_" + security_group['SecurityGroupId'])
-                    self.push(self.inventory, key, dest)
-                    if self.nested_groups:
-                        self.push_group(self.inventory, 'security_groups', key)
-
-        # Inventory: Group by engine
-        if self.group_by_elasticache_engine and not is_redis:
-            self.push(self.inventory, self.to_safe("elasticache_" + cluster['Engine']), dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'elasticache_engines', self.to_safe(cluster['Engine']))
-
-        # Inventory: Group by parameter group
-        if self.group_by_elasticache_parameter_group:
-            self.push(self.inventory, self.to_safe("elasticache_parameter_group_" + cluster['CacheParameterGroup']['CacheParameterGroupName']), dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'elasticache_parameter_groups', self.to_safe(cluster['CacheParameterGroup']['CacheParameterGroupName']))
-
-        # Inventory: Group by replication group
-        if self.group_by_elasticache_replication_group and 'ReplicationGroupId' in cluster and cluster['ReplicationGroupId']:
-            self.push(self.inventory, self.to_safe("elasticache_replication_group_" + cluster['ReplicationGroupId']), dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'elasticache_replication_groups', self.to_safe(cluster['ReplicationGroupId']))
-
-        # Global Tag: all ElastiCache clusters
-        self.push(self.inventory, 'elasticache_clusters', cluster['CacheClusterId'])
-
-        host_info = self.get_host_info_dict_from_describe_dict(cluster)
-
-        self.inventory["_meta"]["hostvars"][dest] = host_info
-
-        # Add the nodes
-        for node in cluster['CacheNodes']:
-            self.add_elasticache_node(node, cluster, region)
-
-    def add_elasticache_node(self, node, cluster, region):
-        ''' Adds an ElastiCache node to the inventory and index, as long as
-        it is addressable '''
-
-        # Only want available nodes unless all_elasticache_nodes is True
-        if not self.all_elasticache_nodes and node['CacheNodeStatus'] != 'available':
-            return
-
-        # Select the best destination address
-        dest = node['Endpoint']['Address']
-
-        if not dest:
-            # Skip nodes we cannot address (e.g. private VPC subnet)
-            return
-
-        node_id = self.to_safe(cluster['CacheClusterId'] + '_' + node['CacheNodeId'])
-
-        # Add to index
-        self.index[dest] = [region, node_id]
-
-        # Inventory: Group by node ID (always a group of 1)
-        if self.group_by_instance_id:
-            self.inventory[node_id] = [dest]
-            if self.nested_groups:
-                self.push_group(self.inventory, 'instances', node_id)
-
-        # Inventory: Group by region
-        if self.group_by_region:
-            self.push(self.inventory, region, dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'regions', region)
-
-        # Inventory: Group by availability zone
-        if self.group_by_availability_zone:
-            self.push(self.inventory, cluster['PreferredAvailabilityZone'], dest)
-            if self.nested_groups:
-                if self.group_by_region:
-                    self.push_group(self.inventory, region, cluster['PreferredAvailabilityZone'])
-                self.push_group(self.inventory, 'zones', cluster['PreferredAvailabilityZone'])
-
-        # Inventory: Group by node type
-        if self.group_by_instance_type:
-            type_name = self.to_safe('type_' + cluster['CacheNodeType'])
-            self.push(self.inventory, type_name, dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'types', type_name)
-
-        # Inventory: Group by VPC (information not available in the current
-        # AWS API version for ElastiCache)
-
-        # Inventory: Group by security group
-        if self.group_by_security_group:
-
-            # Check for the existence of the 'SecurityGroups' key and also if
-            # this key has some value. When the cluster is not placed in a SG
-            # the query can return None here and cause an error.
-            if 'SecurityGroups' in cluster and cluster['SecurityGroups'] is not None:
-                for security_group in cluster['SecurityGroups']:
-                    key = self.to_safe("security_group_" + security_group['SecurityGroupId'])
-                    self.push(self.inventory, key, dest)
-                    if self.nested_groups:
-                        self.push_group(self.inventory, 'security_groups', key)
-
-        # Inventory: Group by engine
-        if self.group_by_elasticache_engine:
-            self.push(self.inventory, self.to_safe("elasticache_" + cluster['Engine']), dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'elasticache_engines', self.to_safe("elasticache_" + cluster['Engine']))
-
-        # Inventory: Group by parameter group (done at cluster level)
-
-        # Inventory: Group by replication group (done at cluster level)
-
-        # Inventory: Group by ElastiCache Cluster
-        if self.group_by_elasticache_cluster:
-            self.push(self.inventory, self.to_safe("elasticache_cluster_" + cluster['CacheClusterId']), dest)
-
-        # Global Tag: all ElastiCache nodes
-        self.push(self.inventory, 'elasticache_nodes', dest)
-
-        host_info = self.get_host_info_dict_from_describe_dict(node)
-
-        if dest in self.inventory["_meta"]["hostvars"]:
-            self.inventory["_meta"]["hostvars"][dest].update(host_info)
-        else:
-            self.inventory["_meta"]["hostvars"][dest] = host_info
-
-    def add_elasticache_replication_group(self, replication_group, region):
-        ''' Adds an ElastiCache replication group to the inventory and index '''
-
-        # Only want available clusters unless all_elasticache_replication_groups is True
-        if not self.all_elasticache_replication_groups and replication_group['Status'] != 'available':
-            return
-
-        # Select the best destination address (PrimaryEndpoint)
-        dest = replication_group['NodeGroups'][0]['PrimaryEndpoint']['Address']
-
-        if not dest:
-            # Skip clusters we cannot address (e.g. private VPC subnet)
-            return
-
-        # Add to index
-        self.index[dest] = [region, replication_group['ReplicationGroupId']]
-
-        # Inventory: Group by ID (always a group of 1)
-        if self.group_by_instance_id:
-            self.inventory[replication_group['ReplicationGroupId']] = [dest]
-            if self.nested_groups:
-                self.push_group(self.inventory, 'instances', replication_group['ReplicationGroupId'])
-
-        # Inventory: Group by region
-        if self.group_by_region:
-            self.push(self.inventory, region, dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'regions', region)
-
-        # Inventory: Group by availability zone (doesn't apply to replication groups)
-
-        # Inventory: Group by node type (doesn't apply to replication groups)
-
-        # Inventory: Group by VPC (information not available in the current
-        # AWS API version for replication groups
-
-        # Inventory: Group by security group (doesn't apply to replication groups)
-        # Check this value in cluster level
-
-        # Inventory: Group by engine (replication groups are always Redis)
-        if self.group_by_elasticache_engine:
-            self.push(self.inventory, 'elasticache_redis', dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'elasticache_engines', 'redis')
-
-        # Global Tag: all ElastiCache clusters
-        self.push(self.inventory, 'elasticache_replication_groups', replication_group['ReplicationGroupId'])
-
-        host_info = self.get_host_info_dict_from_describe_dict(replication_group)
-
-        self.inventory["_meta"]["hostvars"][dest] = host_info
-
-    def get_route53_records(self):
-        ''' Get and store the map of resource records to domain names that
-        point to them. '''
-
-        r53_conn = route53.Route53Connection()
-        all_zones = r53_conn.get_zones()
-
-        route53_zones = [ zone for zone in all_zones if zone.name[:-1]
-                          not in self.route53_excluded_zones ]
-
-        self.route53_records = {}
-
-        for zone in route53_zones:
-            rrsets = r53_conn.get_all_rrsets(zone.id)
-
-            for record_set in rrsets:
-                record_name = record_set.name
-
-                if record_name.endswith('.'):
-                    record_name = record_name[:-1]
-
-                for resource in record_set.resource_records:
-                    self.route53_records.setdefault(resource, set())
-                    self.route53_records[resource].add(record_name)
-
-
-    def get_instance_route53_names(self, instance):
-        ''' Check if an instance is referenced in the records we have from
-        Route53. If it is, return the list of domain names pointing to said
-        instance. If nothing points to it, return an empty list. '''
-
-        instance_attributes = [ 'public_dns_name', 'private_dns_name',
-                                'ip_address', 'private_ip_address' ]
-
-        name_list = set()
-
-        for attrib in instance_attributes:
-            try:
-                value = getattr(instance, attrib)
-            except AttributeError:
-                continue
-
-            if value in self.route53_records:
-                name_list.update(self.route53_records[value])
-
-        return list(name_list)
-
-    def get_host_info_dict_from_instance(self, instance):
-        instance_vars = {}
-        for key in vars(instance):
-            value = getattr(instance, key)
-            key = self.to_safe('ec2_' + key)
-
-            # Handle complex types
-            # state/previous_state changed to properties in boto in https://github.com/boto/boto/commit/a23c379837f698212252720d2af8dec0325c9518
-            if key == 'ec2__state':
-                instance_vars['ec2_state'] = instance.state or ''
-                instance_vars['ec2_state_code'] = instance.state_code
-            elif key == 'ec2__previous_state':
-                instance_vars['ec2_previous_state'] = instance.previous_state or ''
-                instance_vars['ec2_previous_state_code'] = instance.previous_state_code
-            elif type(value) in [int, bool]:
-                instance_vars[key] = value
-            elif isinstance(value, six.string_types):
-                instance_vars[key] = value.strip()
-            elif type(value) == type(None):
-                instance_vars[key] = ''
-            elif key == 'ec2_region':
-                instance_vars[key] = value.name
-            elif key == 'ec2__placement':
-                instance_vars['ec2_placement'] = value.zone
-            elif key == 'ec2_tags':
-                for k, v in value.items():
-                    if self.expand_csv_tags and ',' in v:
-                        v = map(lambda x: x.strip(), v.split(','))
-                    key = self.to_safe('ec2_tag_' + k)
-                    instance_vars[key] = v
-            elif key == 'ec2_groups':
-                group_ids = []
-                group_names = []
-                for group in value:
-                    group_ids.append(group.id)
-                    group_names.append(group.name)
-                instance_vars["ec2_security_group_ids"] = ','.join([str(i) for i in group_ids])
-                instance_vars["ec2_security_group_names"] = ','.join([str(i) for i in group_names])
-            else:
-                pass
-                # TODO Product codes if someone finds them useful
-                #print key
-                #print type(value)
-                #print value
-
-        return instance_vars
-
-    def get_host_info_dict_from_describe_dict(self, describe_dict):
-        ''' Parses the dictionary returned by the API call into a flat list
-            of parameters. This method should be used only when 'describe' is
-            used directly because Boto doesn't provide specific classes. '''
-
-        # I really don't agree with prefixing everything with 'ec2'
-        # because EC2, RDS and ElastiCache are different services.
-        # I'm just following the pattern used until now to not break any
-        # compatibility.
-
-        host_info = {}
-        for key in describe_dict:
-            value = describe_dict[key]
-            key = self.to_safe('ec2_' + self.uncammelize(key))
-
-            # Handle complex types
-
-            # Target: Memcached Cache Clusters
-            if key == 'ec2_configuration_endpoint' and value:
-                host_info['ec2_configuration_endpoint_address'] = value['Address']
-                host_info['ec2_configuration_endpoint_port'] = value['Port']
-
-            # Target: Cache Nodes and Redis Cache Clusters (single node)
-            if key == 'ec2_endpoint' and value:
-                host_info['ec2_endpoint_address'] = value['Address']
-                host_info['ec2_endpoint_port'] = value['Port']
-
-            # Target: Redis Replication Groups
-            if key == 'ec2_node_groups' and value:
-                host_info['ec2_endpoint_address'] = value[0]['PrimaryEndpoint']['Address']
-                host_info['ec2_endpoint_port'] = value[0]['PrimaryEndpoint']['Port']
-                replica_count = 0
-                for node in value[0]['NodeGroupMembers']:
-                    if node['CurrentRole'] == 'primary':
-                        host_info['ec2_primary_cluster_address'] = node['ReadEndpoint']['Address']
-                        host_info['ec2_primary_cluster_port'] = node['ReadEndpoint']['Port']
-                        host_info['ec2_primary_cluster_id'] = node['CacheClusterId']
-                    elif node['CurrentRole'] == 'replica':
-                        host_info['ec2_replica_cluster_address_'+ str(replica_count)] = node['ReadEndpoint']['Address']
-                        host_info['ec2_replica_cluster_port_'+ str(replica_count)] = node['ReadEndpoint']['Port']
-                        host_info['ec2_replica_cluster_id_'+ str(replica_count)] = node['CacheClusterId']
-                        replica_count += 1
-
-            # Target: Redis Replication Groups
-            if key == 'ec2_member_clusters' and value:
-                host_info['ec2_member_clusters'] = ','.join([str(i) for i in value])
-
-            # Target: All Cache Clusters
-            elif key == 'ec2_cache_parameter_group':
-                host_info["ec2_cache_node_ids_to_reboot"] = ','.join([str(i) for i in value['CacheNodeIdsToReboot']])
-                host_info['ec2_cache_parameter_group_name'] = value['CacheParameterGroupName']
-                host_info['ec2_cache_parameter_apply_status'] = value['ParameterApplyStatus']
-
-            # Target: Almost everything
-            elif key == 'ec2_security_groups':
-
-                # Skip if SecurityGroups is None
-                # (it is possible to have the key defined but no value in it).
-                if value is not None:
-                    sg_ids = []
-                    for sg in value:
-                        sg_ids.append(sg['SecurityGroupId'])
-                    host_info["ec2_security_group_ids"] = ','.join([str(i) for i in sg_ids])
-
-            # Target: Everything
-            # Preserve booleans and integers
-            elif type(value) in [int, bool]:
-                host_info[key] = value
-
-            # Target: Everything
-            # Sanitize string values
-            elif isinstance(value, six.string_types):
-                host_info[key] = value.strip()
-
-            # Target: Everything
-            # Replace None by an empty string
-            elif type(value) == type(None):
-                host_info[key] = ''
-
-            else:
-                # Remove non-processed complex types
-                pass
-
-        return host_info
-
-    def get_host_info(self):
-        ''' Get variables about a specific host '''
-
-        if len(self.index) == 0:
-            # Need to load index from cache
-            self.load_index_from_cache()
-
-        if not self.args.host in self.index:
-            # try updating the cache
-            self.do_api_calls_update_cache()
-            if not self.args.host in self.index:
-                # host might not exist anymore
-                return self.json_format_dict({}, True)
-
-        (region, instance_id) = self.index[self.args.host]
-
-        instance = self.get_instance(region, instance_id)
-        return self.json_format_dict(self.get_host_info_dict_from_instance(instance), True)
-
-    def push(self, my_dict, key, element):
-        ''' Push an element onto an array that may not have been defined in
-        the dict '''
-        group_info = my_dict.setdefault(key, [])
-        if isinstance(group_info, dict):
-            host_list = group_info.setdefault('hosts', [])
-            host_list.append(element)
-        else:
-            group_info.append(element)
-
-    def push_group(self, my_dict, key, element):
-        ''' Push a group as a child of another group. '''
-        parent_group = my_dict.setdefault(key, {})
-        if not isinstance(parent_group, dict):
-            parent_group = my_dict[key] = {'hosts': parent_group}
-        child_groups = parent_group.setdefault('children', [])
-        if element not in child_groups:
-            child_groups.append(element)
-
-    def get_inventory_from_cache(self):
-        ''' Reads the inventory from the cache file and returns it as a JSON
-        object '''
-
-        cache = open(self.cache_path_cache, 'r')
-        json_inventory = cache.read()
-        return json_inventory
-
-
-    def load_index_from_cache(self):
-        ''' Reads the index from the cache file sets self.index '''
-
-        cache = open(self.cache_path_index, 'r')
-        json_index = cache.read()
-        self.index = json.loads(json_index)
-
-
-    def write_to_cache(self, data, filename):
-        ''' Writes data in JSON format to a file '''
-
-        json_data = self.json_format_dict(data, True)
-        cache = open(filename, 'w')
-        cache.write(json_data)
-        cache.close()
-
-    def uncammelize(self, key):
-        temp = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', key)
-        return re.sub('([a-z0-9])([A-Z])', r'\1_\2', temp).lower()
-
-    def to_safe(self, word):
-        ''' Converts 'bad' characters in a string to underscores so they can be used as Ansible groups '''
-        regex = "[^A-Za-z0-9\_"
-        if not self.replace_dash_in_groups:
-            regex += "\-"
-        return re.sub(regex + "]", "_", word)
-
-    def json_format_dict(self, data, pretty=False):
-        ''' Converts a dict to a JSON object and dumps it as a formatted
-        string '''
-
-        if pretty:
-            return json.dumps(data, sort_keys=True, indent=2)
-        else:
-            return json.dumps(data)
-
-
-# Run the script
-Ec2Inventory()
diff --git a/edge-1601-dc4/inventory b/edge-1601-dc4/inventory
deleted file mode 100644
index 0b97282..0000000
--- a/edge-1601-dc4/inventory
+++ /dev/null
@@ -1,74 +0,0 @@
-[tag_Name_dc3_n1]
-[tag_Name_dc3_n2]
-[tag_Name_dc3_n3]
-[tag_Name_dc3_n4]
-[tag_Name_dc3_n5]
-
-[planet:children]
-dc-1
-
-[dc-1:children]
-tag_Name_dc3_n1
-tag_Name_dc3_n2
-tag_Name_dc3_n3
-tag_Name_dc3_n4
-tag_Name_dc3_n5
-
-[ds:children]
-dc-1-ds
-
-[dc-1-ds:children]
-tag_Name_dc3_n2
-tag_Name_dc3_n3
-tag_Name_dc3_n4
-
-[ms:children]
-dc-1-ms
-
-[dc-1-ms:children]
-tag_Name_dc3_n1
-
-[ui:children]
-dc-1-ui
-
-[dc-1-ui:children]
-tag_Name_dc3_n1
-
-[ldap:children]
-dc-1-ldap
-
-[dc-1-ldap:children]
-tag_Name_dc3_n1
-
-[rmp:children]
-dc-1-rmp
-
-[dc-1-rmp:children]
-tag_Name_dc3_n3
-tag_Name_dc3_n4
-
-[qpid:children]
-dc-1-qpid
-
-[dc-1-qpid:children]
-tag_Name_dc3_n4
-tag_Name_dc3_n5
-
-[pg:children]
-dc-1-pg
-
-[dc-1-pg:children]
-dc-1-pgmaster
-dc-1-pgstandby
-
-[pgmaster:children]
-dc-1-pgmaster
-
-[dc-1-pgmaster:children]
-tag_Name_dc3_n4
-
-[pgstandby:children]
-dc-1-pgstandby
-
-[dc-1-pgstandby:children]
-tag_Name_dc3_n5
diff --git a/edge-1601-dc5-dc6/ec2.ini b/edge-1601-dc5-dc6/ec2.ini
deleted file mode 100644
index 36b3921..0000000
--- a/edge-1601-dc5-dc6/ec2.ini
+++ /dev/null
@@ -1,200 +0,0 @@
-# Ansible EC2 external inventory script settings
-#
-
-[ec2]
-
-# to talk to a private eucalyptus instance uncomment these lines
-# and edit edit eucalyptus_host to be the host name of your cloud controller
-#eucalyptus = True
-#eucalyptus_host = clc.cloud.domain.org
-
-# AWS regions to make calls to. Set this to 'all' to make request to all regions
-# in AWS and merge the results together. Alternatively, set this to a comma
-# separated list of regions. E.g. 'us-east-1,us-west-1,us-west-2'
-regions = all
-regions_exclude = us-gov-west-1,cn-north-1
-
-# When generating inventory, Ansible needs to know how to address a server.
-# Each EC2 instance has a lot of variables associated with it. Here is the list:
-#   http://docs.pythonboto.org/en/latest/ref/ec2.html#module-boto.ec2.instance
-# Below are 2 variables that are used as the address of a server:
-#   - destination_variable
-#   - vpc_destination_variable
-
-# This is the normal destination variable to use. If you are running Ansible
-# from outside EC2, then 'public_dns_name' makes the most sense. If you are
-# running Ansible from within EC2, then perhaps you want to use the internal
-# address, and should set this to 'private_dns_name'. The key of an EC2 tag
-# may optionally be used; however the boto instance variables hold precedence
-# in the event of a collision.
-destination_variable = public_dns_name
-
-# This allows you to override the inventory_name with an ec2 variable, instead
-# of using the destination_variable above. Addressing (aka ansible_ssh_host)
-# will still use destination_variable. Tags should be written as 'tag_TAGNAME'.
-#hostname_variable = tag_Name
-
-# For server inside a VPC, using DNS names may not make sense. When an instance
-# has 'subnet_id' set, this variable is used. If the subnet is public, setting
-# this to 'ip_address' will return the public IP address. For instances in a
-# private subnet, this should be set to 'private_ip_address', and Ansible must
-# be run from within EC2. The key of an EC2 tag may optionally be used; however
-# the boto instance variables hold precedence in the event of a collision.
-# WARNING: - instances that are in the private vpc, _without_ public ip address
-# will not be listed in the inventory until You set:
-# vpc_destination_variable = private_ip_address
-vpc_destination_variable = ip_address
-
-# The following two settings allow flexible ansible host naming based on a
-# python format string and a comma-separated list of ec2 tags.  Note that:
-#
-# 1) If the tags referenced are not present for some instances, empty strings
-#    will be substituted in the format string.
-# 2) This overrides both destination_variable and vpc_destination_variable.
-#
-#destination_format = {0}.{1}.example.com
-#destination_format_tags = Name,environment
-
-# To tag instances on EC2 with the resource records that point to them from
-# Route53, uncomment and set 'route53' to True.
-route53 = False
-
-# To exclude RDS instances from the inventory, uncomment and set to False.
-rds = False
-
-# To exclude ElastiCache instances from the inventory, uncomment and set to False.
-elasticache = False
-
-# Additionally, you can specify the list of zones to exclude looking up in
-# 'route53_excluded_zones' as a comma-separated list.
-# route53_excluded_zones = samplezone1.com, samplezone2.com
-
-# By default, only EC2 instances in the 'running' state are returned. Set
-# 'all_instances' to True to return all instances regardless of state.
-all_instances = True
-
-# By default, only EC2 instances in the 'running' state are returned. Specify
-# EC2 instance states to return as a comma-separated list. This
-# option is overriden when 'all_instances' is True.
-# instance_states = pending, running, shutting-down, terminated, stopping, stopped
-
-# By default, only RDS instances in the 'available' state are returned.  Set
-# 'all_rds_instances' to True return all RDS instances regardless of state.
-all_rds_instances = False
-
-# By default, only ElastiCache clusters and nodes in the 'available' state
-# are returned. Set 'all_elasticache_clusters' and/or 'all_elastic_nodes'
-# to True return all ElastiCache clusters and nodes, regardless of state.
-#
-# Note that all_elasticache_nodes only applies to listed clusters. That means
-# if you set all_elastic_clusters to false, no node will be return from
-# unavailable clusters, regardless of the state and to what you set for
-# all_elasticache_nodes.
-all_elasticache_replication_groups = False
-all_elasticache_clusters = False
-all_elasticache_nodes = False
-
-# API calls to EC2 are slow. For this reason, we cache the results of an API
-# call. Set this to the path you want cache files to be written to. Two files
-# will be written to this directory:
-#   - ansible-ec2.cache
-#   - ansible-ec2.index
-cache_path = ~/.ansible/tmp
-
-# The number of seconds a cache file is considered valid. After this many
-# seconds, a new API call will be made, and the cache file will be updated.
-# To disable the cache, set this value to 0
-cache_max_age = 300
-
-# Organize groups into a nested/hierarchy instead of a flat namespace.
-nested_groups = False
-
-# Replace - tags when creating groups to avoid issues with ansible
-replace_dash_in_groups = True
-
-# If set to true, any tag of the form "a,b,c" is expanded into a list
-# and the results are used to create additional tag_* inventory groups.
-expand_csv_tags = False
-
-# The EC2 inventory output can become very large. To manage its size,
-# configure which groups should be created.
-group_by_instance_id = True
-group_by_region = True
-group_by_availability_zone = True
-group_by_ami_id = True
-group_by_instance_type = True
-group_by_key_pair = True
-group_by_vpc_id = True
-group_by_security_group = True
-group_by_tag_keys = True
-group_by_tag_none = True
-group_by_route53_names = True
-group_by_rds_engine = False
-group_by_rds_parameter_group = False
-group_by_elasticache_engine = True
-group_by_elasticache_cluster = True
-group_by_elasticache_parameter_group = True
-group_by_elasticache_replication_group = True
-
-# If you only want to include hosts that match a certain regular expression
-# pattern_include = staging-*
-
-# If you want to exclude any hosts that match a certain regular expression
-# pattern_exclude = staging-*
-# Ansible EC2 external inventory script settings
-#
-
-##[ec2]
-##
-### to talk to a private eucalyptus instance uncomment these lines
-### and edit edit eucalyptus_host to be the host name of your cloud controller
-###eucalyptus = True
-###eucalyptus_host = clc.cloud.domain.org
-##
-### AWS regions to make calls to. Set this to 'all' to make request to all regions
-##
-### in AWS and merge the results together. Alternatively, set this to a comma
-### separated list of regions. E.g. 'us-east-1,us-west-1,us-west-2'
-##regions = all
-##regions_exclude = us-gov-west-1,cn-north-1
-##
-### When generating inventory, Ansible needs to know how to address a server.
-### Each EC2 instance has a lot of variables associated with it. Here is the list:
-###   http://docs.pythonboto.org/en/latest/ref/ec2.html#module-boto.ec2.instance
-### Below are 2 variables that are used as the address of a server:
-###   - destination_variable
-###   - vpc_destination_variable
-##
-### This is the normal destination variable to use. If you are running Ansible
-### from outside EC2, then 'public_dns_name' makes the most sense. If you are
-### running Ansible from within EC2, then perhaps you want to use the internal
-### address, and should set this to 'private_dns_name'. The key of an EC2 tag
-##...skipping...
-### pattern_include = staging-*
-##
-### If you want to exclude any hosts that match a certain regular expression
-### pattern_exclude = staging-*
-
-# Instance filters can be used to control which instances are retrieved for
-# inventory. For the full list of possible filters, please read the EC2 API
-# docs: http://docs.aws.amazon.com/AWSEC2/latest/APIReference/ApiReference-query-DescribeInstances.html#query-DescribeInstances-filters
-# Filters are key/value pairs separated by '=', to list multiple filters use
-# a list separated by commas. See examples below.
-
-# Retrieve only instances with (key=value) env=staging tag
-# instance_filters = tag:env=staging
-
-# Retrieve only instances with role=webservers OR role=dbservers tag
-# instance_filters = tag:role=webservers,tag:role=dbservers
-
-# Retrieve only t1.micro instances OR instances with tag env=staging
-# instance_filters = instance-type=t1.micro,tag:env=staging
-
-# You can use wildcards in filter values also. Below will list instances which
-# tag Name value matches webservers1*
-# (ex. webservers15, webservers1a, webservers123 etc)
-# instance_filters = tag:Name=webservers1*
-
-# A boto configuration profile may be used to separate out credentials
-# see http://boto.readthedocs.org/en/latest/boto_config_tut.html
-# boto_profile = some-boto-profile-name
diff --git a/edge-1601-dc5-dc6/ec2.py b/edge-1601-dc5-dc6/ec2.py
deleted file mode 100755
index f30958a..0000000
--- a/edge-1601-dc5-dc6/ec2.py
+++ /dev/null
@@ -1,1385 +0,0 @@
-#!/usr/bin/env python
-
-'''
-EC2 external inventory script
-=================================
-
-Generates inventory that Ansible can understand by making API request to
-AWS EC2 using the Boto library.
-
-NOTE: This script assumes Ansible is being executed where the environment
-variables needed for Boto have already been set:
-    export AWS_ACCESS_KEY_ID='AK123'
-    export AWS_SECRET_ACCESS_KEY='abc123'
-
-This script also assumes there is an ec2.ini file alongside it.  To specify a
-different path to ec2.ini, define the EC2_INI_PATH environment variable:
-
-    export EC2_INI_PATH=/path/to/my_ec2.ini
-
-If you're using eucalyptus you need to set the above variables and
-you need to define:
-
-    export EC2_URL=http://hostname_of_your_cc:port/services/Eucalyptus
-
-If you're using boto profiles (requires boto>=2.24.0) you can choose a profile
-using the --boto-profile command line argument (e.g. ec2.py --boto-profile prod) or using
-the AWS_PROFILE variable:
-
-    AWS_PROFILE=prod ansible-playbook -i ec2.py myplaybook.yml
-
-For more details, see: http://docs.pythonboto.org/en/latest/boto_config_tut.html
-
-When run against a specific host, this script returns the following variables:
- - ec2_ami_launch_index
- - ec2_architecture
- - ec2_association
- - ec2_attachTime
- - ec2_attachment
- - ec2_attachmentId
- - ec2_client_token
- - ec2_deleteOnTermination
- - ec2_description
- - ec2_deviceIndex
- - ec2_dns_name
- - ec2_eventsSet
- - ec2_group_name
- - ec2_hypervisor
- - ec2_id
- - ec2_image_id
- - ec2_instanceState
- - ec2_instance_type
- - ec2_ipOwnerId
- - ec2_ip_address
- - ec2_item
- - ec2_kernel
- - ec2_key_name
- - ec2_launch_time
- - ec2_monitored
- - ec2_monitoring
- - ec2_networkInterfaceId
- - ec2_ownerId
- - ec2_persistent
- - ec2_placement
- - ec2_platform
- - ec2_previous_state
- - ec2_private_dns_name
- - ec2_private_ip_address
- - ec2_publicIp
- - ec2_public_dns_name
- - ec2_ramdisk
- - ec2_reason
- - ec2_region
- - ec2_requester_id
- - ec2_root_device_name
- - ec2_root_device_type
- - ec2_security_group_ids
- - ec2_security_group_names
- - ec2_shutdown_state
- - ec2_sourceDestCheck
- - ec2_spot_instance_request_id
- - ec2_state
- - ec2_state_code
- - ec2_state_reason
- - ec2_status
- - ec2_subnet_id
- - ec2_tenancy
- - ec2_virtualization_type
- - ec2_vpc_id
-
-These variables are pulled out of a boto.ec2.instance object. There is a lack of
-consistency with variable spellings (camelCase and underscores) since this
-just loops through all variables the object exposes. It is preferred to use the
-ones with underscores when multiple exist.
-
-In addition, if an instance has AWS Tags associated with it, each tag is a new
-variable named:
- - ec2_tag_[Key] = [Value]
-
-Security groups are comma-separated in 'ec2_security_group_ids' and
-'ec2_security_group_names'.
-'''
-
-# (c) 2012, Peter Sankauskas
-#
-# This file is part of Ansible,
-#
-# Ansible is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# Ansible is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with Ansible.  If not, see <http://www.gnu.org/licenses/>.
-
-######################################################################
-
-import sys
-import os
-import argparse
-import re
-from time import time
-import boto
-from boto import ec2
-from boto import rds
-from boto import elasticache
-from boto import route53
-import six
-
-from six.moves import configparser
-from collections import defaultdict
-
-try:
-    import json
-except ImportError:
-    import simplejson as json
-
-
-class Ec2Inventory(object):
-
-    def _empty_inventory(self):
-        return {"_meta" : {"hostvars" : {}}}
-
-    def __init__(self):
-        ''' Main execution path '''
-
-        # Inventory grouped by instance IDs, tags, security groups, regions,
-        # and availability zones
-        self.inventory = self._empty_inventory()
-
-        # Index of hostname (address) to instance ID
-        self.index = {}
-
-        # Boto profile to use (if any)
-        self.boto_profile = None
-
-        # Read settings and parse CLI arguments
-        self.parse_cli_args()
-        self.read_settings()
-
-        # Make sure that profile_name is not passed at all if not set
-        # as pre 2.24 boto will fall over otherwise
-        if self.boto_profile:
-            if not hasattr(boto.ec2.EC2Connection, 'profile_name'):
-                self.fail_with_error("boto version must be >= 2.24 to use profile")
-
-        # Cache
-        if self.args.refresh_cache:
-            self.do_api_calls_update_cache()
-        elif not self.is_cache_valid():
-            self.do_api_calls_update_cache()
-
-        # Data to print
-        if self.args.host:
-            data_to_print = self.get_host_info()
-
-        elif self.args.list:
-            # Display list of instances for inventory
-            if self.inventory == self._empty_inventory():
-                data_to_print = self.get_inventory_from_cache()
-            else:
-                data_to_print = self.json_format_dict(self.inventory, True)
-
-        print(data_to_print)
-
-
-    def is_cache_valid(self):
-        ''' Determines if the cache files have expired, or if it is still valid '''
-
-        if os.path.isfile(self.cache_path_cache):
-            mod_time = os.path.getmtime(self.cache_path_cache)
-            current_time = time()
-            if (mod_time + self.cache_max_age) > current_time:
-                if os.path.isfile(self.cache_path_index):
-                    return True
-
-        return False
-
-
-    def read_settings(self):
-        ''' Reads the settings from the ec2.ini file '''
-        if six.PY3:
-            config = configparser.ConfigParser()
-        else:
-            config = configparser.SafeConfigParser()
-        ec2_default_ini_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'ec2.ini')
-        ec2_ini_path = os.path.expanduser(os.path.expandvars(os.environ.get('EC2_INI_PATH', ec2_default_ini_path)))
-        config.read(ec2_ini_path)
-
-        # is eucalyptus?
-        self.eucalyptus_host = None
-        self.eucalyptus = False
-        if config.has_option('ec2', 'eucalyptus'):
-            self.eucalyptus = config.getboolean('ec2', 'eucalyptus')
-        if self.eucalyptus and config.has_option('ec2', 'eucalyptus_host'):
-            self.eucalyptus_host = config.get('ec2', 'eucalyptus_host')
-
-        # Regions
-        self.regions = []
-        configRegions = config.get('ec2', 'regions')
-        configRegions_exclude = config.get('ec2', 'regions_exclude')
-        if (configRegions == 'all'):
-            if self.eucalyptus_host:
-                self.regions.append(boto.connect_euca(host=self.eucalyptus_host).region.name)
-            else:
-                for regionInfo in ec2.regions():
-                    if regionInfo.name not in configRegions_exclude:
-                        self.regions.append(regionInfo.name)
-        else:
-            self.regions = configRegions.split(",")
-
-        # Destination addresses
-        self.destination_variable = config.get('ec2', 'destination_variable')
-        self.vpc_destination_variable = config.get('ec2', 'vpc_destination_variable')
-
-        if config.has_option('ec2', 'hostname_variable'):
-            self.hostname_variable = config.get('ec2', 'hostname_variable')
-        else:
-            self.hostname_variable = None
-
-        if config.has_option('ec2', 'destination_format') and \
-                config.has_option('ec2', 'destination_format_tags'):
-            self.destination_format = config.get('ec2', 'destination_format')
-            self.destination_format_tags = config.get('ec2', 'destination_format_tags').split(',')
-        else:
-            self.destination_format = None
-            self.destination_format_tags = None
-
-        # Route53
-        self.route53_enabled = config.getboolean('ec2', 'route53')
-        self.route53_excluded_zones = []
-        if config.has_option('ec2', 'route53_excluded_zones'):
-            self.route53_excluded_zones.extend(
-                    config.get('ec2', 'route53_excluded_zones', '').split(','))
-
-        # Include RDS instances?
-        self.rds_enabled = True
-        if config.has_option('ec2', 'rds'):
-            self.rds_enabled = config.getboolean('ec2', 'rds')
-
-        # Include ElastiCache instances?
-        self.elasticache_enabled = True
-        if config.has_option('ec2', 'elasticache'):
-            self.elasticache_enabled = config.getboolean('ec2', 'elasticache')
-
-        # Return all EC2 instances?
-        if config.has_option('ec2', 'all_instances'):
-            self.all_instances = config.getboolean('ec2', 'all_instances')
-        else:
-            self.all_instances = False
-
-        # Instance states to be gathered in inventory. Default is 'running'.
-        # Setting 'all_instances' to 'yes' overrides this option.
-        ec2_valid_instance_states = [
-            'pending',
-            'running',
-            'shutting-down',
-            'terminated',
-            'stopping',
-            'stopped'
-        ]
-        self.ec2_instance_states = []
-        if self.all_instances:
-            self.ec2_instance_states = ec2_valid_instance_states
-        elif config.has_option('ec2', 'instance_states'):
-            for instance_state in config.get('ec2', 'instance_states').split(','):
-                instance_state = instance_state.strip()
-                if instance_state not in ec2_valid_instance_states:
-                    continue
-                self.ec2_instance_states.append(instance_state)
-        else:
-            self.ec2_instance_states = ['running']
-
-        # Return all RDS instances? (if RDS is enabled)
-        if config.has_option('ec2', 'all_rds_instances') and self.rds_enabled:
-            self.all_rds_instances = config.getboolean('ec2', 'all_rds_instances')
-        else:
-            self.all_rds_instances = False
-
-        # Return all ElastiCache replication groups? (if ElastiCache is enabled)
-        if config.has_option('ec2', 'all_elasticache_replication_groups') and self.elasticache_enabled:
-            self.all_elasticache_replication_groups = config.getboolean('ec2', 'all_elasticache_replication_groups')
-        else:
-            self.all_elasticache_replication_groups = False
-
-        # Return all ElastiCache clusters? (if ElastiCache is enabled)
-        if config.has_option('ec2', 'all_elasticache_clusters') and self.elasticache_enabled:
-            self.all_elasticache_clusters = config.getboolean('ec2', 'all_elasticache_clusters')
-        else:
-            self.all_elasticache_clusters = False
-
-        # Return all ElastiCache nodes? (if ElastiCache is enabled)
-        if config.has_option('ec2', 'all_elasticache_nodes') and self.elasticache_enabled:
-            self.all_elasticache_nodes = config.getboolean('ec2', 'all_elasticache_nodes')
-        else:
-            self.all_elasticache_nodes = False
-
-        # boto configuration profile (prefer CLI argument)
-        self.boto_profile = self.args.boto_profile
-        if config.has_option('ec2', 'boto_profile') and not self.boto_profile:
-            self.boto_profile = config.get('ec2', 'boto_profile')
-
-        # Cache related
-        cache_dir = os.path.expanduser(config.get('ec2', 'cache_path'))
-        if self.boto_profile:
-            cache_dir = os.path.join(cache_dir, 'profile_' + self.boto_profile)
-        if not os.path.exists(cache_dir):
-            os.makedirs(cache_dir)
-
-        cache_name = 'ansible-ec2'
-        aws_profile = lambda: (self.boto_profile or
-                               os.environ.get('AWS_PROFILE') or
-                               os.environ.get('AWS_ACCESS_KEY_ID'))
-        if aws_profile():
-            cache_name = '%s-%s' % (cache_name, aws_profile())
-        self.cache_path_cache = cache_dir + "/%s.cache" % cache_name
-        self.cache_path_index = cache_dir + "/%s.index" % cache_name
-        self.cache_max_age = config.getint('ec2', 'cache_max_age')
-
-        if config.has_option('ec2', 'expand_csv_tags'):
-            self.expand_csv_tags = config.getboolean('ec2', 'expand_csv_tags')
-        else:
-            self.expand_csv_tags = False
-
-        # Configure nested groups instead of flat namespace.
-        if config.has_option('ec2', 'nested_groups'):
-            self.nested_groups = config.getboolean('ec2', 'nested_groups')
-        else:
-            self.nested_groups = False
-
-        # Replace dash or not in group names
-        if config.has_option('ec2', 'replace_dash_in_groups'):
-            self.replace_dash_in_groups = config.getboolean('ec2', 'replace_dash_in_groups')
-        else:
-            self.replace_dash_in_groups = True
-
-        # Configure which groups should be created.
-        group_by_options = [
-            'group_by_instance_id',
-            'group_by_region',
-            'group_by_availability_zone',
-            'group_by_ami_id',
-            'group_by_instance_type',
-            'group_by_key_pair',
-            'group_by_vpc_id',
-            'group_by_security_group',
-            'group_by_tag_keys',
-            'group_by_tag_none',
-            'group_by_route53_names',
-            'group_by_rds_engine',
-            'group_by_rds_parameter_group',
-            'group_by_elasticache_engine',
-            'group_by_elasticache_cluster',
-            'group_by_elasticache_parameter_group',
-            'group_by_elasticache_replication_group',
-        ]
-        for option in group_by_options:
-            if config.has_option('ec2', option):
-                setattr(self, option, config.getboolean('ec2', option))
-            else:
-                setattr(self, option, True)
-
-        # Do we need to just include hosts that match a pattern?
-        try:
-            pattern_include = config.get('ec2', 'pattern_include')
-            if pattern_include and len(pattern_include) > 0:
-                self.pattern_include = re.compile(pattern_include)
-            else:
-                self.pattern_include = None
-        except configparser.NoOptionError:
-            self.pattern_include = None
-
-        # Do we need to exclude hosts that match a pattern?
-        try:
-            pattern_exclude = config.get('ec2', 'pattern_exclude');
-            if pattern_exclude and len(pattern_exclude) > 0:
-                self.pattern_exclude = re.compile(pattern_exclude)
-            else:
-                self.pattern_exclude = None
-        except configparser.NoOptionError:
-            self.pattern_exclude = None
-
-        # Instance filters (see boto and EC2 API docs). Ignore invalid filters.
-        self.ec2_instance_filters = defaultdict(list)
-        if config.has_option('ec2', 'instance_filters'):
-
-            filters = [f for f in config.get('ec2', 'instance_filters').split(',') if f]
-
-            for instance_filter in filters:
-                instance_filter = instance_filter.strip()
-                if not instance_filter or '=' not in instance_filter:
-                    continue
-                filter_key, filter_value = [x.strip() for x in instance_filter.split('=', 1)]
-                if not filter_key:
-                    continue
-                self.ec2_instance_filters[filter_key].append(filter_value)
-
-    def parse_cli_args(self):
-        ''' Command line argument processing '''
-
-        parser = argparse.ArgumentParser(description='Produce an Ansible Inventory file based on EC2')
-        parser.add_argument('--list', action='store_true', default=True,
-                            help='List instances (default: True)')
-        parser.add_argument('--host', action='store',
-                            help='Get all the variables about a specific instance')
-        parser.add_argument('--refresh-cache', action='store_true', default=False,
-                            help='Force refresh of cache by making API requests to EC2 (default: False - use cache files)')
-        parser.add_argument('--profile', '--boto-profile', action='store', dest='boto_profile',
-                            help='Use boto profile for connections to EC2')
-        self.args = parser.parse_args()
-
-
-    def do_api_calls_update_cache(self):
-        ''' Do API calls to each region, and save data in cache files '''
-
-        if self.route53_enabled:
-            self.get_route53_records()
-
-        for region in self.regions:
-            self.get_instances_by_region(region)
-            if self.rds_enabled:
-                self.get_rds_instances_by_region(region)
-            if self.elasticache_enabled:
-                self.get_elasticache_clusters_by_region(region)
-                self.get_elasticache_replication_groups_by_region(region)
-
-        self.write_to_cache(self.inventory, self.cache_path_cache)
-        self.write_to_cache(self.index, self.cache_path_index)
-
-    def connect(self, region):
-        ''' create connection to api server'''
-        if self.eucalyptus:
-            conn = boto.connect_euca(host=self.eucalyptus_host)
-            conn.APIVersion = '2010-08-31'
-        else:
-            conn = self.connect_to_aws(ec2, region)
-        return conn
-
-    def boto_fix_security_token_in_profile(self, connect_args):
-        ''' monkey patch for boto issue boto/boto#2100 '''
-        profile = 'profile ' + self.boto_profile
-        if boto.config.has_option(profile, 'aws_security_token'):
-            connect_args['security_token'] = boto.config.get(profile, 'aws_security_token')
-        return connect_args
-
-    def connect_to_aws(self, module, region):
-        connect_args = {}
-
-        # only pass the profile name if it's set (as it is not supported by older boto versions)
-        if self.boto_profile:
-            connect_args['profile_name'] = self.boto_profile
-            self.boto_fix_security_token_in_profile(connect_args)
-
-        conn = module.connect_to_region(region, **connect_args)
-        # connect_to_region will fail "silently" by returning None if the region name is wrong or not supported
-        if conn is None:
-            self.fail_with_error("region name: %s likely not supported, or AWS is down.  connection to region failed." % region)
-        return conn
-
-    def get_instances_by_region(self, region):
-        ''' Makes an AWS EC2 API call to the list of instances in a particular
-        region '''
-
-        try:
-            conn = self.connect(region)
-            reservations = []
-            if self.ec2_instance_filters:
-                for filter_key, filter_values in self.ec2_instance_filters.items():
-                    reservations.extend(conn.get_all_instances(filters = { filter_key : filter_values }))
-            else:
-                reservations = conn.get_all_instances()
-
-            for reservation in reservations:
-                for instance in reservation.instances:
-                    self.add_instance(instance, region)
-
-        except boto.exception.BotoServerError as e:
-            if e.error_code == 'AuthFailure':
-                error = self.get_auth_error_message()
-            else:
-                backend = 'Eucalyptus' if self.eucalyptus else 'AWS'
-                error = "Error connecting to %s backend.\n%s" % (backend, e.message)
-            self.fail_with_error(error, 'getting EC2 instances')
-
-    def get_rds_instances_by_region(self, region):
-        ''' Makes an AWS API call to the list of RDS instances in a particular
-        region '''
-
-        try:
-            conn = self.connect_to_aws(rds, region)
-            if conn:
-                marker = None
-                while True:
-                    instances = conn.get_all_dbinstances(marker=marker)
-                    marker = instances.marker
-                    for instance in instances:
-                        self.add_rds_instance(instance, region)
-                    if not marker:
-                        break
-        except boto.exception.BotoServerError as e:
-            error = e.reason
-
-            if e.error_code == 'AuthFailure':
-                error = self.get_auth_error_message()
-            if not e.reason == "Forbidden":
-                error = "Looks like AWS RDS is down:\n%s" % e.message
-            self.fail_with_error(error, 'getting RDS instances')
-
-    def get_elasticache_clusters_by_region(self, region):
-        ''' Makes an AWS API call to the list of ElastiCache clusters (with
-        nodes' info) in a particular region.'''
-
-        # ElastiCache boto module doesn't provide a get_all_intances method,
-        # that's why we need to call describe directly (it would be called by
-        # the shorthand method anyway...)
-        try:
-            conn = self.connect_to_aws(elasticache, region)
-            if conn:
-                # show_cache_node_info = True
-                # because we also want nodes' information
-                response = conn.describe_cache_clusters(None, None, None, True)
-
-        except boto.exception.BotoServerError as e:
-            error = e.reason
-
-            if e.error_code == 'AuthFailure':
-                error = self.get_auth_error_message()
-            if not e.reason == "Forbidden":
-                error = "Looks like AWS ElastiCache is down:\n%s" % e.message
-            self.fail_with_error(error, 'getting ElastiCache clusters')
-
-        try:
-            # Boto also doesn't provide wrapper classes to CacheClusters or
-            # CacheNodes. Because of that wo can't make use of the get_list
-            # method in the AWSQueryConnection. Let's do the work manually
-            clusters = response['DescribeCacheClustersResponse']['DescribeCacheClustersResult']['CacheClusters']
-
-        except KeyError as e:
-            error = "ElastiCache query to AWS failed (unexpected format)."
-            self.fail_with_error(error, 'getting ElastiCache clusters')
-
-        for cluster in clusters:
-            self.add_elasticache_cluster(cluster, region)
-
-    def get_elasticache_replication_groups_by_region(self, region):
-        ''' Makes an AWS API call to the list of ElastiCache replication groups
-        in a particular region.'''
-
-        # ElastiCache boto module doesn't provide a get_all_intances method,
-        # that's why we need to call describe directly (it would be called by
-        # the shorthand method anyway...)
-        try:
-            conn = self.connect_to_aws(elasticache, region)
-            if conn:
-                response = conn.describe_replication_groups()
-
-        except boto.exception.BotoServerError as e:
-            error = e.reason
-
-            if e.error_code == 'AuthFailure':
-                error = self.get_auth_error_message()
-            if not e.reason == "Forbidden":
-                error = "Looks like AWS ElastiCache [Replication Groups] is down:\n%s" % e.message
-            self.fail_with_error(error, 'getting ElastiCache clusters')
-
-        try:
-            # Boto also doesn't provide wrapper classes to ReplicationGroups
-            # Because of that wo can't make use of the get_list method in the
-            # AWSQueryConnection. Let's do the work manually
-            replication_groups = response['DescribeReplicationGroupsResponse']['DescribeReplicationGroupsResult']['ReplicationGroups']
-
-        except KeyError as e:
-            error = "ElastiCache [Replication Groups] query to AWS failed (unexpected format)."
-            self.fail_with_error(error, 'getting ElastiCache clusters')
-
-        for replication_group in replication_groups:
-            self.add_elasticache_replication_group(replication_group, region)
-
-    def get_auth_error_message(self):
-        ''' create an informative error message if there is an issue authenticating'''
-        errors = ["Authentication error retrieving ec2 inventory."]
-        if None in [os.environ.get('AWS_ACCESS_KEY_ID'), os.environ.get('AWS_SECRET_ACCESS_KEY')]:
-            errors.append(' - No AWS_ACCESS_KEY_ID or AWS_SECRET_ACCESS_KEY environment vars found')
-        else:
-            errors.append(' - AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY environment vars found but may not be correct')
-
-        boto_paths = ['/etc/boto.cfg', '~/.boto', '~/.aws/credentials']
-        boto_config_found = list(p for p in boto_paths if os.path.isfile(os.path.expanduser(p)))
-        if len(boto_config_found) > 0:
-            errors.append(" - Boto configs found at '%s', but the credentials contained may not be correct" % ', '.join(boto_config_found))
-        else:
-            errors.append(" - No Boto config found at any expected location '%s'" % ', '.join(boto_paths))
-
-        return '\n'.join(errors)
-
-    def fail_with_error(self, err_msg, err_operation=None):
-        '''log an error to std err for ansible-playbook to consume and exit'''
-        if err_operation:
-            err_msg = 'ERROR: "{err_msg}", while: {err_operation}'.format(
-                    err_msg=err_msg, err_operation=err_operation)
-        sys.stderr.write(err_msg)
-        sys.exit(1)
-
-    def get_instance(self, region, instance_id):
-        conn = self.connect(region)
-
-        reservations = conn.get_all_instances([instance_id])
-        for reservation in reservations:
-            for instance in reservation.instances:
-                return instance
-
-    def add_instance(self, instance, region):
-        ''' Adds an instance to the inventory and index, as long as it is
-        addressable '''
-
-        # Only return instances with desired instance states
-        if instance.state not in self.ec2_instance_states:
-            return
-
-        # Select the best destination address
-        if self.destination_format and self.destination_format_tags:
-            dest = self.destination_format.format(*[ getattr(instance, 'tags').get(tag, '') for tag in self.destination_format_tags ])
-        elif instance.subnet_id:
-            dest = getattr(instance, self.vpc_destination_variable, None)
-            if dest is None:
-                dest = getattr(instance, 'tags').get(self.vpc_destination_variable, None)
-        else:
-            dest = getattr(instance, self.destination_variable, None)
-            if dest is None:
-                dest = getattr(instance, 'tags').get(self.destination_variable, None)
-
-        if not dest:
-            # Skip instances we cannot address (e.g. private VPC subnet)
-            return
-
-        # Set the inventory name
-        hostname = None
-        if self.hostname_variable:
-            if self.hostname_variable.startswith('tag_'):
-                hostname = instance.tags.get(self.hostname_variable[4:], None)
-            else:
-                hostname = getattr(instance, self.hostname_variable)
-
-        # If we can't get a nice hostname, use the destination address
-        if not hostname:
-            hostname = dest
-        else:
-            hostname = self.to_safe(hostname).lower()
-
-        # if we only want to include hosts that match a pattern, skip those that don't
-        if self.pattern_include and not self.pattern_include.match(hostname):
-            return
-
-        # if we need to exclude hosts that match a pattern, skip those
-        if self.pattern_exclude and self.pattern_exclude.match(hostname):
-            return
-
-        # Add to index
-        self.index[hostname] = [region, instance.id]
-
-        # Inventory: Group by instance ID (always a group of 1)
-        if self.group_by_instance_id:
-            self.inventory[instance.id] = [hostname]
-            if self.nested_groups:
-                self.push_group(self.inventory, 'instances', instance.id)
-
-        # Inventory: Group by region
-        if self.group_by_region:
-            self.push(self.inventory, region, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'regions', region)
-
-        # Inventory: Group by availability zone
-        if self.group_by_availability_zone:
-            self.push(self.inventory, instance.placement, hostname)
-            if self.nested_groups:
-                if self.group_by_region:
-                    self.push_group(self.inventory, region, instance.placement)
-                self.push_group(self.inventory, 'zones', instance.placement)
-
-        # Inventory: Group by Amazon Machine Image (AMI) ID
-        if self.group_by_ami_id:
-            ami_id = self.to_safe(instance.image_id)
-            self.push(self.inventory, ami_id, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'images', ami_id)
-
-        # Inventory: Group by instance type
-        if self.group_by_instance_type:
-            type_name = self.to_safe('type_' + instance.instance_type)
-            self.push(self.inventory, type_name, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'types', type_name)
-
-        # Inventory: Group by key pair
-        if self.group_by_key_pair and instance.key_name:
-            key_name = self.to_safe('key_' + instance.key_name)
-            self.push(self.inventory, key_name, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'keys', key_name)
-
-        # Inventory: Group by VPC
-        if self.group_by_vpc_id and instance.vpc_id:
-            vpc_id_name = self.to_safe('vpc_id_' + instance.vpc_id)
-            self.push(self.inventory, vpc_id_name, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'vpcs', vpc_id_name)
-
-        # Inventory: Group by security group
-        if self.group_by_security_group:
-            try:
-                for group in instance.groups:
-                    key = self.to_safe("security_group_" + group.name)
-                    self.push(self.inventory, key, hostname)
-                    if self.nested_groups:
-                        self.push_group(self.inventory, 'security_groups', key)
-            except AttributeError:
-                self.fail_with_error('\n'.join(['Package boto seems a bit older.',
-                                                'Please upgrade boto >= 2.3.0.']))
-
-        # Inventory: Group by tag keys
-        if self.group_by_tag_keys:
-            for k, v in instance.tags.items():
-                if self.expand_csv_tags and v and ',' in v:
-                    values = map(lambda x: x.strip(), v.split(','))
-                else:
-                    values = [v]
-
-                for v in values:
-                    if v:
-                        key = self.to_safe("tag_" + k + "=" + v)
-                    else:
-                        key = self.to_safe("tag_" + k)
-                    self.push(self.inventory, key, hostname)
-                    if self.nested_groups:
-                        self.push_group(self.inventory, 'tags', self.to_safe("tag_" + k))
-                        if v:
-                            self.push_group(self.inventory, self.to_safe("tag_" + k), key)
-
-        # Inventory: Group by Route53 domain names if enabled
-        if self.route53_enabled and self.group_by_route53_names:
-            route53_names = self.get_instance_route53_names(instance)
-            for name in route53_names:
-                self.push(self.inventory, name, hostname)
-                if self.nested_groups:
-                    self.push_group(self.inventory, 'route53', name)
-
-        # Global Tag: instances without tags
-        if self.group_by_tag_none and len(instance.tags) == 0:
-            self.push(self.inventory, 'tag_none', hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'tags', 'tag_none')
-
-        # Global Tag: tag all EC2 instances
-        self.push(self.inventory, 'ec2', hostname)
-
-        self.inventory["_meta"]["hostvars"][hostname] = self.get_host_info_dict_from_instance(instance)
-        self.inventory["_meta"]["hostvars"][hostname]['ansible_ssh_host'] = dest
-
-
-    def add_rds_instance(self, instance, region):
-        ''' Adds an RDS instance to the inventory and index, as long as it is
-        addressable '''
-
-        # Only want available instances unless all_rds_instances is True
-        if not self.all_rds_instances and instance.status != 'available':
-            return
-
-        # Select the best destination address
-        dest = instance.endpoint[0]
-
-        if not dest:
-            # Skip instances we cannot address (e.g. private VPC subnet)
-            return
-
-        # Set the inventory name
-        hostname = None
-        if self.hostname_variable:
-            if self.hostname_variable.startswith('tag_'):
-                hostname = instance.tags.get(self.hostname_variable[4:], None)
-            else:
-                hostname = getattr(instance, self.hostname_variable)
-
-        # If we can't get a nice hostname, use the destination address
-        if not hostname:
-            hostname = dest
-
-        hostname = self.to_safe(hostname).lower()
-
-        # Add to index
-        self.index[hostname] = [region, instance.id]
-
-        # Inventory: Group by instance ID (always a group of 1)
-        if self.group_by_instance_id:
-            self.inventory[instance.id] = [hostname]
-            if self.nested_groups:
-                self.push_group(self.inventory, 'instances', instance.id)
-
-        # Inventory: Group by region
-        if self.group_by_region:
-            self.push(self.inventory, region, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'regions', region)
-
-        # Inventory: Group by availability zone
-        if self.group_by_availability_zone:
-            self.push(self.inventory, instance.availability_zone, hostname)
-            if self.nested_groups:
-                if self.group_by_region:
-                    self.push_group(self.inventory, region, instance.availability_zone)
-                self.push_group(self.inventory, 'zones', instance.availability_zone)
-
-        # Inventory: Group by instance type
-        if self.group_by_instance_type:
-            type_name = self.to_safe('type_' + instance.instance_class)
-            self.push(self.inventory, type_name, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'types', type_name)
-
-        # Inventory: Group by VPC
-        if self.group_by_vpc_id and instance.subnet_group and instance.subnet_group.vpc_id:
-            vpc_id_name = self.to_safe('vpc_id_' + instance.subnet_group.vpc_id)
-            self.push(self.inventory, vpc_id_name, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'vpcs', vpc_id_name)
-
-        # Inventory: Group by security group
-        if self.group_by_security_group:
-            try:
-                if instance.security_group:
-                    key = self.to_safe("security_group_" + instance.security_group.name)
-                    self.push(self.inventory, key, hostname)
-                    if self.nested_groups:
-                        self.push_group(self.inventory, 'security_groups', key)
-
-            except AttributeError:
-                self.fail_with_error('\n'.join(['Package boto seems a bit older.',
-                                                'Please upgrade boto >= 2.3.0.']))
-
-
-        # Inventory: Group by engine
-        if self.group_by_rds_engine:
-            self.push(self.inventory, self.to_safe("rds_" + instance.engine), hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'rds_engines', self.to_safe("rds_" + instance.engine))
-
-        # Inventory: Group by parameter group
-        if self.group_by_rds_parameter_group:
-            self.push(self.inventory, self.to_safe("rds_parameter_group_" + instance.parameter_group.name), hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'rds_parameter_groups', self.to_safe("rds_parameter_group_" + instance.parameter_group.name))
-
-        # Global Tag: all RDS instances
-        self.push(self.inventory, 'rds', hostname)
-
-        self.inventory["_meta"]["hostvars"][hostname] = self.get_host_info_dict_from_instance(instance)
-        self.inventory["_meta"]["hostvars"][hostname]['ansible_ssh_host'] = dest
-
-    def add_elasticache_cluster(self, cluster, region):
-        ''' Adds an ElastiCache cluster to the inventory and index, as long as
-        it's nodes are addressable '''
-
-        # Only want available clusters unless all_elasticache_clusters is True
-        if not self.all_elasticache_clusters and cluster['CacheClusterStatus'] != 'available':
-            return
-
-        # Select the best destination address
-        if 'ConfigurationEndpoint' in cluster and cluster['ConfigurationEndpoint']:
-            # Memcached cluster
-            dest = cluster['ConfigurationEndpoint']['Address']
-            is_redis = False
-        else:
-            # Redis sigle node cluster
-            # Because all Redis clusters are single nodes, we'll merge the
-            # info from the cluster with info about the node
-            dest = cluster['CacheNodes'][0]['Endpoint']['Address']
-            is_redis = True
-
-        if not dest:
-            # Skip clusters we cannot address (e.g. private VPC subnet)
-            return
-
-        # Add to index
-        self.index[dest] = [region, cluster['CacheClusterId']]
-
-        # Inventory: Group by instance ID (always a group of 1)
-        if self.group_by_instance_id:
-            self.inventory[cluster['CacheClusterId']] = [dest]
-            if self.nested_groups:
-                self.push_group(self.inventory, 'instances', cluster['CacheClusterId'])
-
-        # Inventory: Group by region
-        if self.group_by_region and not is_redis:
-            self.push(self.inventory, region, dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'regions', region)
-
-        # Inventory: Group by availability zone
-        if self.group_by_availability_zone and not is_redis:
-            self.push(self.inventory, cluster['PreferredAvailabilityZone'], dest)
-            if self.nested_groups:
-                if self.group_by_region:
-                    self.push_group(self.inventory, region, cluster['PreferredAvailabilityZone'])
-                self.push_group(self.inventory, 'zones', cluster['PreferredAvailabilityZone'])
-
-        # Inventory: Group by node type
-        if self.group_by_instance_type and not is_redis:
-            type_name = self.to_safe('type_' + cluster['CacheNodeType'])
-            self.push(self.inventory, type_name, dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'types', type_name)
-
-        # Inventory: Group by VPC (information not available in the current
-        # AWS API version for ElastiCache)
-
-        # Inventory: Group by security group
-        if self.group_by_security_group and not is_redis:
-
-            # Check for the existence of the 'SecurityGroups' key and also if
-            # this key has some value. When the cluster is not placed in a SG
-            # the query can return None here and cause an error.
-            if 'SecurityGroups' in cluster and cluster['SecurityGroups'] is not None:
-                for security_group in cluster['SecurityGroups']:
-                    key = self.to_safe("security_group_" + security_group['SecurityGroupId'])
-                    self.push(self.inventory, key, dest)
-                    if self.nested_groups:
-                        self.push_group(self.inventory, 'security_groups', key)
-
-        # Inventory: Group by engine
-        if self.group_by_elasticache_engine and not is_redis:
-            self.push(self.inventory, self.to_safe("elasticache_" + cluster['Engine']), dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'elasticache_engines', self.to_safe(cluster['Engine']))
-
-        # Inventory: Group by parameter group
-        if self.group_by_elasticache_parameter_group:
-            self.push(self.inventory, self.to_safe("elasticache_parameter_group_" + cluster['CacheParameterGroup']['CacheParameterGroupName']), dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'elasticache_parameter_groups', self.to_safe(cluster['CacheParameterGroup']['CacheParameterGroupName']))
-
-        # Inventory: Group by replication group
-        if self.group_by_elasticache_replication_group and 'ReplicationGroupId' in cluster and cluster['ReplicationGroupId']:
-            self.push(self.inventory, self.to_safe("elasticache_replication_group_" + cluster['ReplicationGroupId']), dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'elasticache_replication_groups', self.to_safe(cluster['ReplicationGroupId']))
-
-        # Global Tag: all ElastiCache clusters
-        self.push(self.inventory, 'elasticache_clusters', cluster['CacheClusterId'])
-
-        host_info = self.get_host_info_dict_from_describe_dict(cluster)
-
-        self.inventory["_meta"]["hostvars"][dest] = host_info
-
-        # Add the nodes
-        for node in cluster['CacheNodes']:
-            self.add_elasticache_node(node, cluster, region)
-
-    def add_elasticache_node(self, node, cluster, region):
-        ''' Adds an ElastiCache node to the inventory and index, as long as
-        it is addressable '''
-
-        # Only want available nodes unless all_elasticache_nodes is True
-        if not self.all_elasticache_nodes and node['CacheNodeStatus'] != 'available':
-            return
-
-        # Select the best destination address
-        dest = node['Endpoint']['Address']
-
-        if not dest:
-            # Skip nodes we cannot address (e.g. private VPC subnet)
-            return
-
-        node_id = self.to_safe(cluster['CacheClusterId'] + '_' + node['CacheNodeId'])
-
-        # Add to index
-        self.index[dest] = [region, node_id]
-
-        # Inventory: Group by node ID (always a group of 1)
-        if self.group_by_instance_id:
-            self.inventory[node_id] = [dest]
-            if self.nested_groups:
-                self.push_group(self.inventory, 'instances', node_id)
-
-        # Inventory: Group by region
-        if self.group_by_region:
-            self.push(self.inventory, region, dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'regions', region)
-
-        # Inventory: Group by availability zone
-        if self.group_by_availability_zone:
-            self.push(self.inventory, cluster['PreferredAvailabilityZone'], dest)
-            if self.nested_groups:
-                if self.group_by_region:
-                    self.push_group(self.inventory, region, cluster['PreferredAvailabilityZone'])
-                self.push_group(self.inventory, 'zones', cluster['PreferredAvailabilityZone'])
-
-        # Inventory: Group by node type
-        if self.group_by_instance_type:
-            type_name = self.to_safe('type_' + cluster['CacheNodeType'])
-            self.push(self.inventory, type_name, dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'types', type_name)
-
-        # Inventory: Group by VPC (information not available in the current
-        # AWS API version for ElastiCache)
-
-        # Inventory: Group by security group
-        if self.group_by_security_group:
-
-            # Check for the existence of the 'SecurityGroups' key and also if
-            # this key has some value. When the cluster is not placed in a SG
-            # the query can return None here and cause an error.
-            if 'SecurityGroups' in cluster and cluster['SecurityGroups'] is not None:
-                for security_group in cluster['SecurityGroups']:
-                    key = self.to_safe("security_group_" + security_group['SecurityGroupId'])
-                    self.push(self.inventory, key, dest)
-                    if self.nested_groups:
-                        self.push_group(self.inventory, 'security_groups', key)
-
-        # Inventory: Group by engine
-        if self.group_by_elasticache_engine:
-            self.push(self.inventory, self.to_safe("elasticache_" + cluster['Engine']), dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'elasticache_engines', self.to_safe("elasticache_" + cluster['Engine']))
-
-        # Inventory: Group by parameter group (done at cluster level)
-
-        # Inventory: Group by replication group (done at cluster level)
-
-        # Inventory: Group by ElastiCache Cluster
-        if self.group_by_elasticache_cluster:
-            self.push(self.inventory, self.to_safe("elasticache_cluster_" + cluster['CacheClusterId']), dest)
-
-        # Global Tag: all ElastiCache nodes
-        self.push(self.inventory, 'elasticache_nodes', dest)
-
-        host_info = self.get_host_info_dict_from_describe_dict(node)
-
-        if dest in self.inventory["_meta"]["hostvars"]:
-            self.inventory["_meta"]["hostvars"][dest].update(host_info)
-        else:
-            self.inventory["_meta"]["hostvars"][dest] = host_info
-
-    def add_elasticache_replication_group(self, replication_group, region):
-        ''' Adds an ElastiCache replication group to the inventory and index '''
-
-        # Only want available clusters unless all_elasticache_replication_groups is True
-        if not self.all_elasticache_replication_groups and replication_group['Status'] != 'available':
-            return
-
-        # Select the best destination address (PrimaryEndpoint)
-        dest = replication_group['NodeGroups'][0]['PrimaryEndpoint']['Address']
-
-        if not dest:
-            # Skip clusters we cannot address (e.g. private VPC subnet)
-            return
-
-        # Add to index
-        self.index[dest] = [region, replication_group['ReplicationGroupId']]
-
-        # Inventory: Group by ID (always a group of 1)
-        if self.group_by_instance_id:
-            self.inventory[replication_group['ReplicationGroupId']] = [dest]
-            if self.nested_groups:
-                self.push_group(self.inventory, 'instances', replication_group['ReplicationGroupId'])
-
-        # Inventory: Group by region
-        if self.group_by_region:
-            self.push(self.inventory, region, dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'regions', region)
-
-        # Inventory: Group by availability zone (doesn't apply to replication groups)
-
-        # Inventory: Group by node type (doesn't apply to replication groups)
-
-        # Inventory: Group by VPC (information not available in the current
-        # AWS API version for replication groups
-
-        # Inventory: Group by security group (doesn't apply to replication groups)
-        # Check this value in cluster level
-
-        # Inventory: Group by engine (replication groups are always Redis)
-        if self.group_by_elasticache_engine:
-            self.push(self.inventory, 'elasticache_redis', dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'elasticache_engines', 'redis')
-
-        # Global Tag: all ElastiCache clusters
-        self.push(self.inventory, 'elasticache_replication_groups', replication_group['ReplicationGroupId'])
-
-        host_info = self.get_host_info_dict_from_describe_dict(replication_group)
-
-        self.inventory["_meta"]["hostvars"][dest] = host_info
-
-    def get_route53_records(self):
-        ''' Get and store the map of resource records to domain names that
-        point to them. '''
-
-        r53_conn = route53.Route53Connection()
-        all_zones = r53_conn.get_zones()
-
-        route53_zones = [ zone for zone in all_zones if zone.name[:-1]
-                          not in self.route53_excluded_zones ]
-
-        self.route53_records = {}
-
-        for zone in route53_zones:
-            rrsets = r53_conn.get_all_rrsets(zone.id)
-
-            for record_set in rrsets:
-                record_name = record_set.name
-
-                if record_name.endswith('.'):
-                    record_name = record_name[:-1]
-
-                for resource in record_set.resource_records:
-                    self.route53_records.setdefault(resource, set())
-                    self.route53_records[resource].add(record_name)
-
-
-    def get_instance_route53_names(self, instance):
-        ''' Check if an instance is referenced in the records we have from
-        Route53. If it is, return the list of domain names pointing to said
-        instance. If nothing points to it, return an empty list. '''
-
-        instance_attributes = [ 'public_dns_name', 'private_dns_name',
-                                'ip_address', 'private_ip_address' ]
-
-        name_list = set()
-
-        for attrib in instance_attributes:
-            try:
-                value = getattr(instance, attrib)
-            except AttributeError:
-                continue
-
-            if value in self.route53_records:
-                name_list.update(self.route53_records[value])
-
-        return list(name_list)
-
-    def get_host_info_dict_from_instance(self, instance):
-        instance_vars = {}
-        for key in vars(instance):
-            value = getattr(instance, key)
-            key = self.to_safe('ec2_' + key)
-
-            # Handle complex types
-            # state/previous_state changed to properties in boto in https://github.com/boto/boto/commit/a23c379837f698212252720d2af8dec0325c9518
-            if key == 'ec2__state':
-                instance_vars['ec2_state'] = instance.state or ''
-                instance_vars['ec2_state_code'] = instance.state_code
-            elif key == 'ec2__previous_state':
-                instance_vars['ec2_previous_state'] = instance.previous_state or ''
-                instance_vars['ec2_previous_state_code'] = instance.previous_state_code
-            elif type(value) in [int, bool]:
-                instance_vars[key] = value
-            elif isinstance(value, six.string_types):
-                instance_vars[key] = value.strip()
-            elif type(value) == type(None):
-                instance_vars[key] = ''
-            elif key == 'ec2_region':
-                instance_vars[key] = value.name
-            elif key == 'ec2__placement':
-                instance_vars['ec2_placement'] = value.zone
-            elif key == 'ec2_tags':
-                for k, v in value.items():
-                    if self.expand_csv_tags and ',' in v:
-                        v = map(lambda x: x.strip(), v.split(','))
-                    key = self.to_safe('ec2_tag_' + k)
-                    instance_vars[key] = v
-            elif key == 'ec2_groups':
-                group_ids = []
-                group_names = []
-                for group in value:
-                    group_ids.append(group.id)
-                    group_names.append(group.name)
-                instance_vars["ec2_security_group_ids"] = ','.join([str(i) for i in group_ids])
-                instance_vars["ec2_security_group_names"] = ','.join([str(i) for i in group_names])
-            else:
-                pass
-                # TODO Product codes if someone finds them useful
-                #print key
-                #print type(value)
-                #print value
-
-        return instance_vars
-
-    def get_host_info_dict_from_describe_dict(self, describe_dict):
-        ''' Parses the dictionary returned by the API call into a flat list
-            of parameters. This method should be used only when 'describe' is
-            used directly because Boto doesn't provide specific classes. '''
-
-        # I really don't agree with prefixing everything with 'ec2'
-        # because EC2, RDS and ElastiCache are different services.
-        # I'm just following the pattern used until now to not break any
-        # compatibility.
-
-        host_info = {}
-        for key in describe_dict:
-            value = describe_dict[key]
-            key = self.to_safe('ec2_' + self.uncammelize(key))
-
-            # Handle complex types
-
-            # Target: Memcached Cache Clusters
-            if key == 'ec2_configuration_endpoint' and value:
-                host_info['ec2_configuration_endpoint_address'] = value['Address']
-                host_info['ec2_configuration_endpoint_port'] = value['Port']
-
-            # Target: Cache Nodes and Redis Cache Clusters (single node)
-            if key == 'ec2_endpoint' and value:
-                host_info['ec2_endpoint_address'] = value['Address']
-                host_info['ec2_endpoint_port'] = value['Port']
-
-            # Target: Redis Replication Groups
-            if key == 'ec2_node_groups' and value:
-                host_info['ec2_endpoint_address'] = value[0]['PrimaryEndpoint']['Address']
-                host_info['ec2_endpoint_port'] = value[0]['PrimaryEndpoint']['Port']
-                replica_count = 0
-                for node in value[0]['NodeGroupMembers']:
-                    if node['CurrentRole'] == 'primary':
-                        host_info['ec2_primary_cluster_address'] = node['ReadEndpoint']['Address']
-                        host_info['ec2_primary_cluster_port'] = node['ReadEndpoint']['Port']
-                        host_info['ec2_primary_cluster_id'] = node['CacheClusterId']
-                    elif node['CurrentRole'] == 'replica':
-                        host_info['ec2_replica_cluster_address_'+ str(replica_count)] = node['ReadEndpoint']['Address']
-                        host_info['ec2_replica_cluster_port_'+ str(replica_count)] = node['ReadEndpoint']['Port']
-                        host_info['ec2_replica_cluster_id_'+ str(replica_count)] = node['CacheClusterId']
-                        replica_count += 1
-
-            # Target: Redis Replication Groups
-            if key == 'ec2_member_clusters' and value:
-                host_info['ec2_member_clusters'] = ','.join([str(i) for i in value])
-
-            # Target: All Cache Clusters
-            elif key == 'ec2_cache_parameter_group':
-                host_info["ec2_cache_node_ids_to_reboot"] = ','.join([str(i) for i in value['CacheNodeIdsToReboot']])
-                host_info['ec2_cache_parameter_group_name'] = value['CacheParameterGroupName']
-                host_info['ec2_cache_parameter_apply_status'] = value['ParameterApplyStatus']
-
-            # Target: Almost everything
-            elif key == 'ec2_security_groups':
-
-                # Skip if SecurityGroups is None
-                # (it is possible to have the key defined but no value in it).
-                if value is not None:
-                    sg_ids = []
-                    for sg in value:
-                        sg_ids.append(sg['SecurityGroupId'])
-                    host_info["ec2_security_group_ids"] = ','.join([str(i) for i in sg_ids])
-
-            # Target: Everything
-            # Preserve booleans and integers
-            elif type(value) in [int, bool]:
-                host_info[key] = value
-
-            # Target: Everything
-            # Sanitize string values
-            elif isinstance(value, six.string_types):
-                host_info[key] = value.strip()
-
-            # Target: Everything
-            # Replace None by an empty string
-            elif type(value) == type(None):
-                host_info[key] = ''
-
-            else:
-                # Remove non-processed complex types
-                pass
-
-        return host_info
-
-    def get_host_info(self):
-        ''' Get variables about a specific host '''
-
-        if len(self.index) == 0:
-            # Need to load index from cache
-            self.load_index_from_cache()
-
-        if not self.args.host in self.index:
-            # try updating the cache
-            self.do_api_calls_update_cache()
-            if not self.args.host in self.index:
-                # host might not exist anymore
-                return self.json_format_dict({}, True)
-
-        (region, instance_id) = self.index[self.args.host]
-
-        instance = self.get_instance(region, instance_id)
-        return self.json_format_dict(self.get_host_info_dict_from_instance(instance), True)
-
-    def push(self, my_dict, key, element):
-        ''' Push an element onto an array that may not have been defined in
-        the dict '''
-        group_info = my_dict.setdefault(key, [])
-        if isinstance(group_info, dict):
-            host_list = group_info.setdefault('hosts', [])
-            host_list.append(element)
-        else:
-            group_info.append(element)
-
-    def push_group(self, my_dict, key, element):
-        ''' Push a group as a child of another group. '''
-        parent_group = my_dict.setdefault(key, {})
-        if not isinstance(parent_group, dict):
-            parent_group = my_dict[key] = {'hosts': parent_group}
-        child_groups = parent_group.setdefault('children', [])
-        if element not in child_groups:
-            child_groups.append(element)
-
-    def get_inventory_from_cache(self):
-        ''' Reads the inventory from the cache file and returns it as a JSON
-        object '''
-
-        cache = open(self.cache_path_cache, 'r')
-        json_inventory = cache.read()
-        return json_inventory
-
-
-    def load_index_from_cache(self):
-        ''' Reads the index from the cache file sets self.index '''
-
-        cache = open(self.cache_path_index, 'r')
-        json_index = cache.read()
-        self.index = json.loads(json_index)
-
-
-    def write_to_cache(self, data, filename):
-        ''' Writes data in JSON format to a file '''
-
-        json_data = self.json_format_dict(data, True)
-        cache = open(filename, 'w')
-        cache.write(json_data)
-        cache.close()
-
-    def uncammelize(self, key):
-        temp = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', key)
-        return re.sub('([a-z0-9])([A-Z])', r'\1_\2', temp).lower()
-
-    def to_safe(self, word):
-        ''' Converts 'bad' characters in a string to underscores so they can be used as Ansible groups '''
-        regex = "[^A-Za-z0-9\_"
-        if not self.replace_dash_in_groups:
-            regex += "\-"
-        return re.sub(regex + "]", "_", word)
-
-    def json_format_dict(self, data, pretty=False):
-        ''' Converts a dict to a JSON object and dumps it as a formatted
-        string '''
-
-        if pretty:
-            return json.dumps(data, sort_keys=True, indent=2)
-        else:
-            return json.dumps(data)
-
-
-# Run the script
-Ec2Inventory()
diff --git a/edge-1601-dc5-dc6/inventory-dc5 b/edge-1601-dc5-dc6/inventory-dc5
deleted file mode 100644
index f706500..0000000
--- a/edge-1601-dc5-dc6/inventory-dc5
+++ /dev/null
@@ -1,137 +0,0 @@
-[tag_Name_dc5_n1]
-[tag_Name_dc5_n2]
-[tag_Name_dc5_n3]
-[tag_Name_dc5_n4]
-[tag_Name_dc5_n5]
-[tag_Name_dc5_n6]
-[tag_Name_dc5_n7]
-[tag_Name_dc5_n8]
-[tag_Name_dc5_n9]
-[tag_Name_dc5_n10]
-[tag_Name_dc5_n11]
-[tag_Name_dc5_n12]
-[tag_Name_dc5_n13]
-[tag_Name_dc5_n14]
-[tag_Name_dc5_n15]
-[tag_Name_dc5_n16]
-[tag_Name_dc5_n17]
-[tag_Name_dc5_n18]
-[tag_Name_dc5_n19]
-[tag_Name_dc5_n20]
-[tag_Name_dc5_n21]
-
-[planet:children]
-dc-1
-
-[dc-1:children]
-tag_Name_dc5_n1
-tag_Name_dc5_n2
-tag_Name_dc5_n3
-tag_Name_dc5_n4
-tag_Name_dc5_n5
-tag_Name_dc5_n6
-tag_Name_dc5_n7
-tag_Name_dc5_n8
-tag_Name_dc5_n9
-tag_Name_dc5_n10
-tag_Name_dc5_n11
-tag_Name_dc5_n12
-tag_Name_dc5_n13
-tag_Name_dc5_n14
-tag_Name_dc5_n15
-tag_Name_dc5_n16
-tag_Name_dc5_n17
-tag_Name_dc5_n18
-tag_Name_dc5_n19
-tag_Name_dc5_n20
-tag_Name_dc5_n21
-
-[tag_Name_dc5_n5:vars]
-zk_observer=true
-
-[tag_Name_dc5_n6:vars]
-zk_observer=true
-
-[tag_Name_dc5_n7:vars]
-zk_observer=true
-
-[tag_Name_dc5_n8:vars]
-zk_observer=true
-
-[tag_Name_dc5_n9:vars]
-zk_observer=true
-
-[tag_Name_dc5_n10:vars]
-zk_observer=true
-
-[ds:children]
-dc-1-ds
-
-[dc-1-ds:children]
-tag_Name_dc5_n3
-tag_Name_dc5_n4
-tag_Name_dc5_n5
-tag_Name_dc5_n6
-tag_Name_dc5_n7
-tag_Name_dc5_n8
-tag_Name_dc5_n9
-tag_Name_dc5_n10
-
-[ms:children]
-dc-1-ms
-
-[dc-1-ms:children]
-tag_Name_dc5_n1
-tag_Name_dc5_n2
-
-[ui:children]
-dc-1-ui
-
-[dc-1-ui:children]
-tag_Name_dc5_n1
-tag_Name_dc5_n2
-
-[ldap:children]
-dc-1-ldap
-
-[dc-1-ldap:children]
-tag_Name_dc5_n1
-tag_Name_dc5_n2
-
-[rmp:children]
-dc-1-rmp
-
-[dc-1-rmp:children]
-tag_Name_dc5_n11
-tag_Name_dc5_n12
-tag_Name_dc5_n13
-tag_Name_dc5_n14
-tag_Name_dc5_n15
-tag_Name_dc5_n16
-tag_Name_dc5_n17
-
-[qpid:children]
-dc-1-qpid
-
-[dc-1-qpid:children]
-tag_Name_dc5_n18
-tag_Name_dc5_n19
-
-[pg:children]
-dc-1-pg
-
-[dc-1-pg:children]
-dc-1-pgmaster
-dc-1-pgstandby
-
-[pgmaster:children]
-dc-1-pgmaster
-
-[dc-1-pgmaster:children]
-tag_Name_dc5_n20
-
-[pgstandby:children]
-dc-1-pgstandby
-
-[dc-1-pgstandby:children]
-tag_Name_dc5_n21
diff --git a/edge-1601-dc5-dc6/inventory-dc6 b/edge-1601-dc5-dc6/inventory-dc6
deleted file mode 100644
index 0dbf6b1..0000000
--- a/edge-1601-dc5-dc6/inventory-dc6
+++ /dev/null
@@ -1,140 +0,0 @@
-[tag_Name_dc6_n1]
-[tag_Name_dc6_n2]
-[tag_Name_dc6_n3]
-[tag_Name_dc6_n4]
-[tag_Name_dc6_n5]
-[tag_Name_dc6_n6]
-[tag_Name_dc6_n7]
-[tag_Name_dc6_n8]
-[tag_Name_dc6_n9]
-[tag_Name_dc6_n10]
-[tag_Name_dc6_n11]
-[tag_Name_dc6_n12]
-[tag_Name_dc6_n13]
-[tag_Name_dc6_n14]
-[tag_Name_dc6_n15]
-[tag_Name_dc6_n16]
-[tag_Name_dc6_n17]
-[tag_Name_dc6_n18]
-[tag_Name_dc6_n19]
-[tag_Name_dc6_n20]
-[tag_Name_dc6_n21]
-
-[planet:children]
-dc-2
-
-[dc-2:children]
-tag_Name_dc6_n1
-tag_Name_dc6_n2
-tag_Name_dc6_n3
-tag_Name_dc6_n4
-tag_Name_dc6_n5
-tag_Name_dc6_n6
-tag_Name_dc6_n7
-tag_Name_dc6_n8
-tag_Name_dc6_n9
-tag_Name_dc6_n10
-tag_Name_dc6_n11
-tag_Name_dc6_n12
-tag_Name_dc6_n13
-tag_Name_dc6_n14
-tag_Name_dc6_n15
-tag_Name_dc6_n16
-tag_Name_dc6_n17
-tag_Name_dc6_n18
-tag_Name_dc6_n19
-tag_Name_dc6_n20
-tag_Name_dc6_n21
-
-[ds:children]
-dc-2-ds
-
-[tag_Name_dc6_n4:vars]
-zk_observer=true
-
-[tag_Name_dc6_n5:vars]
-zk_observer=true
-
-[tag_Name_dc6_n6:vars]
-zk_observer=true
-
-[tag_Name_dc6_n7:vars]
-zk_observer=true
-
-[tag_Name_dc6_n8:vars]
-zk_observer=true
-
-[tag_Name_dc6_n9:vars]
-zk_observer=true
-
-[tag_Name_dc6_n10:vars]
-zk_observer=true
-
-[dc-2-ds:children]
-tag_Name_dc6_n3
-tag_Name_dc6_n4
-tag_Name_dc6_n5
-tag_Name_dc6_n6
-tag_Name_dc6_n7
-tag_Name_dc6_n8
-tag_Name_dc6_n9
-tag_Name_dc6_n10
-
-[ms:children]
-dc-2-ms
-
-[dc-2-ms:children]
-tag_Name_dc6_n1
-tag_Name_dc6_n2
-
-[ui:children]
-dc-2-ui
-
-[dc-2-ui:children]
-tag_Name_dc6_n1
-tag_Name_dc6_n2
-
-[ldap:children]
-dc-2-ldap
-
-[dc-2-ldap:children]
-tag_Name_dc6_n1
-tag_Name_dc6_n2
-
-[rmp:children]
-dc-2-rmp
-
-[dc-2-rmp:children]
-tag_Name_dc6_n11
-tag_Name_dc6_n12
-tag_Name_dc6_n13
-tag_Name_dc6_n14
-tag_Name_dc6_n15
-tag_Name_dc6_n16
-tag_Name_dc6_n17
-
-[qpid:children]
-dc-2-qpid
-
-[dc-2-qpid:children]
-tag_Name_dc6_n18
-tag_Name_dc6_n19
-
-[pg:children]
-dc-2-pg
-
-[dc-2-pg:children]
-dc-2-pgmaster
-dc-2-pgstandby
-
-[pgmaster:children]
-dc-2-pgmaster
-
-[dc-2-pgmaster:children]
-tag_Name_dc6_n20
-
-[pgstandby:children]
-dc-2-pgstandby
-
-[dc-2-pgstandby:children]
-tag_Name_dc6_n21
diff --git a/edge-1601-dc5-dc6/inventory-haproxy b/edge-1601-dc5-dc6/inventory-haproxy
deleted file mode 100644
index 19c82a2..0000000
--- a/edge-1601-dc5-dc6/inventory-haproxy
+++ /dev/null
@@ -1,4 +0,0 @@
-[tag_Name_dc10_n1]
-
-[haproxy:children]
-tag_Name_dc10_n1
diff --git a/edge-1601-dc5/ec2.ini b/edge-1601-dc5/ec2.ini
deleted file mode 100644
index 36b3921..0000000
--- a/edge-1601-dc5/ec2.ini
+++ /dev/null
@@ -1,200 +0,0 @@
-# Ansible EC2 external inventory script settings
-#
-
-[ec2]
-
-# to talk to a private eucalyptus instance uncomment these lines
-# and edit edit eucalyptus_host to be the host name of your cloud controller
-#eucalyptus = True
-#eucalyptus_host = clc.cloud.domain.org
-
-# AWS regions to make calls to. Set this to 'all' to make request to all regions
-# in AWS and merge the results together. Alternatively, set this to a comma
-# separated list of regions. E.g. 'us-east-1,us-west-1,us-west-2'
-regions = all
-regions_exclude = us-gov-west-1,cn-north-1
-
-# When generating inventory, Ansible needs to know how to address a server.
-# Each EC2 instance has a lot of variables associated with it. Here is the list:
-#   http://docs.pythonboto.org/en/latest/ref/ec2.html#module-boto.ec2.instance
-# Below are 2 variables that are used as the address of a server:
-#   - destination_variable
-#   - vpc_destination_variable
-
-# This is the normal destination variable to use. If you are running Ansible
-# from outside EC2, then 'public_dns_name' makes the most sense. If you are
-# running Ansible from within EC2, then perhaps you want to use the internal
-# address, and should set this to 'private_dns_name'. The key of an EC2 tag
-# may optionally be used; however the boto instance variables hold precedence
-# in the event of a collision.
-destination_variable = public_dns_name
-
-# This allows you to override the inventory_name with an ec2 variable, instead
-# of using the destination_variable above. Addressing (aka ansible_ssh_host)
-# will still use destination_variable. Tags should be written as 'tag_TAGNAME'.
-#hostname_variable = tag_Name
-
-# For server inside a VPC, using DNS names may not make sense. When an instance
-# has 'subnet_id' set, this variable is used. If the subnet is public, setting
-# this to 'ip_address' will return the public IP address. For instances in a
-# private subnet, this should be set to 'private_ip_address', and Ansible must
-# be run from within EC2. The key of an EC2 tag may optionally be used; however
-# the boto instance variables hold precedence in the event of a collision.
-# WARNING: - instances that are in the private vpc, _without_ public ip address
-# will not be listed in the inventory until You set:
-# vpc_destination_variable = private_ip_address
-vpc_destination_variable = ip_address
-
-# The following two settings allow flexible ansible host naming based on a
-# python format string and a comma-separated list of ec2 tags.  Note that:
-#
-# 1) If the tags referenced are not present for some instances, empty strings
-#    will be substituted in the format string.
-# 2) This overrides both destination_variable and vpc_destination_variable.
-#
-#destination_format = {0}.{1}.example.com
-#destination_format_tags = Name,environment
-
-# To tag instances on EC2 with the resource records that point to them from
-# Route53, uncomment and set 'route53' to True.
-route53 = False
-
-# To exclude RDS instances from the inventory, uncomment and set to False.
-rds = False
-
-# To exclude ElastiCache instances from the inventory, uncomment and set to False.
-elasticache = False
-
-# Additionally, you can specify the list of zones to exclude looking up in
-# 'route53_excluded_zones' as a comma-separated list.
-# route53_excluded_zones = samplezone1.com, samplezone2.com
-
-# By default, only EC2 instances in the 'running' state are returned. Set
-# 'all_instances' to True to return all instances regardless of state.
-all_instances = True
-
-# By default, only EC2 instances in the 'running' state are returned. Specify
-# EC2 instance states to return as a comma-separated list. This
-# option is overriden when 'all_instances' is True.
-# instance_states = pending, running, shutting-down, terminated, stopping, stopped
-
-# By default, only RDS instances in the 'available' state are returned.  Set
-# 'all_rds_instances' to True return all RDS instances regardless of state.
-all_rds_instances = False
-
-# By default, only ElastiCache clusters and nodes in the 'available' state
-# are returned. Set 'all_elasticache_clusters' and/or 'all_elastic_nodes'
-# to True return all ElastiCache clusters and nodes, regardless of state.
-#
-# Note that all_elasticache_nodes only applies to listed clusters. That means
-# if you set all_elastic_clusters to false, no node will be return from
-# unavailable clusters, regardless of the state and to what you set for
-# all_elasticache_nodes.
-all_elasticache_replication_groups = False
-all_elasticache_clusters = False
-all_elasticache_nodes = False
-
-# API calls to EC2 are slow. For this reason, we cache the results of an API
-# call. Set this to the path you want cache files to be written to. Two files
-# will be written to this directory:
-#   - ansible-ec2.cache
-#   - ansible-ec2.index
-cache_path = ~/.ansible/tmp
-
-# The number of seconds a cache file is considered valid. After this many
-# seconds, a new API call will be made, and the cache file will be updated.
-# To disable the cache, set this value to 0
-cache_max_age = 300
-
-# Organize groups into a nested/hierarchy instead of a flat namespace.
-nested_groups = False
-
-# Replace - tags when creating groups to avoid issues with ansible
-replace_dash_in_groups = True
-
-# If set to true, any tag of the form "a,b,c" is expanded into a list
-# and the results are used to create additional tag_* inventory groups.
-expand_csv_tags = False
-
-# The EC2 inventory output can become very large. To manage its size,
-# configure which groups should be created.
-group_by_instance_id = True
-group_by_region = True
-group_by_availability_zone = True
-group_by_ami_id = True
-group_by_instance_type = True
-group_by_key_pair = True
-group_by_vpc_id = True
-group_by_security_group = True
-group_by_tag_keys = True
-group_by_tag_none = True
-group_by_route53_names = True
-group_by_rds_engine = False
-group_by_rds_parameter_group = False
-group_by_elasticache_engine = True
-group_by_elasticache_cluster = True
-group_by_elasticache_parameter_group = True
-group_by_elasticache_replication_group = True
-
-# If you only want to include hosts that match a certain regular expression
-# pattern_include = staging-*
-
-# If you want to exclude any hosts that match a certain regular expression
-# pattern_exclude = staging-*
-# Ansible EC2 external inventory script settings
-#
-
-##[ec2]
-##
-### to talk to a private eucalyptus instance uncomment these lines
-### and edit edit eucalyptus_host to be the host name of your cloud controller
-###eucalyptus = True
-###eucalyptus_host = clc.cloud.domain.org
-##
-### AWS regions to make calls to. Set this to 'all' to make request to all regions
-##
-### in AWS and merge the results together. Alternatively, set this to a comma
-### separated list of regions. E.g. 'us-east-1,us-west-1,us-west-2'
-##regions = all
-##regions_exclude = us-gov-west-1,cn-north-1
-##
-### When generating inventory, Ansible needs to know how to address a server.
-### Each EC2 instance has a lot of variables associated with it. Here is the list:
-###   http://docs.pythonboto.org/en/latest/ref/ec2.html#module-boto.ec2.instance
-### Below are 2 variables that are used as the address of a server:
-###   - destination_variable
-###   - vpc_destination_variable
-##
-### This is the normal destination variable to use. If you are running Ansible
-### from outside EC2, then 'public_dns_name' makes the most sense. If you are
-### running Ansible from within EC2, then perhaps you want to use the internal
-### address, and should set this to 'private_dns_name'. The key of an EC2 tag
-##...skipping...
-### pattern_include = staging-*
-##
-### If you want to exclude any hosts that match a certain regular expression
-### pattern_exclude = staging-*
-
-# Instance filters can be used to control which instances are retrieved for
-# inventory. For the full list of possible filters, please read the EC2 API
-# docs: http://docs.aws.amazon.com/AWSEC2/latest/APIReference/ApiReference-query-DescribeInstances.html#query-DescribeInstances-filters
-# Filters are key/value pairs separated by '=', to list multiple filters use
-# a list separated by commas. See examples below.
-
-# Retrieve only instances with (key=value) env=staging tag
-# instance_filters = tag:env=staging
-
-# Retrieve only instances with role=webservers OR role=dbservers tag
-# instance_filters = tag:role=webservers,tag:role=dbservers
-
-# Retrieve only t1.micro instances OR instances with tag env=staging
-# instance_filters = instance-type=t1.micro,tag:env=staging
-
-# You can use wildcards in filter values also. Below will list instances which
-# tag Name value matches webservers1*
-# (ex. webservers15, webservers1a, webservers123 etc)
-# instance_filters = tag:Name=webservers1*
-
-# A boto configuration profile may be used to separate out credentials
-# see http://boto.readthedocs.org/en/latest/boto_config_tut.html
-# boto_profile = some-boto-profile-name
diff --git a/edge-1601-dc5/ec2.py b/edge-1601-dc5/ec2.py
deleted file mode 100755
index f30958a..0000000
--- a/edge-1601-dc5/ec2.py
+++ /dev/null
@@ -1,1385 +0,0 @@
-#!/usr/bin/env python
-
-'''
-EC2 external inventory script
-=================================
-
-Generates inventory that Ansible can understand by making API request to
-AWS EC2 using the Boto library.
-
-NOTE: This script assumes Ansible is being executed where the environment
-variables needed for Boto have already been set:
-    export AWS_ACCESS_KEY_ID='AK123'
-    export AWS_SECRET_ACCESS_KEY='abc123'
-
-This script also assumes there is an ec2.ini file alongside it.  To specify a
-different path to ec2.ini, define the EC2_INI_PATH environment variable:
-
-    export EC2_INI_PATH=/path/to/my_ec2.ini
-
-If you're using eucalyptus you need to set the above variables and
-you need to define:
-
-    export EC2_URL=http://hostname_of_your_cc:port/services/Eucalyptus
-
-If you're using boto profiles (requires boto>=2.24.0) you can choose a profile
-using the --boto-profile command line argument (e.g. ec2.py --boto-profile prod) or using
-the AWS_PROFILE variable:
-
-    AWS_PROFILE=prod ansible-playbook -i ec2.py myplaybook.yml
-
-For more details, see: http://docs.pythonboto.org/en/latest/boto_config_tut.html
-
-When run against a specific host, this script returns the following variables:
- - ec2_ami_launch_index
- - ec2_architecture
- - ec2_association
- - ec2_attachTime
- - ec2_attachment
- - ec2_attachmentId
- - ec2_client_token
- - ec2_deleteOnTermination
- - ec2_description
- - ec2_deviceIndex
- - ec2_dns_name
- - ec2_eventsSet
- - ec2_group_name
- - ec2_hypervisor
- - ec2_id
- - ec2_image_id
- - ec2_instanceState
- - ec2_instance_type
- - ec2_ipOwnerId
- - ec2_ip_address
- - ec2_item
- - ec2_kernel
- - ec2_key_name
- - ec2_launch_time
- - ec2_monitored
- - ec2_monitoring
- - ec2_networkInterfaceId
- - ec2_ownerId
- - ec2_persistent
- - ec2_placement
- - ec2_platform
- - ec2_previous_state
- - ec2_private_dns_name
- - ec2_private_ip_address
- - ec2_publicIp
- - ec2_public_dns_name
- - ec2_ramdisk
- - ec2_reason
- - ec2_region
- - ec2_requester_id
- - ec2_root_device_name
- - ec2_root_device_type
- - ec2_security_group_ids
- - ec2_security_group_names
- - ec2_shutdown_state
- - ec2_sourceDestCheck
- - ec2_spot_instance_request_id
- - ec2_state
- - ec2_state_code
- - ec2_state_reason
- - ec2_status
- - ec2_subnet_id
- - ec2_tenancy
- - ec2_virtualization_type
- - ec2_vpc_id
-
-These variables are pulled out of a boto.ec2.instance object. There is a lack of
-consistency with variable spellings (camelCase and underscores) since this
-just loops through all variables the object exposes. It is preferred to use the
-ones with underscores when multiple exist.
-
-In addition, if an instance has AWS Tags associated with it, each tag is a new
-variable named:
- - ec2_tag_[Key] = [Value]
-
-Security groups are comma-separated in 'ec2_security_group_ids' and
-'ec2_security_group_names'.
-'''
-
-# (c) 2012, Peter Sankauskas
-#
-# This file is part of Ansible,
-#
-# Ansible is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# Ansible is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with Ansible.  If not, see <http://www.gnu.org/licenses/>.
-
-######################################################################
-
-import sys
-import os
-import argparse
-import re
-from time import time
-import boto
-from boto import ec2
-from boto import rds
-from boto import elasticache
-from boto import route53
-import six
-
-from six.moves import configparser
-from collections import defaultdict
-
-try:
-    import json
-except ImportError:
-    import simplejson as json
-
-
-class Ec2Inventory(object):
-
-    def _empty_inventory(self):
-        return {"_meta" : {"hostvars" : {}}}
-
-    def __init__(self):
-        ''' Main execution path '''
-
-        # Inventory grouped by instance IDs, tags, security groups, regions,
-        # and availability zones
-        self.inventory = self._empty_inventory()
-
-        # Index of hostname (address) to instance ID
-        self.index = {}
-
-        # Boto profile to use (if any)
-        self.boto_profile = None
-
-        # Read settings and parse CLI arguments
-        self.parse_cli_args()
-        self.read_settings()
-
-        # Make sure that profile_name is not passed at all if not set
-        # as pre 2.24 boto will fall over otherwise
-        if self.boto_profile:
-            if not hasattr(boto.ec2.EC2Connection, 'profile_name'):
-                self.fail_with_error("boto version must be >= 2.24 to use profile")
-
-        # Cache
-        if self.args.refresh_cache:
-            self.do_api_calls_update_cache()
-        elif not self.is_cache_valid():
-            self.do_api_calls_update_cache()
-
-        # Data to print
-        if self.args.host:
-            data_to_print = self.get_host_info()
-
-        elif self.args.list:
-            # Display list of instances for inventory
-            if self.inventory == self._empty_inventory():
-                data_to_print = self.get_inventory_from_cache()
-            else:
-                data_to_print = self.json_format_dict(self.inventory, True)
-
-        print(data_to_print)
-
-
-    def is_cache_valid(self):
-        ''' Determines if the cache files have expired, or if it is still valid '''
-
-        if os.path.isfile(self.cache_path_cache):
-            mod_time = os.path.getmtime(self.cache_path_cache)
-            current_time = time()
-            if (mod_time + self.cache_max_age) > current_time:
-                if os.path.isfile(self.cache_path_index):
-                    return True
-
-        return False
-
-
-    def read_settings(self):
-        ''' Reads the settings from the ec2.ini file '''
-        if six.PY3:
-            config = configparser.ConfigParser()
-        else:
-            config = configparser.SafeConfigParser()
-        ec2_default_ini_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'ec2.ini')
-        ec2_ini_path = os.path.expanduser(os.path.expandvars(os.environ.get('EC2_INI_PATH', ec2_default_ini_path)))
-        config.read(ec2_ini_path)
-
-        # is eucalyptus?
-        self.eucalyptus_host = None
-        self.eucalyptus = False
-        if config.has_option('ec2', 'eucalyptus'):
-            self.eucalyptus = config.getboolean('ec2', 'eucalyptus')
-        if self.eucalyptus and config.has_option('ec2', 'eucalyptus_host'):
-            self.eucalyptus_host = config.get('ec2', 'eucalyptus_host')
-
-        # Regions
-        self.regions = []
-        configRegions = config.get('ec2', 'regions')
-        configRegions_exclude = config.get('ec2', 'regions_exclude')
-        if (configRegions == 'all'):
-            if self.eucalyptus_host:
-                self.regions.append(boto.connect_euca(host=self.eucalyptus_host).region.name)
-            else:
-                for regionInfo in ec2.regions():
-                    if regionInfo.name not in configRegions_exclude:
-                        self.regions.append(regionInfo.name)
-        else:
-            self.regions = configRegions.split(",")
-
-        # Destination addresses
-        self.destination_variable = config.get('ec2', 'destination_variable')
-        self.vpc_destination_variable = config.get('ec2', 'vpc_destination_variable')
-
-        if config.has_option('ec2', 'hostname_variable'):
-            self.hostname_variable = config.get('ec2', 'hostname_variable')
-        else:
-            self.hostname_variable = None
-
-        if config.has_option('ec2', 'destination_format') and \
-                config.has_option('ec2', 'destination_format_tags'):
-            self.destination_format = config.get('ec2', 'destination_format')
-            self.destination_format_tags = config.get('ec2', 'destination_format_tags').split(',')
-        else:
-            self.destination_format = None
-            self.destination_format_tags = None
-
-        # Route53
-        self.route53_enabled = config.getboolean('ec2', 'route53')
-        self.route53_excluded_zones = []
-        if config.has_option('ec2', 'route53_excluded_zones'):
-            self.route53_excluded_zones.extend(
-                    config.get('ec2', 'route53_excluded_zones', '').split(','))
-
-        # Include RDS instances?
-        self.rds_enabled = True
-        if config.has_option('ec2', 'rds'):
-            self.rds_enabled = config.getboolean('ec2', 'rds')
-
-        # Include ElastiCache instances?
-        self.elasticache_enabled = True
-        if config.has_option('ec2', 'elasticache'):
-            self.elasticache_enabled = config.getboolean('ec2', 'elasticache')
-
-        # Return all EC2 instances?
-        if config.has_option('ec2', 'all_instances'):
-            self.all_instances = config.getboolean('ec2', 'all_instances')
-        else:
-            self.all_instances = False
-
-        # Instance states to be gathered in inventory. Default is 'running'.
-        # Setting 'all_instances' to 'yes' overrides this option.
-        ec2_valid_instance_states = [
-            'pending',
-            'running',
-            'shutting-down',
-            'terminated',
-            'stopping',
-            'stopped'
-        ]
-        self.ec2_instance_states = []
-        if self.all_instances:
-            self.ec2_instance_states = ec2_valid_instance_states
-        elif config.has_option('ec2', 'instance_states'):
-            for instance_state in config.get('ec2', 'instance_states').split(','):
-                instance_state = instance_state.strip()
-                if instance_state not in ec2_valid_instance_states:
-                    continue
-                self.ec2_instance_states.append(instance_state)
-        else:
-            self.ec2_instance_states = ['running']
-
-        # Return all RDS instances? (if RDS is enabled)
-        if config.has_option('ec2', 'all_rds_instances') and self.rds_enabled:
-            self.all_rds_instances = config.getboolean('ec2', 'all_rds_instances')
-        else:
-            self.all_rds_instances = False
-
-        # Return all ElastiCache replication groups? (if ElastiCache is enabled)
-        if config.has_option('ec2', 'all_elasticache_replication_groups') and self.elasticache_enabled:
-            self.all_elasticache_replication_groups = config.getboolean('ec2', 'all_elasticache_replication_groups')
-        else:
-            self.all_elasticache_replication_groups = False
-
-        # Return all ElastiCache clusters? (if ElastiCache is enabled)
-        if config.has_option('ec2', 'all_elasticache_clusters') and self.elasticache_enabled:
-            self.all_elasticache_clusters = config.getboolean('ec2', 'all_elasticache_clusters')
-        else:
-            self.all_elasticache_clusters = False
-
-        # Return all ElastiCache nodes? (if ElastiCache is enabled)
-        if config.has_option('ec2', 'all_elasticache_nodes') and self.elasticache_enabled:
-            self.all_elasticache_nodes = config.getboolean('ec2', 'all_elasticache_nodes')
-        else:
-            self.all_elasticache_nodes = False
-
-        # boto configuration profile (prefer CLI argument)
-        self.boto_profile = self.args.boto_profile
-        if config.has_option('ec2', 'boto_profile') and not self.boto_profile:
-            self.boto_profile = config.get('ec2', 'boto_profile')
-
-        # Cache related
-        cache_dir = os.path.expanduser(config.get('ec2', 'cache_path'))
-        if self.boto_profile:
-            cache_dir = os.path.join(cache_dir, 'profile_' + self.boto_profile)
-        if not os.path.exists(cache_dir):
-            os.makedirs(cache_dir)
-
-        cache_name = 'ansible-ec2'
-        aws_profile = lambda: (self.boto_profile or
-                               os.environ.get('AWS_PROFILE') or
-                               os.environ.get('AWS_ACCESS_KEY_ID'))
-        if aws_profile():
-            cache_name = '%s-%s' % (cache_name, aws_profile())
-        self.cache_path_cache = cache_dir + "/%s.cache" % cache_name
-        self.cache_path_index = cache_dir + "/%s.index" % cache_name
-        self.cache_max_age = config.getint('ec2', 'cache_max_age')
-
-        if config.has_option('ec2', 'expand_csv_tags'):
-            self.expand_csv_tags = config.getboolean('ec2', 'expand_csv_tags')
-        else:
-            self.expand_csv_tags = False
-
-        # Configure nested groups instead of flat namespace.
-        if config.has_option('ec2', 'nested_groups'):
-            self.nested_groups = config.getboolean('ec2', 'nested_groups')
-        else:
-            self.nested_groups = False
-
-        # Replace dash or not in group names
-        if config.has_option('ec2', 'replace_dash_in_groups'):
-            self.replace_dash_in_groups = config.getboolean('ec2', 'replace_dash_in_groups')
-        else:
-            self.replace_dash_in_groups = True
-
-        # Configure which groups should be created.
-        group_by_options = [
-            'group_by_instance_id',
-            'group_by_region',
-            'group_by_availability_zone',
-            'group_by_ami_id',
-            'group_by_instance_type',
-            'group_by_key_pair',
-            'group_by_vpc_id',
-            'group_by_security_group',
-            'group_by_tag_keys',
-            'group_by_tag_none',
-            'group_by_route53_names',
-            'group_by_rds_engine',
-            'group_by_rds_parameter_group',
-            'group_by_elasticache_engine',
-            'group_by_elasticache_cluster',
-            'group_by_elasticache_parameter_group',
-            'group_by_elasticache_replication_group',
-        ]
-        for option in group_by_options:
-            if config.has_option('ec2', option):
-                setattr(self, option, config.getboolean('ec2', option))
-            else:
-                setattr(self, option, True)
-
-        # Do we need to just include hosts that match a pattern?
-        try:
-            pattern_include = config.get('ec2', 'pattern_include')
-            if pattern_include and len(pattern_include) > 0:
-                self.pattern_include = re.compile(pattern_include)
-            else:
-                self.pattern_include = None
-        except configparser.NoOptionError:
-            self.pattern_include = None
-
-        # Do we need to exclude hosts that match a pattern?
-        try:
-            pattern_exclude = config.get('ec2', 'pattern_exclude');
-            if pattern_exclude and len(pattern_exclude) > 0:
-                self.pattern_exclude = re.compile(pattern_exclude)
-            else:
-                self.pattern_exclude = None
-        except configparser.NoOptionError:
-            self.pattern_exclude = None
-
-        # Instance filters (see boto and EC2 API docs). Ignore invalid filters.
-        self.ec2_instance_filters = defaultdict(list)
-        if config.has_option('ec2', 'instance_filters'):
-
-            filters = [f for f in config.get('ec2', 'instance_filters').split(',') if f]
-
-            for instance_filter in filters:
-                instance_filter = instance_filter.strip()
-                if not instance_filter or '=' not in instance_filter:
-                    continue
-                filter_key, filter_value = [x.strip() for x in instance_filter.split('=', 1)]
-                if not filter_key:
-                    continue
-                self.ec2_instance_filters[filter_key].append(filter_value)
-
-    def parse_cli_args(self):
-        ''' Command line argument processing '''
-
-        parser = argparse.ArgumentParser(description='Produce an Ansible Inventory file based on EC2')
-        parser.add_argument('--list', action='store_true', default=True,
-                            help='List instances (default: True)')
-        parser.add_argument('--host', action='store',
-                            help='Get all the variables about a specific instance')
-        parser.add_argument('--refresh-cache', action='store_true', default=False,
-                            help='Force refresh of cache by making API requests to EC2 (default: False - use cache files)')
-        parser.add_argument('--profile', '--boto-profile', action='store', dest='boto_profile',
-                            help='Use boto profile for connections to EC2')
-        self.args = parser.parse_args()
-
-
-    def do_api_calls_update_cache(self):
-        ''' Do API calls to each region, and save data in cache files '''
-
-        if self.route53_enabled:
-            self.get_route53_records()
-
-        for region in self.regions:
-            self.get_instances_by_region(region)
-            if self.rds_enabled:
-                self.get_rds_instances_by_region(region)
-            if self.elasticache_enabled:
-                self.get_elasticache_clusters_by_region(region)
-                self.get_elasticache_replication_groups_by_region(region)
-
-        self.write_to_cache(self.inventory, self.cache_path_cache)
-        self.write_to_cache(self.index, self.cache_path_index)
-
-    def connect(self, region):
-        ''' create connection to api server'''
-        if self.eucalyptus:
-            conn = boto.connect_euca(host=self.eucalyptus_host)
-            conn.APIVersion = '2010-08-31'
-        else:
-            conn = self.connect_to_aws(ec2, region)
-        return conn
-
-    def boto_fix_security_token_in_profile(self, connect_args):
-        ''' monkey patch for boto issue boto/boto#2100 '''
-        profile = 'profile ' + self.boto_profile
-        if boto.config.has_option(profile, 'aws_security_token'):
-            connect_args['security_token'] = boto.config.get(profile, 'aws_security_token')
-        return connect_args
-
-    def connect_to_aws(self, module, region):
-        connect_args = {}
-
-        # only pass the profile name if it's set (as it is not supported by older boto versions)
-        if self.boto_profile:
-            connect_args['profile_name'] = self.boto_profile
-            self.boto_fix_security_token_in_profile(connect_args)
-
-        conn = module.connect_to_region(region, **connect_args)
-        # connect_to_region will fail "silently" by returning None if the region name is wrong or not supported
-        if conn is None:
-            self.fail_with_error("region name: %s likely not supported, or AWS is down.  connection to region failed." % region)
-        return conn
-
-    def get_instances_by_region(self, region):
-        ''' Makes an AWS EC2 API call to the list of instances in a particular
-        region '''
-
-        try:
-            conn = self.connect(region)
-            reservations = []
-            if self.ec2_instance_filters:
-                for filter_key, filter_values in self.ec2_instance_filters.items():
-                    reservations.extend(conn.get_all_instances(filters = { filter_key : filter_values }))
-            else:
-                reservations = conn.get_all_instances()
-
-            for reservation in reservations:
-                for instance in reservation.instances:
-                    self.add_instance(instance, region)
-
-        except boto.exception.BotoServerError as e:
-            if e.error_code == 'AuthFailure':
-                error = self.get_auth_error_message()
-            else:
-                backend = 'Eucalyptus' if self.eucalyptus else 'AWS'
-                error = "Error connecting to %s backend.\n%s" % (backend, e.message)
-            self.fail_with_error(error, 'getting EC2 instances')
-
-    def get_rds_instances_by_region(self, region):
-        ''' Makes an AWS API call to the list of RDS instances in a particular
-        region '''
-
-        try:
-            conn = self.connect_to_aws(rds, region)
-            if conn:
-                marker = None
-                while True:
-                    instances = conn.get_all_dbinstances(marker=marker)
-                    marker = instances.marker
-                    for instance in instances:
-                        self.add_rds_instance(instance, region)
-                    if not marker:
-                        break
-        except boto.exception.BotoServerError as e:
-            error = e.reason
-
-            if e.error_code == 'AuthFailure':
-                error = self.get_auth_error_message()
-            if not e.reason == "Forbidden":
-                error = "Looks like AWS RDS is down:\n%s" % e.message
-            self.fail_with_error(error, 'getting RDS instances')
-
-    def get_elasticache_clusters_by_region(self, region):
-        ''' Makes an AWS API call to the list of ElastiCache clusters (with
-        nodes' info) in a particular region.'''
-
-        # ElastiCache boto module doesn't provide a get_all_intances method,
-        # that's why we need to call describe directly (it would be called by
-        # the shorthand method anyway...)
-        try:
-            conn = self.connect_to_aws(elasticache, region)
-            if conn:
-                # show_cache_node_info = True
-                # because we also want nodes' information
-                response = conn.describe_cache_clusters(None, None, None, True)
-
-        except boto.exception.BotoServerError as e:
-            error = e.reason
-
-            if e.error_code == 'AuthFailure':
-                error = self.get_auth_error_message()
-            if not e.reason == "Forbidden":
-                error = "Looks like AWS ElastiCache is down:\n%s" % e.message
-            self.fail_with_error(error, 'getting ElastiCache clusters')
-
-        try:
-            # Boto also doesn't provide wrapper classes to CacheClusters or
-            # CacheNodes. Because of that wo can't make use of the get_list
-            # method in the AWSQueryConnection. Let's do the work manually
-            clusters = response['DescribeCacheClustersResponse']['DescribeCacheClustersResult']['CacheClusters']
-
-        except KeyError as e:
-            error = "ElastiCache query to AWS failed (unexpected format)."
-            self.fail_with_error(error, 'getting ElastiCache clusters')
-
-        for cluster in clusters:
-            self.add_elasticache_cluster(cluster, region)
-
-    def get_elasticache_replication_groups_by_region(self, region):
-        ''' Makes an AWS API call to the list of ElastiCache replication groups
-        in a particular region.'''
-
-        # ElastiCache boto module doesn't provide a get_all_intances method,
-        # that's why we need to call describe directly (it would be called by
-        # the shorthand method anyway...)
-        try:
-            conn = self.connect_to_aws(elasticache, region)
-            if conn:
-                response = conn.describe_replication_groups()
-
-        except boto.exception.BotoServerError as e:
-            error = e.reason
-
-            if e.error_code == 'AuthFailure':
-                error = self.get_auth_error_message()
-            if not e.reason == "Forbidden":
-                error = "Looks like AWS ElastiCache [Replication Groups] is down:\n%s" % e.message
-            self.fail_with_error(error, 'getting ElastiCache clusters')
-
-        try:
-            # Boto also doesn't provide wrapper classes to ReplicationGroups
-            # Because of that wo can't make use of the get_list method in the
-            # AWSQueryConnection. Let's do the work manually
-            replication_groups = response['DescribeReplicationGroupsResponse']['DescribeReplicationGroupsResult']['ReplicationGroups']
-
-        except KeyError as e:
-            error = "ElastiCache [Replication Groups] query to AWS failed (unexpected format)."
-            self.fail_with_error(error, 'getting ElastiCache clusters')
-
-        for replication_group in replication_groups:
-            self.add_elasticache_replication_group(replication_group, region)
-
-    def get_auth_error_message(self):
-        ''' create an informative error message if there is an issue authenticating'''
-        errors = ["Authentication error retrieving ec2 inventory."]
-        if None in [os.environ.get('AWS_ACCESS_KEY_ID'), os.environ.get('AWS_SECRET_ACCESS_KEY')]:
-            errors.append(' - No AWS_ACCESS_KEY_ID or AWS_SECRET_ACCESS_KEY environment vars found')
-        else:
-            errors.append(' - AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY environment vars found but may not be correct')
-
-        boto_paths = ['/etc/boto.cfg', '~/.boto', '~/.aws/credentials']
-        boto_config_found = list(p for p in boto_paths if os.path.isfile(os.path.expanduser(p)))
-        if len(boto_config_found) > 0:
-            errors.append(" - Boto configs found at '%s', but the credentials contained may not be correct" % ', '.join(boto_config_found))
-        else:
-            errors.append(" - No Boto config found at any expected location '%s'" % ', '.join(boto_paths))
-
-        return '\n'.join(errors)
-
-    def fail_with_error(self, err_msg, err_operation=None):
-        '''log an error to std err for ansible-playbook to consume and exit'''
-        if err_operation:
-            err_msg = 'ERROR: "{err_msg}", while: {err_operation}'.format(
-                    err_msg=err_msg, err_operation=err_operation)
-        sys.stderr.write(err_msg)
-        sys.exit(1)
-
-    def get_instance(self, region, instance_id):
-        conn = self.connect(region)
-
-        reservations = conn.get_all_instances([instance_id])
-        for reservation in reservations:
-            for instance in reservation.instances:
-                return instance
-
-    def add_instance(self, instance, region):
-        ''' Adds an instance to the inventory and index, as long as it is
-        addressable '''
-
-        # Only return instances with desired instance states
-        if instance.state not in self.ec2_instance_states:
-            return
-
-        # Select the best destination address
-        if self.destination_format and self.destination_format_tags:
-            dest = self.destination_format.format(*[ getattr(instance, 'tags').get(tag, '') for tag in self.destination_format_tags ])
-        elif instance.subnet_id:
-            dest = getattr(instance, self.vpc_destination_variable, None)
-            if dest is None:
-                dest = getattr(instance, 'tags').get(self.vpc_destination_variable, None)
-        else:
-            dest = getattr(instance, self.destination_variable, None)
-            if dest is None:
-                dest = getattr(instance, 'tags').get(self.destination_variable, None)
-
-        if not dest:
-            # Skip instances we cannot address (e.g. private VPC subnet)
-            return
-
-        # Set the inventory name
-        hostname = None
-        if self.hostname_variable:
-            if self.hostname_variable.startswith('tag_'):
-                hostname = instance.tags.get(self.hostname_variable[4:], None)
-            else:
-                hostname = getattr(instance, self.hostname_variable)
-
-        # If we can't get a nice hostname, use the destination address
-        if not hostname:
-            hostname = dest
-        else:
-            hostname = self.to_safe(hostname).lower()
-
-        # if we only want to include hosts that match a pattern, skip those that don't
-        if self.pattern_include and not self.pattern_include.match(hostname):
-            return
-
-        # if we need to exclude hosts that match a pattern, skip those
-        if self.pattern_exclude and self.pattern_exclude.match(hostname):
-            return
-
-        # Add to index
-        self.index[hostname] = [region, instance.id]
-
-        # Inventory: Group by instance ID (always a group of 1)
-        if self.group_by_instance_id:
-            self.inventory[instance.id] = [hostname]
-            if self.nested_groups:
-                self.push_group(self.inventory, 'instances', instance.id)
-
-        # Inventory: Group by region
-        if self.group_by_region:
-            self.push(self.inventory, region, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'regions', region)
-
-        # Inventory: Group by availability zone
-        if self.group_by_availability_zone:
-            self.push(self.inventory, instance.placement, hostname)
-            if self.nested_groups:
-                if self.group_by_region:
-                    self.push_group(self.inventory, region, instance.placement)
-                self.push_group(self.inventory, 'zones', instance.placement)
-
-        # Inventory: Group by Amazon Machine Image (AMI) ID
-        if self.group_by_ami_id:
-            ami_id = self.to_safe(instance.image_id)
-            self.push(self.inventory, ami_id, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'images', ami_id)
-
-        # Inventory: Group by instance type
-        if self.group_by_instance_type:
-            type_name = self.to_safe('type_' + instance.instance_type)
-            self.push(self.inventory, type_name, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'types', type_name)
-
-        # Inventory: Group by key pair
-        if self.group_by_key_pair and instance.key_name:
-            key_name = self.to_safe('key_' + instance.key_name)
-            self.push(self.inventory, key_name, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'keys', key_name)
-
-        # Inventory: Group by VPC
-        if self.group_by_vpc_id and instance.vpc_id:
-            vpc_id_name = self.to_safe('vpc_id_' + instance.vpc_id)
-            self.push(self.inventory, vpc_id_name, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'vpcs', vpc_id_name)
-
-        # Inventory: Group by security group
-        if self.group_by_security_group:
-            try:
-                for group in instance.groups:
-                    key = self.to_safe("security_group_" + group.name)
-                    self.push(self.inventory, key, hostname)
-                    if self.nested_groups:
-                        self.push_group(self.inventory, 'security_groups', key)
-            except AttributeError:
-                self.fail_with_error('\n'.join(['Package boto seems a bit older.',
-                                                'Please upgrade boto >= 2.3.0.']))
-
-        # Inventory: Group by tag keys
-        if self.group_by_tag_keys:
-            for k, v in instance.tags.items():
-                if self.expand_csv_tags and v and ',' in v:
-                    values = map(lambda x: x.strip(), v.split(','))
-                else:
-                    values = [v]
-
-                for v in values:
-                    if v:
-                        key = self.to_safe("tag_" + k + "=" + v)
-                    else:
-                        key = self.to_safe("tag_" + k)
-                    self.push(self.inventory, key, hostname)
-                    if self.nested_groups:
-                        self.push_group(self.inventory, 'tags', self.to_safe("tag_" + k))
-                        if v:
-                            self.push_group(self.inventory, self.to_safe("tag_" + k), key)
-
-        # Inventory: Group by Route53 domain names if enabled
-        if self.route53_enabled and self.group_by_route53_names:
-            route53_names = self.get_instance_route53_names(instance)
-            for name in route53_names:
-                self.push(self.inventory, name, hostname)
-                if self.nested_groups:
-                    self.push_group(self.inventory, 'route53', name)
-
-        # Global Tag: instances without tags
-        if self.group_by_tag_none and len(instance.tags) == 0:
-            self.push(self.inventory, 'tag_none', hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'tags', 'tag_none')
-
-        # Global Tag: tag all EC2 instances
-        self.push(self.inventory, 'ec2', hostname)
-
-        self.inventory["_meta"]["hostvars"][hostname] = self.get_host_info_dict_from_instance(instance)
-        self.inventory["_meta"]["hostvars"][hostname]['ansible_ssh_host'] = dest
-
-
-    def add_rds_instance(self, instance, region):
-        ''' Adds an RDS instance to the inventory and index, as long as it is
-        addressable '''
-
-        # Only want available instances unless all_rds_instances is True
-        if not self.all_rds_instances and instance.status != 'available':
-            return
-
-        # Select the best destination address
-        dest = instance.endpoint[0]
-
-        if not dest:
-            # Skip instances we cannot address (e.g. private VPC subnet)
-            return
-
-        # Set the inventory name
-        hostname = None
-        if self.hostname_variable:
-            if self.hostname_variable.startswith('tag_'):
-                hostname = instance.tags.get(self.hostname_variable[4:], None)
-            else:
-                hostname = getattr(instance, self.hostname_variable)
-
-        # If we can't get a nice hostname, use the destination address
-        if not hostname:
-            hostname = dest
-
-        hostname = self.to_safe(hostname).lower()
-
-        # Add to index
-        self.index[hostname] = [region, instance.id]
-
-        # Inventory: Group by instance ID (always a group of 1)
-        if self.group_by_instance_id:
-            self.inventory[instance.id] = [hostname]
-            if self.nested_groups:
-                self.push_group(self.inventory, 'instances', instance.id)
-
-        # Inventory: Group by region
-        if self.group_by_region:
-            self.push(self.inventory, region, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'regions', region)
-
-        # Inventory: Group by availability zone
-        if self.group_by_availability_zone:
-            self.push(self.inventory, instance.availability_zone, hostname)
-            if self.nested_groups:
-                if self.group_by_region:
-                    self.push_group(self.inventory, region, instance.availability_zone)
-                self.push_group(self.inventory, 'zones', instance.availability_zone)
-
-        # Inventory: Group by instance type
-        if self.group_by_instance_type:
-            type_name = self.to_safe('type_' + instance.instance_class)
-            self.push(self.inventory, type_name, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'types', type_name)
-
-        # Inventory: Group by VPC
-        if self.group_by_vpc_id and instance.subnet_group and instance.subnet_group.vpc_id:
-            vpc_id_name = self.to_safe('vpc_id_' + instance.subnet_group.vpc_id)
-            self.push(self.inventory, vpc_id_name, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'vpcs', vpc_id_name)
-
-        # Inventory: Group by security group
-        if self.group_by_security_group:
-            try:
-                if instance.security_group:
-                    key = self.to_safe("security_group_" + instance.security_group.name)
-                    self.push(self.inventory, key, hostname)
-                    if self.nested_groups:
-                        self.push_group(self.inventory, 'security_groups', key)
-
-            except AttributeError:
-                self.fail_with_error('\n'.join(['Package boto seems a bit older.',
-                                                'Please upgrade boto >= 2.3.0.']))
-
-
-        # Inventory: Group by engine
-        if self.group_by_rds_engine:
-            self.push(self.inventory, self.to_safe("rds_" + instance.engine), hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'rds_engines', self.to_safe("rds_" + instance.engine))
-
-        # Inventory: Group by parameter group
-        if self.group_by_rds_parameter_group:
-            self.push(self.inventory, self.to_safe("rds_parameter_group_" + instance.parameter_group.name), hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'rds_parameter_groups', self.to_safe("rds_parameter_group_" + instance.parameter_group.name))
-
-        # Global Tag: all RDS instances
-        self.push(self.inventory, 'rds', hostname)
-
-        self.inventory["_meta"]["hostvars"][hostname] = self.get_host_info_dict_from_instance(instance)
-        self.inventory["_meta"]["hostvars"][hostname]['ansible_ssh_host'] = dest
-
-    def add_elasticache_cluster(self, cluster, region):
-        ''' Adds an ElastiCache cluster to the inventory and index, as long as
-        it's nodes are addressable '''
-
-        # Only want available clusters unless all_elasticache_clusters is True
-        if not self.all_elasticache_clusters and cluster['CacheClusterStatus'] != 'available':
-            return
-
-        # Select the best destination address
-        if 'ConfigurationEndpoint' in cluster and cluster['ConfigurationEndpoint']:
-            # Memcached cluster
-            dest = cluster['ConfigurationEndpoint']['Address']
-            is_redis = False
-        else:
-            # Redis sigle node cluster
-            # Because all Redis clusters are single nodes, we'll merge the
-            # info from the cluster with info about the node
-            dest = cluster['CacheNodes'][0]['Endpoint']['Address']
-            is_redis = True
-
-        if not dest:
-            # Skip clusters we cannot address (e.g. private VPC subnet)
-            return
-
-        # Add to index
-        self.index[dest] = [region, cluster['CacheClusterId']]
-
-        # Inventory: Group by instance ID (always a group of 1)
-        if self.group_by_instance_id:
-            self.inventory[cluster['CacheClusterId']] = [dest]
-            if self.nested_groups:
-                self.push_group(self.inventory, 'instances', cluster['CacheClusterId'])
-
-        # Inventory: Group by region
-        if self.group_by_region and not is_redis:
-            self.push(self.inventory, region, dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'regions', region)
-
-        # Inventory: Group by availability zone
-        if self.group_by_availability_zone and not is_redis:
-            self.push(self.inventory, cluster['PreferredAvailabilityZone'], dest)
-            if self.nested_groups:
-                if self.group_by_region:
-                    self.push_group(self.inventory, region, cluster['PreferredAvailabilityZone'])
-                self.push_group(self.inventory, 'zones', cluster['PreferredAvailabilityZone'])
-
-        # Inventory: Group by node type
-        if self.group_by_instance_type and not is_redis:
-            type_name = self.to_safe('type_' + cluster['CacheNodeType'])
-            self.push(self.inventory, type_name, dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'types', type_name)
-
-        # Inventory: Group by VPC (information not available in the current
-        # AWS API version for ElastiCache)
-
-        # Inventory: Group by security group
-        if self.group_by_security_group and not is_redis:
-
-            # Check for the existence of the 'SecurityGroups' key and also if
-            # this key has some value. When the cluster is not placed in a SG
-            # the query can return None here and cause an error.
-            if 'SecurityGroups' in cluster and cluster['SecurityGroups'] is not None:
-                for security_group in cluster['SecurityGroups']:
-                    key = self.to_safe("security_group_" + security_group['SecurityGroupId'])
-                    self.push(self.inventory, key, dest)
-                    if self.nested_groups:
-                        self.push_group(self.inventory, 'security_groups', key)
-
-        # Inventory: Group by engine
-        if self.group_by_elasticache_engine and not is_redis:
-            self.push(self.inventory, self.to_safe("elasticache_" + cluster['Engine']), dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'elasticache_engines', self.to_safe(cluster['Engine']))
-
-        # Inventory: Group by parameter group
-        if self.group_by_elasticache_parameter_group:
-            self.push(self.inventory, self.to_safe("elasticache_parameter_group_" + cluster['CacheParameterGroup']['CacheParameterGroupName']), dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'elasticache_parameter_groups', self.to_safe(cluster['CacheParameterGroup']['CacheParameterGroupName']))
-
-        # Inventory: Group by replication group
-        if self.group_by_elasticache_replication_group and 'ReplicationGroupId' in cluster and cluster['ReplicationGroupId']:
-            self.push(self.inventory, self.to_safe("elasticache_replication_group_" + cluster['ReplicationGroupId']), dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'elasticache_replication_groups', self.to_safe(cluster['ReplicationGroupId']))
-
-        # Global Tag: all ElastiCache clusters
-        self.push(self.inventory, 'elasticache_clusters', cluster['CacheClusterId'])
-
-        host_info = self.get_host_info_dict_from_describe_dict(cluster)
-
-        self.inventory["_meta"]["hostvars"][dest] = host_info
-
-        # Add the nodes
-        for node in cluster['CacheNodes']:
-            self.add_elasticache_node(node, cluster, region)
-
-    def add_elasticache_node(self, node, cluster, region):
-        ''' Adds an ElastiCache node to the inventory and index, as long as
-        it is addressable '''
-
-        # Only want available nodes unless all_elasticache_nodes is True
-        if not self.all_elasticache_nodes and node['CacheNodeStatus'] != 'available':
-            return
-
-        # Select the best destination address
-        dest = node['Endpoint']['Address']
-
-        if not dest:
-            # Skip nodes we cannot address (e.g. private VPC subnet)
-            return
-
-        node_id = self.to_safe(cluster['CacheClusterId'] + '_' + node['CacheNodeId'])
-
-        # Add to index
-        self.index[dest] = [region, node_id]
-
-        # Inventory: Group by node ID (always a group of 1)
-        if self.group_by_instance_id:
-            self.inventory[node_id] = [dest]
-            if self.nested_groups:
-                self.push_group(self.inventory, 'instances', node_id)
-
-        # Inventory: Group by region
-        if self.group_by_region:
-            self.push(self.inventory, region, dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'regions', region)
-
-        # Inventory: Group by availability zone
-        if self.group_by_availability_zone:
-            self.push(self.inventory, cluster['PreferredAvailabilityZone'], dest)
-            if self.nested_groups:
-                if self.group_by_region:
-                    self.push_group(self.inventory, region, cluster['PreferredAvailabilityZone'])
-                self.push_group(self.inventory, 'zones', cluster['PreferredAvailabilityZone'])
-
-        # Inventory: Group by node type
-        if self.group_by_instance_type:
-            type_name = self.to_safe('type_' + cluster['CacheNodeType'])
-            self.push(self.inventory, type_name, dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'types', type_name)
-
-        # Inventory: Group by VPC (information not available in the current
-        # AWS API version for ElastiCache)
-
-        # Inventory: Group by security group
-        if self.group_by_security_group:
-
-            # Check for the existence of the 'SecurityGroups' key and also if
-            # this key has some value. When the cluster is not placed in a SG
-            # the query can return None here and cause an error.
-            if 'SecurityGroups' in cluster and cluster['SecurityGroups'] is not None:
-                for security_group in cluster['SecurityGroups']:
-                    key = self.to_safe("security_group_" + security_group['SecurityGroupId'])
-                    self.push(self.inventory, key, dest)
-                    if self.nested_groups:
-                        self.push_group(self.inventory, 'security_groups', key)
-
-        # Inventory: Group by engine
-        if self.group_by_elasticache_engine:
-            self.push(self.inventory, self.to_safe("elasticache_" + cluster['Engine']), dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'elasticache_engines', self.to_safe("elasticache_" + cluster['Engine']))
-
-        # Inventory: Group by parameter group (done at cluster level)
-
-        # Inventory: Group by replication group (done at cluster level)
-
-        # Inventory: Group by ElastiCache Cluster
-        if self.group_by_elasticache_cluster:
-            self.push(self.inventory, self.to_safe("elasticache_cluster_" + cluster['CacheClusterId']), dest)
-
-        # Global Tag: all ElastiCache nodes
-        self.push(self.inventory, 'elasticache_nodes', dest)
-
-        host_info = self.get_host_info_dict_from_describe_dict(node)
-
-        if dest in self.inventory["_meta"]["hostvars"]:
-            self.inventory["_meta"]["hostvars"][dest].update(host_info)
-        else:
-            self.inventory["_meta"]["hostvars"][dest] = host_info
-
-    def add_elasticache_replication_group(self, replication_group, region):
-        ''' Adds an ElastiCache replication group to the inventory and index '''
-
-        # Only want available clusters unless all_elasticache_replication_groups is True
-        if not self.all_elasticache_replication_groups and replication_group['Status'] != 'available':
-            return
-
-        # Select the best destination address (PrimaryEndpoint)
-        dest = replication_group['NodeGroups'][0]['PrimaryEndpoint']['Address']
-
-        if not dest:
-            # Skip clusters we cannot address (e.g. private VPC subnet)
-            return
-
-        # Add to index
-        self.index[dest] = [region, replication_group['ReplicationGroupId']]
-
-        # Inventory: Group by ID (always a group of 1)
-        if self.group_by_instance_id:
-            self.inventory[replication_group['ReplicationGroupId']] = [dest]
-            if self.nested_groups:
-                self.push_group(self.inventory, 'instances', replication_group['ReplicationGroupId'])
-
-        # Inventory: Group by region
-        if self.group_by_region:
-            self.push(self.inventory, region, dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'regions', region)
-
-        # Inventory: Group by availability zone (doesn't apply to replication groups)
-
-        # Inventory: Group by node type (doesn't apply to replication groups)
-
-        # Inventory: Group by VPC (information not available in the current
-        # AWS API version for replication groups
-
-        # Inventory: Group by security group (doesn't apply to replication groups)
-        # Check this value in cluster level
-
-        # Inventory: Group by engine (replication groups are always Redis)
-        if self.group_by_elasticache_engine:
-            self.push(self.inventory, 'elasticache_redis', dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'elasticache_engines', 'redis')
-
-        # Global Tag: all ElastiCache clusters
-        self.push(self.inventory, 'elasticache_replication_groups', replication_group['ReplicationGroupId'])
-
-        host_info = self.get_host_info_dict_from_describe_dict(replication_group)
-
-        self.inventory["_meta"]["hostvars"][dest] = host_info
-
-    def get_route53_records(self):
-        ''' Get and store the map of resource records to domain names that
-        point to them. '''
-
-        r53_conn = route53.Route53Connection()
-        all_zones = r53_conn.get_zones()
-
-        route53_zones = [ zone for zone in all_zones if zone.name[:-1]
-                          not in self.route53_excluded_zones ]
-
-        self.route53_records = {}
-
-        for zone in route53_zones:
-            rrsets = r53_conn.get_all_rrsets(zone.id)
-
-            for record_set in rrsets:
-                record_name = record_set.name
-
-                if record_name.endswith('.'):
-                    record_name = record_name[:-1]
-
-                for resource in record_set.resource_records:
-                    self.route53_records.setdefault(resource, set())
-                    self.route53_records[resource].add(record_name)
-
-
-    def get_instance_route53_names(self, instance):
-        ''' Check if an instance is referenced in the records we have from
-        Route53. If it is, return the list of domain names pointing to said
-        instance. If nothing points to it, return an empty list. '''
-
-        instance_attributes = [ 'public_dns_name', 'private_dns_name',
-                                'ip_address', 'private_ip_address' ]
-
-        name_list = set()
-
-        for attrib in instance_attributes:
-            try:
-                value = getattr(instance, attrib)
-            except AttributeError:
-                continue
-
-            if value in self.route53_records:
-                name_list.update(self.route53_records[value])
-
-        return list(name_list)
-
-    def get_host_info_dict_from_instance(self, instance):
-        instance_vars = {}
-        for key in vars(instance):
-            value = getattr(instance, key)
-            key = self.to_safe('ec2_' + key)
-
-            # Handle complex types
-            # state/previous_state changed to properties in boto in https://github.com/boto/boto/commit/a23c379837f698212252720d2af8dec0325c9518
-            if key == 'ec2__state':
-                instance_vars['ec2_state'] = instance.state or ''
-                instance_vars['ec2_state_code'] = instance.state_code
-            elif key == 'ec2__previous_state':
-                instance_vars['ec2_previous_state'] = instance.previous_state or ''
-                instance_vars['ec2_previous_state_code'] = instance.previous_state_code
-            elif type(value) in [int, bool]:
-                instance_vars[key] = value
-            elif isinstance(value, six.string_types):
-                instance_vars[key] = value.strip()
-            elif type(value) == type(None):
-                instance_vars[key] = ''
-            elif key == 'ec2_region':
-                instance_vars[key] = value.name
-            elif key == 'ec2__placement':
-                instance_vars['ec2_placement'] = value.zone
-            elif key == 'ec2_tags':
-                for k, v in value.items():
-                    if self.expand_csv_tags and ',' in v:
-                        v = map(lambda x: x.strip(), v.split(','))
-                    key = self.to_safe('ec2_tag_' + k)
-                    instance_vars[key] = v
-            elif key == 'ec2_groups':
-                group_ids = []
-                group_names = []
-                for group in value:
-                    group_ids.append(group.id)
-                    group_names.append(group.name)
-                instance_vars["ec2_security_group_ids"] = ','.join([str(i) for i in group_ids])
-                instance_vars["ec2_security_group_names"] = ','.join([str(i) for i in group_names])
-            else:
-                pass
-                # TODO Product codes if someone finds them useful
-                #print key
-                #print type(value)
-                #print value
-
-        return instance_vars
-
-    def get_host_info_dict_from_describe_dict(self, describe_dict):
-        ''' Parses the dictionary returned by the API call into a flat list
-            of parameters. This method should be used only when 'describe' is
-            used directly because Boto doesn't provide specific classes. '''
-
-        # I really don't agree with prefixing everything with 'ec2'
-        # because EC2, RDS and ElastiCache are different services.
-        # I'm just following the pattern used until now to not break any
-        # compatibility.
-
-        host_info = {}
-        for key in describe_dict:
-            value = describe_dict[key]
-            key = self.to_safe('ec2_' + self.uncammelize(key))
-
-            # Handle complex types
-
-            # Target: Memcached Cache Clusters
-            if key == 'ec2_configuration_endpoint' and value:
-                host_info['ec2_configuration_endpoint_address'] = value['Address']
-                host_info['ec2_configuration_endpoint_port'] = value['Port']
-
-            # Target: Cache Nodes and Redis Cache Clusters (single node)
-            if key == 'ec2_endpoint' and value:
-                host_info['ec2_endpoint_address'] = value['Address']
-                host_info['ec2_endpoint_port'] = value['Port']
-
-            # Target: Redis Replication Groups
-            if key == 'ec2_node_groups' and value:
-                host_info['ec2_endpoint_address'] = value[0]['PrimaryEndpoint']['Address']
-                host_info['ec2_endpoint_port'] = value[0]['PrimaryEndpoint']['Port']
-                replica_count = 0
-                for node in value[0]['NodeGroupMembers']:
-                    if node['CurrentRole'] == 'primary':
-                        host_info['ec2_primary_cluster_address'] = node['ReadEndpoint']['Address']
-                        host_info['ec2_primary_cluster_port'] = node['ReadEndpoint']['Port']
-                        host_info['ec2_primary_cluster_id'] = node['CacheClusterId']
-                    elif node['CurrentRole'] == 'replica':
-                        host_info['ec2_replica_cluster_address_'+ str(replica_count)] = node['ReadEndpoint']['Address']
-                        host_info['ec2_replica_cluster_port_'+ str(replica_count)] = node['ReadEndpoint']['Port']
-                        host_info['ec2_replica_cluster_id_'+ str(replica_count)] = node['CacheClusterId']
-                        replica_count += 1
-
-            # Target: Redis Replication Groups
-            if key == 'ec2_member_clusters' and value:
-                host_info['ec2_member_clusters'] = ','.join([str(i) for i in value])
-
-            # Target: All Cache Clusters
-            elif key == 'ec2_cache_parameter_group':
-                host_info["ec2_cache_node_ids_to_reboot"] = ','.join([str(i) for i in value['CacheNodeIdsToReboot']])
-                host_info['ec2_cache_parameter_group_name'] = value['CacheParameterGroupName']
-                host_info['ec2_cache_parameter_apply_status'] = value['ParameterApplyStatus']
-
-            # Target: Almost everything
-            elif key == 'ec2_security_groups':
-
-                # Skip if SecurityGroups is None
-                # (it is possible to have the key defined but no value in it).
-                if value is not None:
-                    sg_ids = []
-                    for sg in value:
-                        sg_ids.append(sg['SecurityGroupId'])
-                    host_info["ec2_security_group_ids"] = ','.join([str(i) for i in sg_ids])
-
-            # Target: Everything
-            # Preserve booleans and integers
-            elif type(value) in [int, bool]:
-                host_info[key] = value
-
-            # Target: Everything
-            # Sanitize string values
-            elif isinstance(value, six.string_types):
-                host_info[key] = value.strip()
-
-            # Target: Everything
-            # Replace None by an empty string
-            elif type(value) == type(None):
-                host_info[key] = ''
-
-            else:
-                # Remove non-processed complex types
-                pass
-
-        return host_info
-
-    def get_host_info(self):
-        ''' Get variables about a specific host '''
-
-        if len(self.index) == 0:
-            # Need to load index from cache
-            self.load_index_from_cache()
-
-        if not self.args.host in self.index:
-            # try updating the cache
-            self.do_api_calls_update_cache()
-            if not self.args.host in self.index:
-                # host might not exist anymore
-                return self.json_format_dict({}, True)
-
-        (region, instance_id) = self.index[self.args.host]
-
-        instance = self.get_instance(region, instance_id)
-        return self.json_format_dict(self.get_host_info_dict_from_instance(instance), True)
-
-    def push(self, my_dict, key, element):
-        ''' Push an element onto an array that may not have been defined in
-        the dict '''
-        group_info = my_dict.setdefault(key, [])
-        if isinstance(group_info, dict):
-            host_list = group_info.setdefault('hosts', [])
-            host_list.append(element)
-        else:
-            group_info.append(element)
-
-    def push_group(self, my_dict, key, element):
-        ''' Push a group as a child of another group. '''
-        parent_group = my_dict.setdefault(key, {})
-        if not isinstance(parent_group, dict):
-            parent_group = my_dict[key] = {'hosts': parent_group}
-        child_groups = parent_group.setdefault('children', [])
-        if element not in child_groups:
-            child_groups.append(element)
-
-    def get_inventory_from_cache(self):
-        ''' Reads the inventory from the cache file and returns it as a JSON
-        object '''
-
-        cache = open(self.cache_path_cache, 'r')
-        json_inventory = cache.read()
-        return json_inventory
-
-
-    def load_index_from_cache(self):
-        ''' Reads the index from the cache file sets self.index '''
-
-        cache = open(self.cache_path_index, 'r')
-        json_index = cache.read()
-        self.index = json.loads(json_index)
-
-
-    def write_to_cache(self, data, filename):
-        ''' Writes data in JSON format to a file '''
-
-        json_data = self.json_format_dict(data, True)
-        cache = open(filename, 'w')
-        cache.write(json_data)
-        cache.close()
-
-    def uncammelize(self, key):
-        temp = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', key)
-        return re.sub('([a-z0-9])([A-Z])', r'\1_\2', temp).lower()
-
-    def to_safe(self, word):
-        ''' Converts 'bad' characters in a string to underscores so they can be used as Ansible groups '''
-        regex = "[^A-Za-z0-9\_"
-        if not self.replace_dash_in_groups:
-            regex += "\-"
-        return re.sub(regex + "]", "_", word)
-
-    def json_format_dict(self, data, pretty=False):
-        ''' Converts a dict to a JSON object and dumps it as a formatted
-        string '''
-
-        if pretty:
-            return json.dumps(data, sort_keys=True, indent=2)
-        else:
-            return json.dumps(data)
-
-
-# Run the script
-Ec2Inventory()
diff --git a/edge-1601-dc5/inventory b/edge-1601-dc5/inventory
deleted file mode 100644
index 4654714..0000000
--- a/edge-1601-dc5/inventory
+++ /dev/null
@@ -1,119 +0,0 @@
-[tag_Name_dc5_n1]
-[tag_Name_dc5_n2]
-[tag_Name_dc5_n3]
-[tag_Name_dc5_n4]
-[tag_Name_dc5_n5]
-[tag_Name_dc5_n6]
-[tag_Name_dc5_n7]
-[tag_Name_dc5_n8]
-[tag_Name_dc5_n9]
-[tag_Name_dc5_n10]
-[tag_Name_dc5_n11]
-[tag_Name_dc5_n12]
-[tag_Name_dc5_n13]
-[tag_Name_dc5_n14]
-[tag_Name_dc5_n15]
-[tag_Name_dc5_n16]
-[tag_Name_dc5_n17]
-[tag_Name_dc5_n18]
-[tag_Name_dc5_n19]
-[tag_Name_dc5_n20]
-[tag_Name_dc5_n21]
-
-[planet:children]
-dc-1
-
-[dc-1:children]
-tag_Name_dc5_n1
-tag_Name_dc5_n2
-tag_Name_dc5_n3
-tag_Name_dc5_n4
-tag_Name_dc5_n5
-tag_Name_dc5_n6
-tag_Name_dc5_n7
-tag_Name_dc5_n8
-tag_Name_dc5_n9
-tag_Name_dc5_n10
-tag_Name_dc5_n11
-tag_Name_dc5_n12
-tag_Name_dc5_n13
-tag_Name_dc5_n14
-tag_Name_dc5_n15
-tag_Name_dc5_n16
-tag_Name_dc5_n17
-tag_Name_dc5_n18
-tag_Name_dc5_n19
-tag_Name_dc5_n20
-tag_Name_dc5_n21
-
-[ds:children]
-dc-1-ds
-
-[dc-1-ds:children]
-tag_Name_dc5_n3
-tag_Name_dc5_n4
-tag_Name_dc5_n5
-tag_Name_dc5_n6
-tag_Name_dc5_n7
-tag_Name_dc5_n8
-tag_Name_dc5_n9
-tag_Name_dc5_n10
-
-[ms:children]
-dc-1-ms
-
-[dc-1-ms:children]
-tag_Name_dc5_n1
-tag_Name_dc5_n2
-
-[ui:children]
-dc-1-ui
-
-[dc-1-ui:children]
-tag_Name_dc5_n1
-tag_Name_dc5_n2
-
-[ldap:children]
-dc-1-ldap
-
-[dc-1-ldap:children]
-tag_Name_dc5_n1
-tag_Name_dc5_n2
-
-[rmp:children]
-dc-1-rmp
-
-[dc-1-rmp:children]
-tag_Name_dc5_n11
-tag_Name_dc5_n12
-tag_Name_dc5_n13
-tag_Name_dc5_n14
-tag_Name_dc5_n15
-tag_Name_dc5_n16
-tag_Name_dc5_n17
-
-[qpid:children]
-dc-1-qpid
-
-[dc-1-qpid:children]
-tag_Name_dc5_n18
-tag_Name_dc5_n19
-
-[pg:children]
-dc-1-pg
-
-[dc-1-pg:children]
-dc-1-pgmaster
-dc-1-pgstandby
-
-[pgmaster:children]
-dc-1-pgmaster
-
-[dc-1-pgmaster:children]
-tag_Name_dc5_n20
-
-[pgstandby:children]
-dc-1-pgstandby
-
-[dc-1-pgstandby:children]
-tag_Name_dc5_n21
diff --git a/edge-1601-dc6/ec2.ini b/edge-1601-dc6/ec2.ini
deleted file mode 100644
index 36b3921..0000000
--- a/edge-1601-dc6/ec2.ini
+++ /dev/null
@@ -1,200 +0,0 @@
-# Ansible EC2 external inventory script settings
-#
-
-[ec2]
-
-# to talk to a private eucalyptus instance uncomment these lines
-# and edit edit eucalyptus_host to be the host name of your cloud controller
-#eucalyptus = True
-#eucalyptus_host = clc.cloud.domain.org
-
-# AWS regions to make calls to. Set this to 'all' to make request to all regions
-# in AWS and merge the results together. Alternatively, set this to a comma
-# separated list of regions. E.g. 'us-east-1,us-west-1,us-west-2'
-regions = all
-regions_exclude = us-gov-west-1,cn-north-1
-
-# When generating inventory, Ansible needs to know how to address a server.
-# Each EC2 instance has a lot of variables associated with it. Here is the list:
-#   http://docs.pythonboto.org/en/latest/ref/ec2.html#module-boto.ec2.instance
-# Below are 2 variables that are used as the address of a server:
-#   - destination_variable
-#   - vpc_destination_variable
-
-# This is the normal destination variable to use. If you are running Ansible
-# from outside EC2, then 'public_dns_name' makes the most sense. If you are
-# running Ansible from within EC2, then perhaps you want to use the internal
-# address, and should set this to 'private_dns_name'. The key of an EC2 tag
-# may optionally be used; however the boto instance variables hold precedence
-# in the event of a collision.
-destination_variable = public_dns_name
-
-# This allows you to override the inventory_name with an ec2 variable, instead
-# of using the destination_variable above. Addressing (aka ansible_ssh_host)
-# will still use destination_variable. Tags should be written as 'tag_TAGNAME'.
-#hostname_variable = tag_Name
-
-# For server inside a VPC, using DNS names may not make sense. When an instance
-# has 'subnet_id' set, this variable is used. If the subnet is public, setting
-# this to 'ip_address' will return the public IP address. For instances in a
-# private subnet, this should be set to 'private_ip_address', and Ansible must
-# be run from within EC2. The key of an EC2 tag may optionally be used; however
-# the boto instance variables hold precedence in the event of a collision.
-# WARNING: - instances that are in the private vpc, _without_ public ip address
-# will not be listed in the inventory until You set:
-# vpc_destination_variable = private_ip_address
-vpc_destination_variable = ip_address
-
-# The following two settings allow flexible ansible host naming based on a
-# python format string and a comma-separated list of ec2 tags.  Note that:
-#
-# 1) If the tags referenced are not present for some instances, empty strings
-#    will be substituted in the format string.
-# 2) This overrides both destination_variable and vpc_destination_variable.
-#
-#destination_format = {0}.{1}.example.com
-#destination_format_tags = Name,environment
-
-# To tag instances on EC2 with the resource records that point to them from
-# Route53, uncomment and set 'route53' to True.
-route53 = False
-
-# To exclude RDS instances from the inventory, uncomment and set to False.
-rds = False
-
-# To exclude ElastiCache instances from the inventory, uncomment and set to False.
-elasticache = False
-
-# Additionally, you can specify the list of zones to exclude looking up in
-# 'route53_excluded_zones' as a comma-separated list.
-# route53_excluded_zones = samplezone1.com, samplezone2.com
-
-# By default, only EC2 instances in the 'running' state are returned. Set
-# 'all_instances' to True to return all instances regardless of state.
-all_instances = True
-
-# By default, only EC2 instances in the 'running' state are returned. Specify
-# EC2 instance states to return as a comma-separated list. This
-# option is overriden when 'all_instances' is True.
-# instance_states = pending, running, shutting-down, terminated, stopping, stopped
-
-# By default, only RDS instances in the 'available' state are returned.  Set
-# 'all_rds_instances' to True return all RDS instances regardless of state.
-all_rds_instances = False
-
-# By default, only ElastiCache clusters and nodes in the 'available' state
-# are returned. Set 'all_elasticache_clusters' and/or 'all_elastic_nodes'
-# to True return all ElastiCache clusters and nodes, regardless of state.
-#
-# Note that all_elasticache_nodes only applies to listed clusters. That means
-# if you set all_elastic_clusters to false, no node will be return from
-# unavailable clusters, regardless of the state and to what you set for
-# all_elasticache_nodes.
-all_elasticache_replication_groups = False
-all_elasticache_clusters = False
-all_elasticache_nodes = False
-
-# API calls to EC2 are slow. For this reason, we cache the results of an API
-# call. Set this to the path you want cache files to be written to. Two files
-# will be written to this directory:
-#   - ansible-ec2.cache
-#   - ansible-ec2.index
-cache_path = ~/.ansible/tmp
-
-# The number of seconds a cache file is considered valid. After this many
-# seconds, a new API call will be made, and the cache file will be updated.
-# To disable the cache, set this value to 0
-cache_max_age = 300
-
-# Organize groups into a nested/hierarchy instead of a flat namespace.
-nested_groups = False
-
-# Replace - tags when creating groups to avoid issues with ansible
-replace_dash_in_groups = True
-
-# If set to true, any tag of the form "a,b,c" is expanded into a list
-# and the results are used to create additional tag_* inventory groups.
-expand_csv_tags = False
-
-# The EC2 inventory output can become very large. To manage its size,
-# configure which groups should be created.
-group_by_instance_id = True
-group_by_region = True
-group_by_availability_zone = True
-group_by_ami_id = True
-group_by_instance_type = True
-group_by_key_pair = True
-group_by_vpc_id = True
-group_by_security_group = True
-group_by_tag_keys = True
-group_by_tag_none = True
-group_by_route53_names = True
-group_by_rds_engine = False
-group_by_rds_parameter_group = False
-group_by_elasticache_engine = True
-group_by_elasticache_cluster = True
-group_by_elasticache_parameter_group = True
-group_by_elasticache_replication_group = True
-
-# If you only want to include hosts that match a certain regular expression
-# pattern_include = staging-*
-
-# If you want to exclude any hosts that match a certain regular expression
-# pattern_exclude = staging-*
-# Ansible EC2 external inventory script settings
-#
-
-##[ec2]
-##
-### to talk to a private eucalyptus instance uncomment these lines
-### and edit edit eucalyptus_host to be the host name of your cloud controller
-###eucalyptus = True
-###eucalyptus_host = clc.cloud.domain.org
-##
-### AWS regions to make calls to. Set this to 'all' to make request to all regions
-##
-### in AWS and merge the results together. Alternatively, set this to a comma
-### separated list of regions. E.g. 'us-east-1,us-west-1,us-west-2'
-##regions = all
-##regions_exclude = us-gov-west-1,cn-north-1
-##
-### When generating inventory, Ansible needs to know how to address a server.
-### Each EC2 instance has a lot of variables associated with it. Here is the list:
-###   http://docs.pythonboto.org/en/latest/ref/ec2.html#module-boto.ec2.instance
-### Below are 2 variables that are used as the address of a server:
-###   - destination_variable
-###   - vpc_destination_variable
-##
-### This is the normal destination variable to use. If you are running Ansible
-### from outside EC2, then 'public_dns_name' makes the most sense. If you are
-### running Ansible from within EC2, then perhaps you want to use the internal
-### address, and should set this to 'private_dns_name'. The key of an EC2 tag
-##...skipping...
-### pattern_include = staging-*
-##
-### If you want to exclude any hosts that match a certain regular expression
-### pattern_exclude = staging-*
-
-# Instance filters can be used to control which instances are retrieved for
-# inventory. For the full list of possible filters, please read the EC2 API
-# docs: http://docs.aws.amazon.com/AWSEC2/latest/APIReference/ApiReference-query-DescribeInstances.html#query-DescribeInstances-filters
-# Filters are key/value pairs separated by '=', to list multiple filters use
-# a list separated by commas. See examples below.
-
-# Retrieve only instances with (key=value) env=staging tag
-# instance_filters = tag:env=staging
-
-# Retrieve only instances with role=webservers OR role=dbservers tag
-# instance_filters = tag:role=webservers,tag:role=dbservers
-
-# Retrieve only t1.micro instances OR instances with tag env=staging
-# instance_filters = instance-type=t1.micro,tag:env=staging
-
-# You can use wildcards in filter values also. Below will list instances which
-# tag Name value matches webservers1*
-# (ex. webservers15, webservers1a, webservers123 etc)
-# instance_filters = tag:Name=webservers1*
-
-# A boto configuration profile may be used to separate out credentials
-# see http://boto.readthedocs.org/en/latest/boto_config_tut.html
-# boto_profile = some-boto-profile-name
diff --git a/edge-1601-dc6/ec2.py b/edge-1601-dc6/ec2.py
deleted file mode 100755
index f30958a..0000000
--- a/edge-1601-dc6/ec2.py
+++ /dev/null
@@ -1,1385 +0,0 @@
-#!/usr/bin/env python
-
-'''
-EC2 external inventory script
-=================================
-
-Generates inventory that Ansible can understand by making API request to
-AWS EC2 using the Boto library.
-
-NOTE: This script assumes Ansible is being executed where the environment
-variables needed for Boto have already been set:
-    export AWS_ACCESS_KEY_ID='AK123'
-    export AWS_SECRET_ACCESS_KEY='abc123'
-
-This script also assumes there is an ec2.ini file alongside it.  To specify a
-different path to ec2.ini, define the EC2_INI_PATH environment variable:
-
-    export EC2_INI_PATH=/path/to/my_ec2.ini
-
-If you're using eucalyptus you need to set the above variables and
-you need to define:
-
-    export EC2_URL=http://hostname_of_your_cc:port/services/Eucalyptus
-
-If you're using boto profiles (requires boto>=2.24.0) you can choose a profile
-using the --boto-profile command line argument (e.g. ec2.py --boto-profile prod) or using
-the AWS_PROFILE variable:
-
-    AWS_PROFILE=prod ansible-playbook -i ec2.py myplaybook.yml
-
-For more details, see: http://docs.pythonboto.org/en/latest/boto_config_tut.html
-
-When run against a specific host, this script returns the following variables:
- - ec2_ami_launch_index
- - ec2_architecture
- - ec2_association
- - ec2_attachTime
- - ec2_attachment
- - ec2_attachmentId
- - ec2_client_token
- - ec2_deleteOnTermination
- - ec2_description
- - ec2_deviceIndex
- - ec2_dns_name
- - ec2_eventsSet
- - ec2_group_name
- - ec2_hypervisor
- - ec2_id
- - ec2_image_id
- - ec2_instanceState
- - ec2_instance_type
- - ec2_ipOwnerId
- - ec2_ip_address
- - ec2_item
- - ec2_kernel
- - ec2_key_name
- - ec2_launch_time
- - ec2_monitored
- - ec2_monitoring
- - ec2_networkInterfaceId
- - ec2_ownerId
- - ec2_persistent
- - ec2_placement
- - ec2_platform
- - ec2_previous_state
- - ec2_private_dns_name
- - ec2_private_ip_address
- - ec2_publicIp
- - ec2_public_dns_name
- - ec2_ramdisk
- - ec2_reason
- - ec2_region
- - ec2_requester_id
- - ec2_root_device_name
- - ec2_root_device_type
- - ec2_security_group_ids
- - ec2_security_group_names
- - ec2_shutdown_state
- - ec2_sourceDestCheck
- - ec2_spot_instance_request_id
- - ec2_state
- - ec2_state_code
- - ec2_state_reason
- - ec2_status
- - ec2_subnet_id
- - ec2_tenancy
- - ec2_virtualization_type
- - ec2_vpc_id
-
-These variables are pulled out of a boto.ec2.instance object. There is a lack of
-consistency with variable spellings (camelCase and underscores) since this
-just loops through all variables the object exposes. It is preferred to use the
-ones with underscores when multiple exist.
-
-In addition, if an instance has AWS Tags associated with it, each tag is a new
-variable named:
- - ec2_tag_[Key] = [Value]
-
-Security groups are comma-separated in 'ec2_security_group_ids' and
-'ec2_security_group_names'.
-'''
-
-# (c) 2012, Peter Sankauskas
-#
-# This file is part of Ansible,
-#
-# Ansible is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# Ansible is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with Ansible.  If not, see <http://www.gnu.org/licenses/>.
-
-######################################################################
-
-import sys
-import os
-import argparse
-import re
-from time import time
-import boto
-from boto import ec2
-from boto import rds
-from boto import elasticache
-from boto import route53
-import six
-
-from six.moves import configparser
-from collections import defaultdict
-
-try:
-    import json
-except ImportError:
-    import simplejson as json
-
-
-class Ec2Inventory(object):
-
-    def _empty_inventory(self):
-        return {"_meta" : {"hostvars" : {}}}
-
-    def __init__(self):
-        ''' Main execution path '''
-
-        # Inventory grouped by instance IDs, tags, security groups, regions,
-        # and availability zones
-        self.inventory = self._empty_inventory()
-
-        # Index of hostname (address) to instance ID
-        self.index = {}
-
-        # Boto profile to use (if any)
-        self.boto_profile = None
-
-        # Read settings and parse CLI arguments
-        self.parse_cli_args()
-        self.read_settings()
-
-        # Make sure that profile_name is not passed at all if not set
-        # as pre 2.24 boto will fall over otherwise
-        if self.boto_profile:
-            if not hasattr(boto.ec2.EC2Connection, 'profile_name'):
-                self.fail_with_error("boto version must be >= 2.24 to use profile")
-
-        # Cache
-        if self.args.refresh_cache:
-            self.do_api_calls_update_cache()
-        elif not self.is_cache_valid():
-            self.do_api_calls_update_cache()
-
-        # Data to print
-        if self.args.host:
-            data_to_print = self.get_host_info()
-
-        elif self.args.list:
-            # Display list of instances for inventory
-            if self.inventory == self._empty_inventory():
-                data_to_print = self.get_inventory_from_cache()
-            else:
-                data_to_print = self.json_format_dict(self.inventory, True)
-
-        print(data_to_print)
-
-
-    def is_cache_valid(self):
-        ''' Determines if the cache files have expired, or if it is still valid '''
-
-        if os.path.isfile(self.cache_path_cache):
-            mod_time = os.path.getmtime(self.cache_path_cache)
-            current_time = time()
-            if (mod_time + self.cache_max_age) > current_time:
-                if os.path.isfile(self.cache_path_index):
-                    return True
-
-        return False
-
-
-    def read_settings(self):
-        ''' Reads the settings from the ec2.ini file '''
-        if six.PY3:
-            config = configparser.ConfigParser()
-        else:
-            config = configparser.SafeConfigParser()
-        ec2_default_ini_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'ec2.ini')
-        ec2_ini_path = os.path.expanduser(os.path.expandvars(os.environ.get('EC2_INI_PATH', ec2_default_ini_path)))
-        config.read(ec2_ini_path)
-
-        # is eucalyptus?
-        self.eucalyptus_host = None
-        self.eucalyptus = False
-        if config.has_option('ec2', 'eucalyptus'):
-            self.eucalyptus = config.getboolean('ec2', 'eucalyptus')
-        if self.eucalyptus and config.has_option('ec2', 'eucalyptus_host'):
-            self.eucalyptus_host = config.get('ec2', 'eucalyptus_host')
-
-        # Regions
-        self.regions = []
-        configRegions = config.get('ec2', 'regions')
-        configRegions_exclude = config.get('ec2', 'regions_exclude')
-        if (configRegions == 'all'):
-            if self.eucalyptus_host:
-                self.regions.append(boto.connect_euca(host=self.eucalyptus_host).region.name)
-            else:
-                for regionInfo in ec2.regions():
-                    if regionInfo.name not in configRegions_exclude:
-                        self.regions.append(regionInfo.name)
-        else:
-            self.regions = configRegions.split(",")
-
-        # Destination addresses
-        self.destination_variable = config.get('ec2', 'destination_variable')
-        self.vpc_destination_variable = config.get('ec2', 'vpc_destination_variable')
-
-        if config.has_option('ec2', 'hostname_variable'):
-            self.hostname_variable = config.get('ec2', 'hostname_variable')
-        else:
-            self.hostname_variable = None
-
-        if config.has_option('ec2', 'destination_format') and \
-                config.has_option('ec2', 'destination_format_tags'):
-            self.destination_format = config.get('ec2', 'destination_format')
-            self.destination_format_tags = config.get('ec2', 'destination_format_tags').split(',')
-        else:
-            self.destination_format = None
-            self.destination_format_tags = None
-
-        # Route53
-        self.route53_enabled = config.getboolean('ec2', 'route53')
-        self.route53_excluded_zones = []
-        if config.has_option('ec2', 'route53_excluded_zones'):
-            self.route53_excluded_zones.extend(
-                    config.get('ec2', 'route53_excluded_zones', '').split(','))
-
-        # Include RDS instances?
-        self.rds_enabled = True
-        if config.has_option('ec2', 'rds'):
-            self.rds_enabled = config.getboolean('ec2', 'rds')
-
-        # Include ElastiCache instances?
-        self.elasticache_enabled = True
-        if config.has_option('ec2', 'elasticache'):
-            self.elasticache_enabled = config.getboolean('ec2', 'elasticache')
-
-        # Return all EC2 instances?
-        if config.has_option('ec2', 'all_instances'):
-            self.all_instances = config.getboolean('ec2', 'all_instances')
-        else:
-            self.all_instances = False
-
-        # Instance states to be gathered in inventory. Default is 'running'.
-        # Setting 'all_instances' to 'yes' overrides this option.
-        ec2_valid_instance_states = [
-            'pending',
-            'running',
-            'shutting-down',
-            'terminated',
-            'stopping',
-            'stopped'
-        ]
-        self.ec2_instance_states = []
-        if self.all_instances:
-            self.ec2_instance_states = ec2_valid_instance_states
-        elif config.has_option('ec2', 'instance_states'):
-            for instance_state in config.get('ec2', 'instance_states').split(','):
-                instance_state = instance_state.strip()
-                if instance_state not in ec2_valid_instance_states:
-                    continue
-                self.ec2_instance_states.append(instance_state)
-        else:
-            self.ec2_instance_states = ['running']
-
-        # Return all RDS instances? (if RDS is enabled)
-        if config.has_option('ec2', 'all_rds_instances') and self.rds_enabled:
-            self.all_rds_instances = config.getboolean('ec2', 'all_rds_instances')
-        else:
-            self.all_rds_instances = False
-
-        # Return all ElastiCache replication groups? (if ElastiCache is enabled)
-        if config.has_option('ec2', 'all_elasticache_replication_groups') and self.elasticache_enabled:
-            self.all_elasticache_replication_groups = config.getboolean('ec2', 'all_elasticache_replication_groups')
-        else:
-            self.all_elasticache_replication_groups = False
-
-        # Return all ElastiCache clusters? (if ElastiCache is enabled)
-        if config.has_option('ec2', 'all_elasticache_clusters') and self.elasticache_enabled:
-            self.all_elasticache_clusters = config.getboolean('ec2', 'all_elasticache_clusters')
-        else:
-            self.all_elasticache_clusters = False
-
-        # Return all ElastiCache nodes? (if ElastiCache is enabled)
-        if config.has_option('ec2', 'all_elasticache_nodes') and self.elasticache_enabled:
-            self.all_elasticache_nodes = config.getboolean('ec2', 'all_elasticache_nodes')
-        else:
-            self.all_elasticache_nodes = False
-
-        # boto configuration profile (prefer CLI argument)
-        self.boto_profile = self.args.boto_profile
-        if config.has_option('ec2', 'boto_profile') and not self.boto_profile:
-            self.boto_profile = config.get('ec2', 'boto_profile')
-
-        # Cache related
-        cache_dir = os.path.expanduser(config.get('ec2', 'cache_path'))
-        if self.boto_profile:
-            cache_dir = os.path.join(cache_dir, 'profile_' + self.boto_profile)
-        if not os.path.exists(cache_dir):
-            os.makedirs(cache_dir)
-
-        cache_name = 'ansible-ec2'
-        aws_profile = lambda: (self.boto_profile or
-                               os.environ.get('AWS_PROFILE') or
-                               os.environ.get('AWS_ACCESS_KEY_ID'))
-        if aws_profile():
-            cache_name = '%s-%s' % (cache_name, aws_profile())
-        self.cache_path_cache = cache_dir + "/%s.cache" % cache_name
-        self.cache_path_index = cache_dir + "/%s.index" % cache_name
-        self.cache_max_age = config.getint('ec2', 'cache_max_age')
-
-        if config.has_option('ec2', 'expand_csv_tags'):
-            self.expand_csv_tags = config.getboolean('ec2', 'expand_csv_tags')
-        else:
-            self.expand_csv_tags = False
-
-        # Configure nested groups instead of flat namespace.
-        if config.has_option('ec2', 'nested_groups'):
-            self.nested_groups = config.getboolean('ec2', 'nested_groups')
-        else:
-            self.nested_groups = False
-
-        # Replace dash or not in group names
-        if config.has_option('ec2', 'replace_dash_in_groups'):
-            self.replace_dash_in_groups = config.getboolean('ec2', 'replace_dash_in_groups')
-        else:
-            self.replace_dash_in_groups = True
-
-        # Configure which groups should be created.
-        group_by_options = [
-            'group_by_instance_id',
-            'group_by_region',
-            'group_by_availability_zone',
-            'group_by_ami_id',
-            'group_by_instance_type',
-            'group_by_key_pair',
-            'group_by_vpc_id',
-            'group_by_security_group',
-            'group_by_tag_keys',
-            'group_by_tag_none',
-            'group_by_route53_names',
-            'group_by_rds_engine',
-            'group_by_rds_parameter_group',
-            'group_by_elasticache_engine',
-            'group_by_elasticache_cluster',
-            'group_by_elasticache_parameter_group',
-            'group_by_elasticache_replication_group',
-        ]
-        for option in group_by_options:
-            if config.has_option('ec2', option):
-                setattr(self, option, config.getboolean('ec2', option))
-            else:
-                setattr(self, option, True)
-
-        # Do we need to just include hosts that match a pattern?
-        try:
-            pattern_include = config.get('ec2', 'pattern_include')
-            if pattern_include and len(pattern_include) > 0:
-                self.pattern_include = re.compile(pattern_include)
-            else:
-                self.pattern_include = None
-        except configparser.NoOptionError:
-            self.pattern_include = None
-
-        # Do we need to exclude hosts that match a pattern?
-        try:
-            pattern_exclude = config.get('ec2', 'pattern_exclude');
-            if pattern_exclude and len(pattern_exclude) > 0:
-                self.pattern_exclude = re.compile(pattern_exclude)
-            else:
-                self.pattern_exclude = None
-        except configparser.NoOptionError:
-            self.pattern_exclude = None
-
-        # Instance filters (see boto and EC2 API docs). Ignore invalid filters.
-        self.ec2_instance_filters = defaultdict(list)
-        if config.has_option('ec2', 'instance_filters'):
-
-            filters = [f for f in config.get('ec2', 'instance_filters').split(',') if f]
-
-            for instance_filter in filters:
-                instance_filter = instance_filter.strip()
-                if not instance_filter or '=' not in instance_filter:
-                    continue
-                filter_key, filter_value = [x.strip() for x in instance_filter.split('=', 1)]
-                if not filter_key:
-                    continue
-                self.ec2_instance_filters[filter_key].append(filter_value)
-
-    def parse_cli_args(self):
-        ''' Command line argument processing '''
-
-        parser = argparse.ArgumentParser(description='Produce an Ansible Inventory file based on EC2')
-        parser.add_argument('--list', action='store_true', default=True,
-                            help='List instances (default: True)')
-        parser.add_argument('--host', action='store',
-                            help='Get all the variables about a specific instance')
-        parser.add_argument('--refresh-cache', action='store_true', default=False,
-                            help='Force refresh of cache by making API requests to EC2 (default: False - use cache files)')
-        parser.add_argument('--profile', '--boto-profile', action='store', dest='boto_profile',
-                            help='Use boto profile for connections to EC2')
-        self.args = parser.parse_args()
-
-
-    def do_api_calls_update_cache(self):
-        ''' Do API calls to each region, and save data in cache files '''
-
-        if self.route53_enabled:
-            self.get_route53_records()
-
-        for region in self.regions:
-            self.get_instances_by_region(region)
-            if self.rds_enabled:
-                self.get_rds_instances_by_region(region)
-            if self.elasticache_enabled:
-                self.get_elasticache_clusters_by_region(region)
-                self.get_elasticache_replication_groups_by_region(region)
-
-        self.write_to_cache(self.inventory, self.cache_path_cache)
-        self.write_to_cache(self.index, self.cache_path_index)
-
-    def connect(self, region):
-        ''' create connection to api server'''
-        if self.eucalyptus:
-            conn = boto.connect_euca(host=self.eucalyptus_host)
-            conn.APIVersion = '2010-08-31'
-        else:
-            conn = self.connect_to_aws(ec2, region)
-        return conn
-
-    def boto_fix_security_token_in_profile(self, connect_args):
-        ''' monkey patch for boto issue boto/boto#2100 '''
-        profile = 'profile ' + self.boto_profile
-        if boto.config.has_option(profile, 'aws_security_token'):
-            connect_args['security_token'] = boto.config.get(profile, 'aws_security_token')
-        return connect_args
-
-    def connect_to_aws(self, module, region):
-        connect_args = {}
-
-        # only pass the profile name if it's set (as it is not supported by older boto versions)
-        if self.boto_profile:
-            connect_args['profile_name'] = self.boto_profile
-            self.boto_fix_security_token_in_profile(connect_args)
-
-        conn = module.connect_to_region(region, **connect_args)
-        # connect_to_region will fail "silently" by returning None if the region name is wrong or not supported
-        if conn is None:
-            self.fail_with_error("region name: %s likely not supported, or AWS is down.  connection to region failed." % region)
-        return conn
-
-    def get_instances_by_region(self, region):
-        ''' Makes an AWS EC2 API call to the list of instances in a particular
-        region '''
-
-        try:
-            conn = self.connect(region)
-            reservations = []
-            if self.ec2_instance_filters:
-                for filter_key, filter_values in self.ec2_instance_filters.items():
-                    reservations.extend(conn.get_all_instances(filters = { filter_key : filter_values }))
-            else:
-                reservations = conn.get_all_instances()
-
-            for reservation in reservations:
-                for instance in reservation.instances:
-                    self.add_instance(instance, region)
-
-        except boto.exception.BotoServerError as e:
-            if e.error_code == 'AuthFailure':
-                error = self.get_auth_error_message()
-            else:
-                backend = 'Eucalyptus' if self.eucalyptus else 'AWS'
-                error = "Error connecting to %s backend.\n%s" % (backend, e.message)
-            self.fail_with_error(error, 'getting EC2 instances')
-
-    def get_rds_instances_by_region(self, region):
-        ''' Makes an AWS API call to the list of RDS instances in a particular
-        region '''
-
-        try:
-            conn = self.connect_to_aws(rds, region)
-            if conn:
-                marker = None
-                while True:
-                    instances = conn.get_all_dbinstances(marker=marker)
-                    marker = instances.marker
-                    for instance in instances:
-                        self.add_rds_instance(instance, region)
-                    if not marker:
-                        break
-        except boto.exception.BotoServerError as e:
-            error = e.reason
-
-            if e.error_code == 'AuthFailure':
-                error = self.get_auth_error_message()
-            if not e.reason == "Forbidden":
-                error = "Looks like AWS RDS is down:\n%s" % e.message
-            self.fail_with_error(error, 'getting RDS instances')
-
-    def get_elasticache_clusters_by_region(self, region):
-        ''' Makes an AWS API call to the list of ElastiCache clusters (with
-        nodes' info) in a particular region.'''
-
-        # ElastiCache boto module doesn't provide a get_all_intances method,
-        # that's why we need to call describe directly (it would be called by
-        # the shorthand method anyway...)
-        try:
-            conn = self.connect_to_aws(elasticache, region)
-            if conn:
-                # show_cache_node_info = True
-                # because we also want nodes' information
-                response = conn.describe_cache_clusters(None, None, None, True)
-
-        except boto.exception.BotoServerError as e:
-            error = e.reason
-
-            if e.error_code == 'AuthFailure':
-                error = self.get_auth_error_message()
-            if not e.reason == "Forbidden":
-                error = "Looks like AWS ElastiCache is down:\n%s" % e.message
-            self.fail_with_error(error, 'getting ElastiCache clusters')
-
-        try:
-            # Boto also doesn't provide wrapper classes to CacheClusters or
-            # CacheNodes. Because of that wo can't make use of the get_list
-            # method in the AWSQueryConnection. Let's do the work manually
-            clusters = response['DescribeCacheClustersResponse']['DescribeCacheClustersResult']['CacheClusters']
-
-        except KeyError as e:
-            error = "ElastiCache query to AWS failed (unexpected format)."
-            self.fail_with_error(error, 'getting ElastiCache clusters')
-
-        for cluster in clusters:
-            self.add_elasticache_cluster(cluster, region)
-
-    def get_elasticache_replication_groups_by_region(self, region):
-        ''' Makes an AWS API call to the list of ElastiCache replication groups
-        in a particular region.'''
-
-        # ElastiCache boto module doesn't provide a get_all_intances method,
-        # that's why we need to call describe directly (it would be called by
-        # the shorthand method anyway...)
-        try:
-            conn = self.connect_to_aws(elasticache, region)
-            if conn:
-                response = conn.describe_replication_groups()
-
-        except boto.exception.BotoServerError as e:
-            error = e.reason
-
-            if e.error_code == 'AuthFailure':
-                error = self.get_auth_error_message()
-            if not e.reason == "Forbidden":
-                error = "Looks like AWS ElastiCache [Replication Groups] is down:\n%s" % e.message
-            self.fail_with_error(error, 'getting ElastiCache clusters')
-
-        try:
-            # Boto also doesn't provide wrapper classes to ReplicationGroups
-            # Because of that wo can't make use of the get_list method in the
-            # AWSQueryConnection. Let's do the work manually
-            replication_groups = response['DescribeReplicationGroupsResponse']['DescribeReplicationGroupsResult']['ReplicationGroups']
-
-        except KeyError as e:
-            error = "ElastiCache [Replication Groups] query to AWS failed (unexpected format)."
-            self.fail_with_error(error, 'getting ElastiCache clusters')
-
-        for replication_group in replication_groups:
-            self.add_elasticache_replication_group(replication_group, region)
-
-    def get_auth_error_message(self):
-        ''' create an informative error message if there is an issue authenticating'''
-        errors = ["Authentication error retrieving ec2 inventory."]
-        if None in [os.environ.get('AWS_ACCESS_KEY_ID'), os.environ.get('AWS_SECRET_ACCESS_KEY')]:
-            errors.append(' - No AWS_ACCESS_KEY_ID or AWS_SECRET_ACCESS_KEY environment vars found')
-        else:
-            errors.append(' - AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY environment vars found but may not be correct')
-
-        boto_paths = ['/etc/boto.cfg', '~/.boto', '~/.aws/credentials']
-        boto_config_found = list(p for p in boto_paths if os.path.isfile(os.path.expanduser(p)))
-        if len(boto_config_found) > 0:
-            errors.append(" - Boto configs found at '%s', but the credentials contained may not be correct" % ', '.join(boto_config_found))
-        else:
-            errors.append(" - No Boto config found at any expected location '%s'" % ', '.join(boto_paths))
-
-        return '\n'.join(errors)
-
-    def fail_with_error(self, err_msg, err_operation=None):
-        '''log an error to std err for ansible-playbook to consume and exit'''
-        if err_operation:
-            err_msg = 'ERROR: "{err_msg}", while: {err_operation}'.format(
-                    err_msg=err_msg, err_operation=err_operation)
-        sys.stderr.write(err_msg)
-        sys.exit(1)
-
-    def get_instance(self, region, instance_id):
-        conn = self.connect(region)
-
-        reservations = conn.get_all_instances([instance_id])
-        for reservation in reservations:
-            for instance in reservation.instances:
-                return instance
-
-    def add_instance(self, instance, region):
-        ''' Adds an instance to the inventory and index, as long as it is
-        addressable '''
-
-        # Only return instances with desired instance states
-        if instance.state not in self.ec2_instance_states:
-            return
-
-        # Select the best destination address
-        if self.destination_format and self.destination_format_tags:
-            dest = self.destination_format.format(*[ getattr(instance, 'tags').get(tag, '') for tag in self.destination_format_tags ])
-        elif instance.subnet_id:
-            dest = getattr(instance, self.vpc_destination_variable, None)
-            if dest is None:
-                dest = getattr(instance, 'tags').get(self.vpc_destination_variable, None)
-        else:
-            dest = getattr(instance, self.destination_variable, None)
-            if dest is None:
-                dest = getattr(instance, 'tags').get(self.destination_variable, None)
-
-        if not dest:
-            # Skip instances we cannot address (e.g. private VPC subnet)
-            return
-
-        # Set the inventory name
-        hostname = None
-        if self.hostname_variable:
-            if self.hostname_variable.startswith('tag_'):
-                hostname = instance.tags.get(self.hostname_variable[4:], None)
-            else:
-                hostname = getattr(instance, self.hostname_variable)
-
-        # If we can't get a nice hostname, use the destination address
-        if not hostname:
-            hostname = dest
-        else:
-            hostname = self.to_safe(hostname).lower()
-
-        # if we only want to include hosts that match a pattern, skip those that don't
-        if self.pattern_include and not self.pattern_include.match(hostname):
-            return
-
-        # if we need to exclude hosts that match a pattern, skip those
-        if self.pattern_exclude and self.pattern_exclude.match(hostname):
-            return
-
-        # Add to index
-        self.index[hostname] = [region, instance.id]
-
-        # Inventory: Group by instance ID (always a group of 1)
-        if self.group_by_instance_id:
-            self.inventory[instance.id] = [hostname]
-            if self.nested_groups:
-                self.push_group(self.inventory, 'instances', instance.id)
-
-        # Inventory: Group by region
-        if self.group_by_region:
-            self.push(self.inventory, region, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'regions', region)
-
-        # Inventory: Group by availability zone
-        if self.group_by_availability_zone:
-            self.push(self.inventory, instance.placement, hostname)
-            if self.nested_groups:
-                if self.group_by_region:
-                    self.push_group(self.inventory, region, instance.placement)
-                self.push_group(self.inventory, 'zones', instance.placement)
-
-        # Inventory: Group by Amazon Machine Image (AMI) ID
-        if self.group_by_ami_id:
-            ami_id = self.to_safe(instance.image_id)
-            self.push(self.inventory, ami_id, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'images', ami_id)
-
-        # Inventory: Group by instance type
-        if self.group_by_instance_type:
-            type_name = self.to_safe('type_' + instance.instance_type)
-            self.push(self.inventory, type_name, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'types', type_name)
-
-        # Inventory: Group by key pair
-        if self.group_by_key_pair and instance.key_name:
-            key_name = self.to_safe('key_' + instance.key_name)
-            self.push(self.inventory, key_name, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'keys', key_name)
-
-        # Inventory: Group by VPC
-        if self.group_by_vpc_id and instance.vpc_id:
-            vpc_id_name = self.to_safe('vpc_id_' + instance.vpc_id)
-            self.push(self.inventory, vpc_id_name, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'vpcs', vpc_id_name)
-
-        # Inventory: Group by security group
-        if self.group_by_security_group:
-            try:
-                for group in instance.groups:
-                    key = self.to_safe("security_group_" + group.name)
-                    self.push(self.inventory, key, hostname)
-                    if self.nested_groups:
-                        self.push_group(self.inventory, 'security_groups', key)
-            except AttributeError:
-                self.fail_with_error('\n'.join(['Package boto seems a bit older.',
-                                                'Please upgrade boto >= 2.3.0.']))
-
-        # Inventory: Group by tag keys
-        if self.group_by_tag_keys:
-            for k, v in instance.tags.items():
-                if self.expand_csv_tags and v and ',' in v:
-                    values = map(lambda x: x.strip(), v.split(','))
-                else:
-                    values = [v]
-
-                for v in values:
-                    if v:
-                        key = self.to_safe("tag_" + k + "=" + v)
-                    else:
-                        key = self.to_safe("tag_" + k)
-                    self.push(self.inventory, key, hostname)
-                    if self.nested_groups:
-                        self.push_group(self.inventory, 'tags', self.to_safe("tag_" + k))
-                        if v:
-                            self.push_group(self.inventory, self.to_safe("tag_" + k), key)
-
-        # Inventory: Group by Route53 domain names if enabled
-        if self.route53_enabled and self.group_by_route53_names:
-            route53_names = self.get_instance_route53_names(instance)
-            for name in route53_names:
-                self.push(self.inventory, name, hostname)
-                if self.nested_groups:
-                    self.push_group(self.inventory, 'route53', name)
-
-        # Global Tag: instances without tags
-        if self.group_by_tag_none and len(instance.tags) == 0:
-            self.push(self.inventory, 'tag_none', hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'tags', 'tag_none')
-
-        # Global Tag: tag all EC2 instances
-        self.push(self.inventory, 'ec2', hostname)
-
-        self.inventory["_meta"]["hostvars"][hostname] = self.get_host_info_dict_from_instance(instance)
-        self.inventory["_meta"]["hostvars"][hostname]['ansible_ssh_host'] = dest
-
-
-    def add_rds_instance(self, instance, region):
-        ''' Adds an RDS instance to the inventory and index, as long as it is
-        addressable '''
-
-        # Only want available instances unless all_rds_instances is True
-        if not self.all_rds_instances and instance.status != 'available':
-            return
-
-        # Select the best destination address
-        dest = instance.endpoint[0]
-
-        if not dest:
-            # Skip instances we cannot address (e.g. private VPC subnet)
-            return
-
-        # Set the inventory name
-        hostname = None
-        if self.hostname_variable:
-            if self.hostname_variable.startswith('tag_'):
-                hostname = instance.tags.get(self.hostname_variable[4:], None)
-            else:
-                hostname = getattr(instance, self.hostname_variable)
-
-        # If we can't get a nice hostname, use the destination address
-        if not hostname:
-            hostname = dest
-
-        hostname = self.to_safe(hostname).lower()
-
-        # Add to index
-        self.index[hostname] = [region, instance.id]
-
-        # Inventory: Group by instance ID (always a group of 1)
-        if self.group_by_instance_id:
-            self.inventory[instance.id] = [hostname]
-            if self.nested_groups:
-                self.push_group(self.inventory, 'instances', instance.id)
-
-        # Inventory: Group by region
-        if self.group_by_region:
-            self.push(self.inventory, region, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'regions', region)
-
-        # Inventory: Group by availability zone
-        if self.group_by_availability_zone:
-            self.push(self.inventory, instance.availability_zone, hostname)
-            if self.nested_groups:
-                if self.group_by_region:
-                    self.push_group(self.inventory, region, instance.availability_zone)
-                self.push_group(self.inventory, 'zones', instance.availability_zone)
-
-        # Inventory: Group by instance type
-        if self.group_by_instance_type:
-            type_name = self.to_safe('type_' + instance.instance_class)
-            self.push(self.inventory, type_name, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'types', type_name)
-
-        # Inventory: Group by VPC
-        if self.group_by_vpc_id and instance.subnet_group and instance.subnet_group.vpc_id:
-            vpc_id_name = self.to_safe('vpc_id_' + instance.subnet_group.vpc_id)
-            self.push(self.inventory, vpc_id_name, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'vpcs', vpc_id_name)
-
-        # Inventory: Group by security group
-        if self.group_by_security_group:
-            try:
-                if instance.security_group:
-                    key = self.to_safe("security_group_" + instance.security_group.name)
-                    self.push(self.inventory, key, hostname)
-                    if self.nested_groups:
-                        self.push_group(self.inventory, 'security_groups', key)
-
-            except AttributeError:
-                self.fail_with_error('\n'.join(['Package boto seems a bit older.',
-                                                'Please upgrade boto >= 2.3.0.']))
-
-
-        # Inventory: Group by engine
-        if self.group_by_rds_engine:
-            self.push(self.inventory, self.to_safe("rds_" + instance.engine), hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'rds_engines', self.to_safe("rds_" + instance.engine))
-
-        # Inventory: Group by parameter group
-        if self.group_by_rds_parameter_group:
-            self.push(self.inventory, self.to_safe("rds_parameter_group_" + instance.parameter_group.name), hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'rds_parameter_groups', self.to_safe("rds_parameter_group_" + instance.parameter_group.name))
-
-        # Global Tag: all RDS instances
-        self.push(self.inventory, 'rds', hostname)
-
-        self.inventory["_meta"]["hostvars"][hostname] = self.get_host_info_dict_from_instance(instance)
-        self.inventory["_meta"]["hostvars"][hostname]['ansible_ssh_host'] = dest
-
-    def add_elasticache_cluster(self, cluster, region):
-        ''' Adds an ElastiCache cluster to the inventory and index, as long as
-        it's nodes are addressable '''
-
-        # Only want available clusters unless all_elasticache_clusters is True
-        if not self.all_elasticache_clusters and cluster['CacheClusterStatus'] != 'available':
-            return
-
-        # Select the best destination address
-        if 'ConfigurationEndpoint' in cluster and cluster['ConfigurationEndpoint']:
-            # Memcached cluster
-            dest = cluster['ConfigurationEndpoint']['Address']
-            is_redis = False
-        else:
-            # Redis sigle node cluster
-            # Because all Redis clusters are single nodes, we'll merge the
-            # info from the cluster with info about the node
-            dest = cluster['CacheNodes'][0]['Endpoint']['Address']
-            is_redis = True
-
-        if not dest:
-            # Skip clusters we cannot address (e.g. private VPC subnet)
-            return
-
-        # Add to index
-        self.index[dest] = [region, cluster['CacheClusterId']]
-
-        # Inventory: Group by instance ID (always a group of 1)
-        if self.group_by_instance_id:
-            self.inventory[cluster['CacheClusterId']] = [dest]
-            if self.nested_groups:
-                self.push_group(self.inventory, 'instances', cluster['CacheClusterId'])
-
-        # Inventory: Group by region
-        if self.group_by_region and not is_redis:
-            self.push(self.inventory, region, dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'regions', region)
-
-        # Inventory: Group by availability zone
-        if self.group_by_availability_zone and not is_redis:
-            self.push(self.inventory, cluster['PreferredAvailabilityZone'], dest)
-            if self.nested_groups:
-                if self.group_by_region:
-                    self.push_group(self.inventory, region, cluster['PreferredAvailabilityZone'])
-                self.push_group(self.inventory, 'zones', cluster['PreferredAvailabilityZone'])
-
-        # Inventory: Group by node type
-        if self.group_by_instance_type and not is_redis:
-            type_name = self.to_safe('type_' + cluster['CacheNodeType'])
-            self.push(self.inventory, type_name, dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'types', type_name)
-
-        # Inventory: Group by VPC (information not available in the current
-        # AWS API version for ElastiCache)
-
-        # Inventory: Group by security group
-        if self.group_by_security_group and not is_redis:
-
-            # Check for the existence of the 'SecurityGroups' key and also if
-            # this key has some value. When the cluster is not placed in a SG
-            # the query can return None here and cause an error.
-            if 'SecurityGroups' in cluster and cluster['SecurityGroups'] is not None:
-                for security_group in cluster['SecurityGroups']:
-                    key = self.to_safe("security_group_" + security_group['SecurityGroupId'])
-                    self.push(self.inventory, key, dest)
-                    if self.nested_groups:
-                        self.push_group(self.inventory, 'security_groups', key)
-
-        # Inventory: Group by engine
-        if self.group_by_elasticache_engine and not is_redis:
-            self.push(self.inventory, self.to_safe("elasticache_" + cluster['Engine']), dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'elasticache_engines', self.to_safe(cluster['Engine']))
-
-        # Inventory: Group by parameter group
-        if self.group_by_elasticache_parameter_group:
-            self.push(self.inventory, self.to_safe("elasticache_parameter_group_" + cluster['CacheParameterGroup']['CacheParameterGroupName']), dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'elasticache_parameter_groups', self.to_safe(cluster['CacheParameterGroup']['CacheParameterGroupName']))
-
-        # Inventory: Group by replication group
-        if self.group_by_elasticache_replication_group and 'ReplicationGroupId' in cluster and cluster['ReplicationGroupId']:
-            self.push(self.inventory, self.to_safe("elasticache_replication_group_" + cluster['ReplicationGroupId']), dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'elasticache_replication_groups', self.to_safe(cluster['ReplicationGroupId']))
-
-        # Global Tag: all ElastiCache clusters
-        self.push(self.inventory, 'elasticache_clusters', cluster['CacheClusterId'])
-
-        host_info = self.get_host_info_dict_from_describe_dict(cluster)
-
-        self.inventory["_meta"]["hostvars"][dest] = host_info
-
-        # Add the nodes
-        for node in cluster['CacheNodes']:
-            self.add_elasticache_node(node, cluster, region)
-
-    def add_elasticache_node(self, node, cluster, region):
-        ''' Adds an ElastiCache node to the inventory and index, as long as
-        it is addressable '''
-
-        # Only want available nodes unless all_elasticache_nodes is True
-        if not self.all_elasticache_nodes and node['CacheNodeStatus'] != 'available':
-            return
-
-        # Select the best destination address
-        dest = node['Endpoint']['Address']
-
-        if not dest:
-            # Skip nodes we cannot address (e.g. private VPC subnet)
-            return
-
-        node_id = self.to_safe(cluster['CacheClusterId'] + '_' + node['CacheNodeId'])
-
-        # Add to index
-        self.index[dest] = [region, node_id]
-
-        # Inventory: Group by node ID (always a group of 1)
-        if self.group_by_instance_id:
-            self.inventory[node_id] = [dest]
-            if self.nested_groups:
-                self.push_group(self.inventory, 'instances', node_id)
-
-        # Inventory: Group by region
-        if self.group_by_region:
-            self.push(self.inventory, region, dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'regions', region)
-
-        # Inventory: Group by availability zone
-        if self.group_by_availability_zone:
-            self.push(self.inventory, cluster['PreferredAvailabilityZone'], dest)
-            if self.nested_groups:
-                if self.group_by_region:
-                    self.push_group(self.inventory, region, cluster['PreferredAvailabilityZone'])
-                self.push_group(self.inventory, 'zones', cluster['PreferredAvailabilityZone'])
-
-        # Inventory: Group by node type
-        if self.group_by_instance_type:
-            type_name = self.to_safe('type_' + cluster['CacheNodeType'])
-            self.push(self.inventory, type_name, dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'types', type_name)
-
-        # Inventory: Group by VPC (information not available in the current
-        # AWS API version for ElastiCache)
-
-        # Inventory: Group by security group
-        if self.group_by_security_group:
-
-            # Check for the existence of the 'SecurityGroups' key and also if
-            # this key has some value. When the cluster is not placed in a SG
-            # the query can return None here and cause an error.
-            if 'SecurityGroups' in cluster and cluster['SecurityGroups'] is not None:
-                for security_group in cluster['SecurityGroups']:
-                    key = self.to_safe("security_group_" + security_group['SecurityGroupId'])
-                    self.push(self.inventory, key, dest)
-                    if self.nested_groups:
-                        self.push_group(self.inventory, 'security_groups', key)
-
-        # Inventory: Group by engine
-        if self.group_by_elasticache_engine:
-            self.push(self.inventory, self.to_safe("elasticache_" + cluster['Engine']), dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'elasticache_engines', self.to_safe("elasticache_" + cluster['Engine']))
-
-        # Inventory: Group by parameter group (done at cluster level)
-
-        # Inventory: Group by replication group (done at cluster level)
-
-        # Inventory: Group by ElastiCache Cluster
-        if self.group_by_elasticache_cluster:
-            self.push(self.inventory, self.to_safe("elasticache_cluster_" + cluster['CacheClusterId']), dest)
-
-        # Global Tag: all ElastiCache nodes
-        self.push(self.inventory, 'elasticache_nodes', dest)
-
-        host_info = self.get_host_info_dict_from_describe_dict(node)
-
-        if dest in self.inventory["_meta"]["hostvars"]:
-            self.inventory["_meta"]["hostvars"][dest].update(host_info)
-        else:
-            self.inventory["_meta"]["hostvars"][dest] = host_info
-
-    def add_elasticache_replication_group(self, replication_group, region):
-        ''' Adds an ElastiCache replication group to the inventory and index '''
-
-        # Only want available clusters unless all_elasticache_replication_groups is True
-        if not self.all_elasticache_replication_groups and replication_group['Status'] != 'available':
-            return
-
-        # Select the best destination address (PrimaryEndpoint)
-        dest = replication_group['NodeGroups'][0]['PrimaryEndpoint']['Address']
-
-        if not dest:
-            # Skip clusters we cannot address (e.g. private VPC subnet)
-            return
-
-        # Add to index
-        self.index[dest] = [region, replication_group['ReplicationGroupId']]
-
-        # Inventory: Group by ID (always a group of 1)
-        if self.group_by_instance_id:
-            self.inventory[replication_group['ReplicationGroupId']] = [dest]
-            if self.nested_groups:
-                self.push_group(self.inventory, 'instances', replication_group['ReplicationGroupId'])
-
-        # Inventory: Group by region
-        if self.group_by_region:
-            self.push(self.inventory, region, dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'regions', region)
-
-        # Inventory: Group by availability zone (doesn't apply to replication groups)
-
-        # Inventory: Group by node type (doesn't apply to replication groups)
-
-        # Inventory: Group by VPC (information not available in the current
-        # AWS API version for replication groups
-
-        # Inventory: Group by security group (doesn't apply to replication groups)
-        # Check this value in cluster level
-
-        # Inventory: Group by engine (replication groups are always Redis)
-        if self.group_by_elasticache_engine:
-            self.push(self.inventory, 'elasticache_redis', dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'elasticache_engines', 'redis')
-
-        # Global Tag: all ElastiCache clusters
-        self.push(self.inventory, 'elasticache_replication_groups', replication_group['ReplicationGroupId'])
-
-        host_info = self.get_host_info_dict_from_describe_dict(replication_group)
-
-        self.inventory["_meta"]["hostvars"][dest] = host_info
-
-    def get_route53_records(self):
-        ''' Get and store the map of resource records to domain names that
-        point to them. '''
-
-        r53_conn = route53.Route53Connection()
-        all_zones = r53_conn.get_zones()
-
-        route53_zones = [ zone for zone in all_zones if zone.name[:-1]
-                          not in self.route53_excluded_zones ]
-
-        self.route53_records = {}
-
-        for zone in route53_zones:
-            rrsets = r53_conn.get_all_rrsets(zone.id)
-
-            for record_set in rrsets:
-                record_name = record_set.name
-
-                if record_name.endswith('.'):
-                    record_name = record_name[:-1]
-
-                for resource in record_set.resource_records:
-                    self.route53_records.setdefault(resource, set())
-                    self.route53_records[resource].add(record_name)
-
-
-    def get_instance_route53_names(self, instance):
-        ''' Check if an instance is referenced in the records we have from
-        Route53. If it is, return the list of domain names pointing to said
-        instance. If nothing points to it, return an empty list. '''
-
-        instance_attributes = [ 'public_dns_name', 'private_dns_name',
-                                'ip_address', 'private_ip_address' ]
-
-        name_list = set()
-
-        for attrib in instance_attributes:
-            try:
-                value = getattr(instance, attrib)
-            except AttributeError:
-                continue
-
-            if value in self.route53_records:
-                name_list.update(self.route53_records[value])
-
-        return list(name_list)
-
-    def get_host_info_dict_from_instance(self, instance):
-        instance_vars = {}
-        for key in vars(instance):
-            value = getattr(instance, key)
-            key = self.to_safe('ec2_' + key)
-
-            # Handle complex types
-            # state/previous_state changed to properties in boto in https://github.com/boto/boto/commit/a23c379837f698212252720d2af8dec0325c9518
-            if key == 'ec2__state':
-                instance_vars['ec2_state'] = instance.state or ''
-                instance_vars['ec2_state_code'] = instance.state_code
-            elif key == 'ec2__previous_state':
-                instance_vars['ec2_previous_state'] = instance.previous_state or ''
-                instance_vars['ec2_previous_state_code'] = instance.previous_state_code
-            elif type(value) in [int, bool]:
-                instance_vars[key] = value
-            elif isinstance(value, six.string_types):
-                instance_vars[key] = value.strip()
-            elif type(value) == type(None):
-                instance_vars[key] = ''
-            elif key == 'ec2_region':
-                instance_vars[key] = value.name
-            elif key == 'ec2__placement':
-                instance_vars['ec2_placement'] = value.zone
-            elif key == 'ec2_tags':
-                for k, v in value.items():
-                    if self.expand_csv_tags and ',' in v:
-                        v = map(lambda x: x.strip(), v.split(','))
-                    key = self.to_safe('ec2_tag_' + k)
-                    instance_vars[key] = v
-            elif key == 'ec2_groups':
-                group_ids = []
-                group_names = []
-                for group in value:
-                    group_ids.append(group.id)
-                    group_names.append(group.name)
-                instance_vars["ec2_security_group_ids"] = ','.join([str(i) for i in group_ids])
-                instance_vars["ec2_security_group_names"] = ','.join([str(i) for i in group_names])
-            else:
-                pass
-                # TODO Product codes if someone finds them useful
-                #print key
-                #print type(value)
-                #print value
-
-        return instance_vars
-
-    def get_host_info_dict_from_describe_dict(self, describe_dict):
-        ''' Parses the dictionary returned by the API call into a flat list
-            of parameters. This method should be used only when 'describe' is
-            used directly because Boto doesn't provide specific classes. '''
-
-        # I really don't agree with prefixing everything with 'ec2'
-        # because EC2, RDS and ElastiCache are different services.
-        # I'm just following the pattern used until now to not break any
-        # compatibility.
-
-        host_info = {}
-        for key in describe_dict:
-            value = describe_dict[key]
-            key = self.to_safe('ec2_' + self.uncammelize(key))
-
-            # Handle complex types
-
-            # Target: Memcached Cache Clusters
-            if key == 'ec2_configuration_endpoint' and value:
-                host_info['ec2_configuration_endpoint_address'] = value['Address']
-                host_info['ec2_configuration_endpoint_port'] = value['Port']
-
-            # Target: Cache Nodes and Redis Cache Clusters (single node)
-            if key == 'ec2_endpoint' and value:
-                host_info['ec2_endpoint_address'] = value['Address']
-                host_info['ec2_endpoint_port'] = value['Port']
-
-            # Target: Redis Replication Groups
-            if key == 'ec2_node_groups' and value:
-                host_info['ec2_endpoint_address'] = value[0]['PrimaryEndpoint']['Address']
-                host_info['ec2_endpoint_port'] = value[0]['PrimaryEndpoint']['Port']
-                replica_count = 0
-                for node in value[0]['NodeGroupMembers']:
-                    if node['CurrentRole'] == 'primary':
-                        host_info['ec2_primary_cluster_address'] = node['ReadEndpoint']['Address']
-                        host_info['ec2_primary_cluster_port'] = node['ReadEndpoint']['Port']
-                        host_info['ec2_primary_cluster_id'] = node['CacheClusterId']
-                    elif node['CurrentRole'] == 'replica':
-                        host_info['ec2_replica_cluster_address_'+ str(replica_count)] = node['ReadEndpoint']['Address']
-                        host_info['ec2_replica_cluster_port_'+ str(replica_count)] = node['ReadEndpoint']['Port']
-                        host_info['ec2_replica_cluster_id_'+ str(replica_count)] = node['CacheClusterId']
-                        replica_count += 1
-
-            # Target: Redis Replication Groups
-            if key == 'ec2_member_clusters' and value:
-                host_info['ec2_member_clusters'] = ','.join([str(i) for i in value])
-
-            # Target: All Cache Clusters
-            elif key == 'ec2_cache_parameter_group':
-                host_info["ec2_cache_node_ids_to_reboot"] = ','.join([str(i) for i in value['CacheNodeIdsToReboot']])
-                host_info['ec2_cache_parameter_group_name'] = value['CacheParameterGroupName']
-                host_info['ec2_cache_parameter_apply_status'] = value['ParameterApplyStatus']
-
-            # Target: Almost everything
-            elif key == 'ec2_security_groups':
-
-                # Skip if SecurityGroups is None
-                # (it is possible to have the key defined but no value in it).
-                if value is not None:
-                    sg_ids = []
-                    for sg in value:
-                        sg_ids.append(sg['SecurityGroupId'])
-                    host_info["ec2_security_group_ids"] = ','.join([str(i) for i in sg_ids])
-
-            # Target: Everything
-            # Preserve booleans and integers
-            elif type(value) in [int, bool]:
-                host_info[key] = value
-
-            # Target: Everything
-            # Sanitize string values
-            elif isinstance(value, six.string_types):
-                host_info[key] = value.strip()
-
-            # Target: Everything
-            # Replace None by an empty string
-            elif type(value) == type(None):
-                host_info[key] = ''
-
-            else:
-                # Remove non-processed complex types
-                pass
-
-        return host_info
-
-    def get_host_info(self):
-        ''' Get variables about a specific host '''
-
-        if len(self.index) == 0:
-            # Need to load index from cache
-            self.load_index_from_cache()
-
-        if not self.args.host in self.index:
-            # try updating the cache
-            self.do_api_calls_update_cache()
-            if not self.args.host in self.index:
-                # host might not exist anymore
-                return self.json_format_dict({}, True)
-
-        (region, instance_id) = self.index[self.args.host]
-
-        instance = self.get_instance(region, instance_id)
-        return self.json_format_dict(self.get_host_info_dict_from_instance(instance), True)
-
-    def push(self, my_dict, key, element):
-        ''' Push an element onto an array that may not have been defined in
-        the dict '''
-        group_info = my_dict.setdefault(key, [])
-        if isinstance(group_info, dict):
-            host_list = group_info.setdefault('hosts', [])
-            host_list.append(element)
-        else:
-            group_info.append(element)
-
-    def push_group(self, my_dict, key, element):
-        ''' Push a group as a child of another group. '''
-        parent_group = my_dict.setdefault(key, {})
-        if not isinstance(parent_group, dict):
-            parent_group = my_dict[key] = {'hosts': parent_group}
-        child_groups = parent_group.setdefault('children', [])
-        if element not in child_groups:
-            child_groups.append(element)
-
-    def get_inventory_from_cache(self):
-        ''' Reads the inventory from the cache file and returns it as a JSON
-        object '''
-
-        cache = open(self.cache_path_cache, 'r')
-        json_inventory = cache.read()
-        return json_inventory
-
-
-    def load_index_from_cache(self):
-        ''' Reads the index from the cache file sets self.index '''
-
-        cache = open(self.cache_path_index, 'r')
-        json_index = cache.read()
-        self.index = json.loads(json_index)
-
-
-    def write_to_cache(self, data, filename):
-        ''' Writes data in JSON format to a file '''
-
-        json_data = self.json_format_dict(data, True)
-        cache = open(filename, 'w')
-        cache.write(json_data)
-        cache.close()
-
-    def uncammelize(self, key):
-        temp = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', key)
-        return re.sub('([a-z0-9])([A-Z])', r'\1_\2', temp).lower()
-
-    def to_safe(self, word):
-        ''' Converts 'bad' characters in a string to underscores so they can be used as Ansible groups '''
-        regex = "[^A-Za-z0-9\_"
-        if not self.replace_dash_in_groups:
-            regex += "\-"
-        return re.sub(regex + "]", "_", word)
-
-    def json_format_dict(self, data, pretty=False):
-        ''' Converts a dict to a JSON object and dumps it as a formatted
-        string '''
-
-        if pretty:
-            return json.dumps(data, sort_keys=True, indent=2)
-        else:
-            return json.dumps(data)
-
-
-# Run the script
-Ec2Inventory()
diff --git a/edge-1601-dc6/inventory b/edge-1601-dc6/inventory
deleted file mode 100644
index 08fc86f..0000000
--- a/edge-1601-dc6/inventory
+++ /dev/null
@@ -1,119 +0,0 @@
-[tag_Name_dc6_n1]
-[tag_Name_dc6_n2]
-[tag_Name_dc6_n3]
-[tag_Name_dc6_n4]
-[tag_Name_dc6_n5]
-[tag_Name_dc6_n6]
-[tag_Name_dc6_n7]
-[tag_Name_dc6_n8]
-[tag_Name_dc6_n9]
-[tag_Name_dc6_n10]
-[tag_Name_dc6_n11]
-[tag_Name_dc6_n12]
-[tag_Name_dc6_n13]
-[tag_Name_dc6_n14]
-[tag_Name_dc6_n15]
-[tag_Name_dc6_n16]
-[tag_Name_dc6_n17]
-[tag_Name_dc6_n18]
-[tag_Name_dc6_n19]
-[tag_Name_dc6_n20]
-[tag_Name_dc6_n21]
-
-[planet:children]
-dc-1
-
-[dc-1:children]
-tag_Name_dc6_n1
-tag_Name_dc6_n2
-tag_Name_dc6_n3
-tag_Name_dc6_n4
-tag_Name_dc6_n5
-tag_Name_dc6_n6
-tag_Name_dc6_n7
-tag_Name_dc6_n8
-tag_Name_dc6_n9
-tag_Name_dc6_n10
-tag_Name_dc6_n11
-tag_Name_dc6_n12
-tag_Name_dc6_n13
-tag_Name_dc6_n14
-tag_Name_dc6_n15
-tag_Name_dc6_n16
-tag_Name_dc6_n17
-tag_Name_dc6_n18
-tag_Name_dc6_n19
-tag_Name_dc6_n20
-tag_Name_dc6_n21
-
-[ds:children]
-dc-1-ds
-
-[dc-1-ds:children]
-tag_Name_dc6_n3
-tag_Name_dc6_n4
-tag_Name_dc6_n5
-tag_Name_dc6_n6
-tag_Name_dc6_n7
-tag_Name_dc6_n8
-tag_Name_dc6_n9
-tag_Name_dc6_n10
-
-[ms:children]
-dc-1-ms
-
-[dc-1-ms:children]
-tag_Name_dc6_n1
-tag_Name_dc6_n2
-
-[ui:children]
-dc-1-ui
-
-[dc-1-ui:children]
-tag_Name_dc6_n1
-tag_Name_dc6_n2
-
-[ldap:children]
-dc-1-ldap
-
-[dc-1-ldap:children]
-tag_Name_dc6_n1
-tag_Name_dc6_n2
-
-[rmp:children]
-dc-1-rmp
-
-[dc-1-rmp:children]
-tag_Name_dc6_n11
-tag_Name_dc6_n12
-tag_Name_dc6_n13
-tag_Name_dc6_n14
-tag_Name_dc6_n15
-tag_Name_dc6_n16
-tag_Name_dc6_n17
-
-[qpid:children]
-dc-1-qpid
-
-[dc-1-qpid:children]
-tag_Name_dc6_n18
-tag_Name_dc6_n19
-
-[pg:children]
-dc-1-pg
-
-[dc-1-pg:children]
-dc-1-pgmaster
-dc-1-pgstandby
-
-[pgmaster:children]
-dc-1-pgmaster
-
-[dc-1-pgmaster:children]
-tag_Name_dc6_n20
-
-[pgstandby:children]
-dc-1-pgstandby
-
-[dc-1-pgstandby:children]
-tag_Name_dc6_n21
diff --git a/edge-1605-dc3/ec2.ini b/edge-1605-dc3/ec2.ini
deleted file mode 100644
index 36b3921..0000000
--- a/edge-1605-dc3/ec2.ini
+++ /dev/null
@@ -1,200 +0,0 @@
-# Ansible EC2 external inventory script settings
-#
-
-[ec2]
-
-# to talk to a private eucalyptus instance uncomment these lines
-# and edit edit eucalyptus_host to be the host name of your cloud controller
-#eucalyptus = True
-#eucalyptus_host = clc.cloud.domain.org
-
-# AWS regions to make calls to. Set this to 'all' to make request to all regions
-# in AWS and merge the results together. Alternatively, set this to a comma
-# separated list of regions. E.g. 'us-east-1,us-west-1,us-west-2'
-regions = all
-regions_exclude = us-gov-west-1,cn-north-1
-
-# When generating inventory, Ansible needs to know how to address a server.
-# Each EC2 instance has a lot of variables associated with it. Here is the list:
-#   http://docs.pythonboto.org/en/latest/ref/ec2.html#module-boto.ec2.instance
-# Below are 2 variables that are used as the address of a server:
-#   - destination_variable
-#   - vpc_destination_variable
-
-# This is the normal destination variable to use. If you are running Ansible
-# from outside EC2, then 'public_dns_name' makes the most sense. If you are
-# running Ansible from within EC2, then perhaps you want to use the internal
-# address, and should set this to 'private_dns_name'. The key of an EC2 tag
-# may optionally be used; however the boto instance variables hold precedence
-# in the event of a collision.
-destination_variable = public_dns_name
-
-# This allows you to override the inventory_name with an ec2 variable, instead
-# of using the destination_variable above. Addressing (aka ansible_ssh_host)
-# will still use destination_variable. Tags should be written as 'tag_TAGNAME'.
-#hostname_variable = tag_Name
-
-# For server inside a VPC, using DNS names may not make sense. When an instance
-# has 'subnet_id' set, this variable is used. If the subnet is public, setting
-# this to 'ip_address' will return the public IP address. For instances in a
-# private subnet, this should be set to 'private_ip_address', and Ansible must
-# be run from within EC2. The key of an EC2 tag may optionally be used; however
-# the boto instance variables hold precedence in the event of a collision.
-# WARNING: - instances that are in the private vpc, _without_ public ip address
-# will not be listed in the inventory until You set:
-# vpc_destination_variable = private_ip_address
-vpc_destination_variable = ip_address
-
-# The following two settings allow flexible ansible host naming based on a
-# python format string and a comma-separated list of ec2 tags.  Note that:
-#
-# 1) If the tags referenced are not present for some instances, empty strings
-#    will be substituted in the format string.
-# 2) This overrides both destination_variable and vpc_destination_variable.
-#
-#destination_format = {0}.{1}.example.com
-#destination_format_tags = Name,environment
-
-# To tag instances on EC2 with the resource records that point to them from
-# Route53, uncomment and set 'route53' to True.
-route53 = False
-
-# To exclude RDS instances from the inventory, uncomment and set to False.
-rds = False
-
-# To exclude ElastiCache instances from the inventory, uncomment and set to False.
-elasticache = False
-
-# Additionally, you can specify the list of zones to exclude looking up in
-# 'route53_excluded_zones' as a comma-separated list.
-# route53_excluded_zones = samplezone1.com, samplezone2.com
-
-# By default, only EC2 instances in the 'running' state are returned. Set
-# 'all_instances' to True to return all instances regardless of state.
-all_instances = True
-
-# By default, only EC2 instances in the 'running' state are returned. Specify
-# EC2 instance states to return as a comma-separated list. This
-# option is overriden when 'all_instances' is True.
-# instance_states = pending, running, shutting-down, terminated, stopping, stopped
-
-# By default, only RDS instances in the 'available' state are returned.  Set
-# 'all_rds_instances' to True return all RDS instances regardless of state.
-all_rds_instances = False
-
-# By default, only ElastiCache clusters and nodes in the 'available' state
-# are returned. Set 'all_elasticache_clusters' and/or 'all_elastic_nodes'
-# to True return all ElastiCache clusters and nodes, regardless of state.
-#
-# Note that all_elasticache_nodes only applies to listed clusters. That means
-# if you set all_elastic_clusters to false, no node will be return from
-# unavailable clusters, regardless of the state and to what you set for
-# all_elasticache_nodes.
-all_elasticache_replication_groups = False
-all_elasticache_clusters = False
-all_elasticache_nodes = False
-
-# API calls to EC2 are slow. For this reason, we cache the results of an API
-# call. Set this to the path you want cache files to be written to. Two files
-# will be written to this directory:
-#   - ansible-ec2.cache
-#   - ansible-ec2.index
-cache_path = ~/.ansible/tmp
-
-# The number of seconds a cache file is considered valid. After this many
-# seconds, a new API call will be made, and the cache file will be updated.
-# To disable the cache, set this value to 0
-cache_max_age = 300
-
-# Organize groups into a nested/hierarchy instead of a flat namespace.
-nested_groups = False
-
-# Replace - tags when creating groups to avoid issues with ansible
-replace_dash_in_groups = True
-
-# If set to true, any tag of the form "a,b,c" is expanded into a list
-# and the results are used to create additional tag_* inventory groups.
-expand_csv_tags = False
-
-# The EC2 inventory output can become very large. To manage its size,
-# configure which groups should be created.
-group_by_instance_id = True
-group_by_region = True
-group_by_availability_zone = True
-group_by_ami_id = True
-group_by_instance_type = True
-group_by_key_pair = True
-group_by_vpc_id = True
-group_by_security_group = True
-group_by_tag_keys = True
-group_by_tag_none = True
-group_by_route53_names = True
-group_by_rds_engine = False
-group_by_rds_parameter_group = False
-group_by_elasticache_engine = True
-group_by_elasticache_cluster = True
-group_by_elasticache_parameter_group = True
-group_by_elasticache_replication_group = True
-
-# If you only want to include hosts that match a certain regular expression
-# pattern_include = staging-*
-
-# If you want to exclude any hosts that match a certain regular expression
-# pattern_exclude = staging-*
-# Ansible EC2 external inventory script settings
-#
-
-##[ec2]
-##
-### to talk to a private eucalyptus instance uncomment these lines
-### and edit edit eucalyptus_host to be the host name of your cloud controller
-###eucalyptus = True
-###eucalyptus_host = clc.cloud.domain.org
-##
-### AWS regions to make calls to. Set this to 'all' to make request to all regions
-##
-### in AWS and merge the results together. Alternatively, set this to a comma
-### separated list of regions. E.g. 'us-east-1,us-west-1,us-west-2'
-##regions = all
-##regions_exclude = us-gov-west-1,cn-north-1
-##
-### When generating inventory, Ansible needs to know how to address a server.
-### Each EC2 instance has a lot of variables associated with it. Here is the list:
-###   http://docs.pythonboto.org/en/latest/ref/ec2.html#module-boto.ec2.instance
-### Below are 2 variables that are used as the address of a server:
-###   - destination_variable
-###   - vpc_destination_variable
-##
-### This is the normal destination variable to use. If you are running Ansible
-### from outside EC2, then 'public_dns_name' makes the most sense. If you are
-### running Ansible from within EC2, then perhaps you want to use the internal
-### address, and should set this to 'private_dns_name'. The key of an EC2 tag
-##...skipping...
-### pattern_include = staging-*
-##
-### If you want to exclude any hosts that match a certain regular expression
-### pattern_exclude = staging-*
-
-# Instance filters can be used to control which instances are retrieved for
-# inventory. For the full list of possible filters, please read the EC2 API
-# docs: http://docs.aws.amazon.com/AWSEC2/latest/APIReference/ApiReference-query-DescribeInstances.html#query-DescribeInstances-filters
-# Filters are key/value pairs separated by '=', to list multiple filters use
-# a list separated by commas. See examples below.
-
-# Retrieve only instances with (key=value) env=staging tag
-# instance_filters = tag:env=staging
-
-# Retrieve only instances with role=webservers OR role=dbservers tag
-# instance_filters = tag:role=webservers,tag:role=dbservers
-
-# Retrieve only t1.micro instances OR instances with tag env=staging
-# instance_filters = instance-type=t1.micro,tag:env=staging
-
-# You can use wildcards in filter values also. Below will list instances which
-# tag Name value matches webservers1*
-# (ex. webservers15, webservers1a, webservers123 etc)
-# instance_filters = tag:Name=webservers1*
-
-# A boto configuration profile may be used to separate out credentials
-# see http://boto.readthedocs.org/en/latest/boto_config_tut.html
-# boto_profile = some-boto-profile-name
diff --git a/edge-1605-dc3/ec2.py b/edge-1605-dc3/ec2.py
deleted file mode 100755
index f30958a..0000000
--- a/edge-1605-dc3/ec2.py
+++ /dev/null
@@ -1,1385 +0,0 @@
-#!/usr/bin/env python
-
-'''
-EC2 external inventory script
-=================================
-
-Generates inventory that Ansible can understand by making API request to
-AWS EC2 using the Boto library.
-
-NOTE: This script assumes Ansible is being executed where the environment
-variables needed for Boto have already been set:
-    export AWS_ACCESS_KEY_ID='AK123'
-    export AWS_SECRET_ACCESS_KEY='abc123'
-
-This script also assumes there is an ec2.ini file alongside it.  To specify a
-different path to ec2.ini, define the EC2_INI_PATH environment variable:
-
-    export EC2_INI_PATH=/path/to/my_ec2.ini
-
-If you're using eucalyptus you need to set the above variables and
-you need to define:
-
-    export EC2_URL=http://hostname_of_your_cc:port/services/Eucalyptus
-
-If you're using boto profiles (requires boto>=2.24.0) you can choose a profile
-using the --boto-profile command line argument (e.g. ec2.py --boto-profile prod) or using
-the AWS_PROFILE variable:
-
-    AWS_PROFILE=prod ansible-playbook -i ec2.py myplaybook.yml
-
-For more details, see: http://docs.pythonboto.org/en/latest/boto_config_tut.html
-
-When run against a specific host, this script returns the following variables:
- - ec2_ami_launch_index
- - ec2_architecture
- - ec2_association
- - ec2_attachTime
- - ec2_attachment
- - ec2_attachmentId
- - ec2_client_token
- - ec2_deleteOnTermination
- - ec2_description
- - ec2_deviceIndex
- - ec2_dns_name
- - ec2_eventsSet
- - ec2_group_name
- - ec2_hypervisor
- - ec2_id
- - ec2_image_id
- - ec2_instanceState
- - ec2_instance_type
- - ec2_ipOwnerId
- - ec2_ip_address
- - ec2_item
- - ec2_kernel
- - ec2_key_name
- - ec2_launch_time
- - ec2_monitored
- - ec2_monitoring
- - ec2_networkInterfaceId
- - ec2_ownerId
- - ec2_persistent
- - ec2_placement
- - ec2_platform
- - ec2_previous_state
- - ec2_private_dns_name
- - ec2_private_ip_address
- - ec2_publicIp
- - ec2_public_dns_name
- - ec2_ramdisk
- - ec2_reason
- - ec2_region
- - ec2_requester_id
- - ec2_root_device_name
- - ec2_root_device_type
- - ec2_security_group_ids
- - ec2_security_group_names
- - ec2_shutdown_state
- - ec2_sourceDestCheck
- - ec2_spot_instance_request_id
- - ec2_state
- - ec2_state_code
- - ec2_state_reason
- - ec2_status
- - ec2_subnet_id
- - ec2_tenancy
- - ec2_virtualization_type
- - ec2_vpc_id
-
-These variables are pulled out of a boto.ec2.instance object. There is a lack of
-consistency with variable spellings (camelCase and underscores) since this
-just loops through all variables the object exposes. It is preferred to use the
-ones with underscores when multiple exist.
-
-In addition, if an instance has AWS Tags associated with it, each tag is a new
-variable named:
- - ec2_tag_[Key] = [Value]
-
-Security groups are comma-separated in 'ec2_security_group_ids' and
-'ec2_security_group_names'.
-'''
-
-# (c) 2012, Peter Sankauskas
-#
-# This file is part of Ansible,
-#
-# Ansible is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# Ansible is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with Ansible.  If not, see <http://www.gnu.org/licenses/>.
-
-######################################################################
-
-import sys
-import os
-import argparse
-import re
-from time import time
-import boto
-from boto import ec2
-from boto import rds
-from boto import elasticache
-from boto import route53
-import six
-
-from six.moves import configparser
-from collections import defaultdict
-
-try:
-    import json
-except ImportError:
-    import simplejson as json
-
-
-class Ec2Inventory(object):
-
-    def _empty_inventory(self):
-        return {"_meta" : {"hostvars" : {}}}
-
-    def __init__(self):
-        ''' Main execution path '''
-
-        # Inventory grouped by instance IDs, tags, security groups, regions,
-        # and availability zones
-        self.inventory = self._empty_inventory()
-
-        # Index of hostname (address) to instance ID
-        self.index = {}
-
-        # Boto profile to use (if any)
-        self.boto_profile = None
-
-        # Read settings and parse CLI arguments
-        self.parse_cli_args()
-        self.read_settings()
-
-        # Make sure that profile_name is not passed at all if not set
-        # as pre 2.24 boto will fall over otherwise
-        if self.boto_profile:
-            if not hasattr(boto.ec2.EC2Connection, 'profile_name'):
-                self.fail_with_error("boto version must be >= 2.24 to use profile")
-
-        # Cache
-        if self.args.refresh_cache:
-            self.do_api_calls_update_cache()
-        elif not self.is_cache_valid():
-            self.do_api_calls_update_cache()
-
-        # Data to print
-        if self.args.host:
-            data_to_print = self.get_host_info()
-
-        elif self.args.list:
-            # Display list of instances for inventory
-            if self.inventory == self._empty_inventory():
-                data_to_print = self.get_inventory_from_cache()
-            else:
-                data_to_print = self.json_format_dict(self.inventory, True)
-
-        print(data_to_print)
-
-
-    def is_cache_valid(self):
-        ''' Determines if the cache files have expired, or if it is still valid '''
-
-        if os.path.isfile(self.cache_path_cache):
-            mod_time = os.path.getmtime(self.cache_path_cache)
-            current_time = time()
-            if (mod_time + self.cache_max_age) > current_time:
-                if os.path.isfile(self.cache_path_index):
-                    return True
-
-        return False
-
-
-    def read_settings(self):
-        ''' Reads the settings from the ec2.ini file '''
-        if six.PY3:
-            config = configparser.ConfigParser()
-        else:
-            config = configparser.SafeConfigParser()
-        ec2_default_ini_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'ec2.ini')
-        ec2_ini_path = os.path.expanduser(os.path.expandvars(os.environ.get('EC2_INI_PATH', ec2_default_ini_path)))
-        config.read(ec2_ini_path)
-
-        # is eucalyptus?
-        self.eucalyptus_host = None
-        self.eucalyptus = False
-        if config.has_option('ec2', 'eucalyptus'):
-            self.eucalyptus = config.getboolean('ec2', 'eucalyptus')
-        if self.eucalyptus and config.has_option('ec2', 'eucalyptus_host'):
-            self.eucalyptus_host = config.get('ec2', 'eucalyptus_host')
-
-        # Regions
-        self.regions = []
-        configRegions = config.get('ec2', 'regions')
-        configRegions_exclude = config.get('ec2', 'regions_exclude')
-        if (configRegions == 'all'):
-            if self.eucalyptus_host:
-                self.regions.append(boto.connect_euca(host=self.eucalyptus_host).region.name)
-            else:
-                for regionInfo in ec2.regions():
-                    if regionInfo.name not in configRegions_exclude:
-                        self.regions.append(regionInfo.name)
-        else:
-            self.regions = configRegions.split(",")
-
-        # Destination addresses
-        self.destination_variable = config.get('ec2', 'destination_variable')
-        self.vpc_destination_variable = config.get('ec2', 'vpc_destination_variable')
-
-        if config.has_option('ec2', 'hostname_variable'):
-            self.hostname_variable = config.get('ec2', 'hostname_variable')
-        else:
-            self.hostname_variable = None
-
-        if config.has_option('ec2', 'destination_format') and \
-                config.has_option('ec2', 'destination_format_tags'):
-            self.destination_format = config.get('ec2', 'destination_format')
-            self.destination_format_tags = config.get('ec2', 'destination_format_tags').split(',')
-        else:
-            self.destination_format = None
-            self.destination_format_tags = None
-
-        # Route53
-        self.route53_enabled = config.getboolean('ec2', 'route53')
-        self.route53_excluded_zones = []
-        if config.has_option('ec2', 'route53_excluded_zones'):
-            self.route53_excluded_zones.extend(
-                    config.get('ec2', 'route53_excluded_zones', '').split(','))
-
-        # Include RDS instances?
-        self.rds_enabled = True
-        if config.has_option('ec2', 'rds'):
-            self.rds_enabled = config.getboolean('ec2', 'rds')
-
-        # Include ElastiCache instances?
-        self.elasticache_enabled = True
-        if config.has_option('ec2', 'elasticache'):
-            self.elasticache_enabled = config.getboolean('ec2', 'elasticache')
-
-        # Return all EC2 instances?
-        if config.has_option('ec2', 'all_instances'):
-            self.all_instances = config.getboolean('ec2', 'all_instances')
-        else:
-            self.all_instances = False
-
-        # Instance states to be gathered in inventory. Default is 'running'.
-        # Setting 'all_instances' to 'yes' overrides this option.
-        ec2_valid_instance_states = [
-            'pending',
-            'running',
-            'shutting-down',
-            'terminated',
-            'stopping',
-            'stopped'
-        ]
-        self.ec2_instance_states = []
-        if self.all_instances:
-            self.ec2_instance_states = ec2_valid_instance_states
-        elif config.has_option('ec2', 'instance_states'):
-            for instance_state in config.get('ec2', 'instance_states').split(','):
-                instance_state = instance_state.strip()
-                if instance_state not in ec2_valid_instance_states:
-                    continue
-                self.ec2_instance_states.append(instance_state)
-        else:
-            self.ec2_instance_states = ['running']
-
-        # Return all RDS instances? (if RDS is enabled)
-        if config.has_option('ec2', 'all_rds_instances') and self.rds_enabled:
-            self.all_rds_instances = config.getboolean('ec2', 'all_rds_instances')
-        else:
-            self.all_rds_instances = False
-
-        # Return all ElastiCache replication groups? (if ElastiCache is enabled)
-        if config.has_option('ec2', 'all_elasticache_replication_groups') and self.elasticache_enabled:
-            self.all_elasticache_replication_groups = config.getboolean('ec2', 'all_elasticache_replication_groups')
-        else:
-            self.all_elasticache_replication_groups = False
-
-        # Return all ElastiCache clusters? (if ElastiCache is enabled)
-        if config.has_option('ec2', 'all_elasticache_clusters') and self.elasticache_enabled:
-            self.all_elasticache_clusters = config.getboolean('ec2', 'all_elasticache_clusters')
-        else:
-            self.all_elasticache_clusters = False
-
-        # Return all ElastiCache nodes? (if ElastiCache is enabled)
-        if config.has_option('ec2', 'all_elasticache_nodes') and self.elasticache_enabled:
-            self.all_elasticache_nodes = config.getboolean('ec2', 'all_elasticache_nodes')
-        else:
-            self.all_elasticache_nodes = False
-
-        # boto configuration profile (prefer CLI argument)
-        self.boto_profile = self.args.boto_profile
-        if config.has_option('ec2', 'boto_profile') and not self.boto_profile:
-            self.boto_profile = config.get('ec2', 'boto_profile')
-
-        # Cache related
-        cache_dir = os.path.expanduser(config.get('ec2', 'cache_path'))
-        if self.boto_profile:
-            cache_dir = os.path.join(cache_dir, 'profile_' + self.boto_profile)
-        if not os.path.exists(cache_dir):
-            os.makedirs(cache_dir)
-
-        cache_name = 'ansible-ec2'
-        aws_profile = lambda: (self.boto_profile or
-                               os.environ.get('AWS_PROFILE') or
-                               os.environ.get('AWS_ACCESS_KEY_ID'))
-        if aws_profile():
-            cache_name = '%s-%s' % (cache_name, aws_profile())
-        self.cache_path_cache = cache_dir + "/%s.cache" % cache_name
-        self.cache_path_index = cache_dir + "/%s.index" % cache_name
-        self.cache_max_age = config.getint('ec2', 'cache_max_age')
-
-        if config.has_option('ec2', 'expand_csv_tags'):
-            self.expand_csv_tags = config.getboolean('ec2', 'expand_csv_tags')
-        else:
-            self.expand_csv_tags = False
-
-        # Configure nested groups instead of flat namespace.
-        if config.has_option('ec2', 'nested_groups'):
-            self.nested_groups = config.getboolean('ec2', 'nested_groups')
-        else:
-            self.nested_groups = False
-
-        # Replace dash or not in group names
-        if config.has_option('ec2', 'replace_dash_in_groups'):
-            self.replace_dash_in_groups = config.getboolean('ec2', 'replace_dash_in_groups')
-        else:
-            self.replace_dash_in_groups = True
-
-        # Configure which groups should be created.
-        group_by_options = [
-            'group_by_instance_id',
-            'group_by_region',
-            'group_by_availability_zone',
-            'group_by_ami_id',
-            'group_by_instance_type',
-            'group_by_key_pair',
-            'group_by_vpc_id',
-            'group_by_security_group',
-            'group_by_tag_keys',
-            'group_by_tag_none',
-            'group_by_route53_names',
-            'group_by_rds_engine',
-            'group_by_rds_parameter_group',
-            'group_by_elasticache_engine',
-            'group_by_elasticache_cluster',
-            'group_by_elasticache_parameter_group',
-            'group_by_elasticache_replication_group',
-        ]
-        for option in group_by_options:
-            if config.has_option('ec2', option):
-                setattr(self, option, config.getboolean('ec2', option))
-            else:
-                setattr(self, option, True)
-
-        # Do we need to just include hosts that match a pattern?
-        try:
-            pattern_include = config.get('ec2', 'pattern_include')
-            if pattern_include and len(pattern_include) > 0:
-                self.pattern_include = re.compile(pattern_include)
-            else:
-                self.pattern_include = None
-        except configparser.NoOptionError:
-            self.pattern_include = None
-
-        # Do we need to exclude hosts that match a pattern?
-        try:
-            pattern_exclude = config.get('ec2', 'pattern_exclude');
-            if pattern_exclude and len(pattern_exclude) > 0:
-                self.pattern_exclude = re.compile(pattern_exclude)
-            else:
-                self.pattern_exclude = None
-        except configparser.NoOptionError:
-            self.pattern_exclude = None
-
-        # Instance filters (see boto and EC2 API docs). Ignore invalid filters.
-        self.ec2_instance_filters = defaultdict(list)
-        if config.has_option('ec2', 'instance_filters'):
-
-            filters = [f for f in config.get('ec2', 'instance_filters').split(',') if f]
-
-            for instance_filter in filters:
-                instance_filter = instance_filter.strip()
-                if not instance_filter or '=' not in instance_filter:
-                    continue
-                filter_key, filter_value = [x.strip() for x in instance_filter.split('=', 1)]
-                if not filter_key:
-                    continue
-                self.ec2_instance_filters[filter_key].append(filter_value)
-
-    def parse_cli_args(self):
-        ''' Command line argument processing '''
-
-        parser = argparse.ArgumentParser(description='Produce an Ansible Inventory file based on EC2')
-        parser.add_argument('--list', action='store_true', default=True,
-                            help='List instances (default: True)')
-        parser.add_argument('--host', action='store',
-                            help='Get all the variables about a specific instance')
-        parser.add_argument('--refresh-cache', action='store_true', default=False,
-                            help='Force refresh of cache by making API requests to EC2 (default: False - use cache files)')
-        parser.add_argument('--profile', '--boto-profile', action='store', dest='boto_profile',
-                            help='Use boto profile for connections to EC2')
-        self.args = parser.parse_args()
-
-
-    def do_api_calls_update_cache(self):
-        ''' Do API calls to each region, and save data in cache files '''
-
-        if self.route53_enabled:
-            self.get_route53_records()
-
-        for region in self.regions:
-            self.get_instances_by_region(region)
-            if self.rds_enabled:
-                self.get_rds_instances_by_region(region)
-            if self.elasticache_enabled:
-                self.get_elasticache_clusters_by_region(region)
-                self.get_elasticache_replication_groups_by_region(region)
-
-        self.write_to_cache(self.inventory, self.cache_path_cache)
-        self.write_to_cache(self.index, self.cache_path_index)
-
-    def connect(self, region):
-        ''' create connection to api server'''
-        if self.eucalyptus:
-            conn = boto.connect_euca(host=self.eucalyptus_host)
-            conn.APIVersion = '2010-08-31'
-        else:
-            conn = self.connect_to_aws(ec2, region)
-        return conn
-
-    def boto_fix_security_token_in_profile(self, connect_args):
-        ''' monkey patch for boto issue boto/boto#2100 '''
-        profile = 'profile ' + self.boto_profile
-        if boto.config.has_option(profile, 'aws_security_token'):
-            connect_args['security_token'] = boto.config.get(profile, 'aws_security_token')
-        return connect_args
-
-    def connect_to_aws(self, module, region):
-        connect_args = {}
-
-        # only pass the profile name if it's set (as it is not supported by older boto versions)
-        if self.boto_profile:
-            connect_args['profile_name'] = self.boto_profile
-            self.boto_fix_security_token_in_profile(connect_args)
-
-        conn = module.connect_to_region(region, **connect_args)
-        # connect_to_region will fail "silently" by returning None if the region name is wrong or not supported
-        if conn is None:
-            self.fail_with_error("region name: %s likely not supported, or AWS is down.  connection to region failed." % region)
-        return conn
-
-    def get_instances_by_region(self, region):
-        ''' Makes an AWS EC2 API call to the list of instances in a particular
-        region '''
-
-        try:
-            conn = self.connect(region)
-            reservations = []
-            if self.ec2_instance_filters:
-                for filter_key, filter_values in self.ec2_instance_filters.items():
-                    reservations.extend(conn.get_all_instances(filters = { filter_key : filter_values }))
-            else:
-                reservations = conn.get_all_instances()
-
-            for reservation in reservations:
-                for instance in reservation.instances:
-                    self.add_instance(instance, region)
-
-        except boto.exception.BotoServerError as e:
-            if e.error_code == 'AuthFailure':
-                error = self.get_auth_error_message()
-            else:
-                backend = 'Eucalyptus' if self.eucalyptus else 'AWS'
-                error = "Error connecting to %s backend.\n%s" % (backend, e.message)
-            self.fail_with_error(error, 'getting EC2 instances')
-
-    def get_rds_instances_by_region(self, region):
-        ''' Makes an AWS API call to the list of RDS instances in a particular
-        region '''
-
-        try:
-            conn = self.connect_to_aws(rds, region)
-            if conn:
-                marker = None
-                while True:
-                    instances = conn.get_all_dbinstances(marker=marker)
-                    marker = instances.marker
-                    for instance in instances:
-                        self.add_rds_instance(instance, region)
-                    if not marker:
-                        break
-        except boto.exception.BotoServerError as e:
-            error = e.reason
-
-            if e.error_code == 'AuthFailure':
-                error = self.get_auth_error_message()
-            if not e.reason == "Forbidden":
-                error = "Looks like AWS RDS is down:\n%s" % e.message
-            self.fail_with_error(error, 'getting RDS instances')
-
-    def get_elasticache_clusters_by_region(self, region):
-        ''' Makes an AWS API call to the list of ElastiCache clusters (with
-        nodes' info) in a particular region.'''
-
-        # ElastiCache boto module doesn't provide a get_all_intances method,
-        # that's why we need to call describe directly (it would be called by
-        # the shorthand method anyway...)
-        try:
-            conn = self.connect_to_aws(elasticache, region)
-            if conn:
-                # show_cache_node_info = True
-                # because we also want nodes' information
-                response = conn.describe_cache_clusters(None, None, None, True)
-
-        except boto.exception.BotoServerError as e:
-            error = e.reason
-
-            if e.error_code == 'AuthFailure':
-                error = self.get_auth_error_message()
-            if not e.reason == "Forbidden":
-                error = "Looks like AWS ElastiCache is down:\n%s" % e.message
-            self.fail_with_error(error, 'getting ElastiCache clusters')
-
-        try:
-            # Boto also doesn't provide wrapper classes to CacheClusters or
-            # CacheNodes. Because of that wo can't make use of the get_list
-            # method in the AWSQueryConnection. Let's do the work manually
-            clusters = response['DescribeCacheClustersResponse']['DescribeCacheClustersResult']['CacheClusters']
-
-        except KeyError as e:
-            error = "ElastiCache query to AWS failed (unexpected format)."
-            self.fail_with_error(error, 'getting ElastiCache clusters')
-
-        for cluster in clusters:
-            self.add_elasticache_cluster(cluster, region)
-
-    def get_elasticache_replication_groups_by_region(self, region):
-        ''' Makes an AWS API call to the list of ElastiCache replication groups
-        in a particular region.'''
-
-        # ElastiCache boto module doesn't provide a get_all_intances method,
-        # that's why we need to call describe directly (it would be called by
-        # the shorthand method anyway...)
-        try:
-            conn = self.connect_to_aws(elasticache, region)
-            if conn:
-                response = conn.describe_replication_groups()
-
-        except boto.exception.BotoServerError as e:
-            error = e.reason
-
-            if e.error_code == 'AuthFailure':
-                error = self.get_auth_error_message()
-            if not e.reason == "Forbidden":
-                error = "Looks like AWS ElastiCache [Replication Groups] is down:\n%s" % e.message
-            self.fail_with_error(error, 'getting ElastiCache clusters')
-
-        try:
-            # Boto also doesn't provide wrapper classes to ReplicationGroups
-            # Because of that wo can't make use of the get_list method in the
-            # AWSQueryConnection. Let's do the work manually
-            replication_groups = response['DescribeReplicationGroupsResponse']['DescribeReplicationGroupsResult']['ReplicationGroups']
-
-        except KeyError as e:
-            error = "ElastiCache [Replication Groups] query to AWS failed (unexpected format)."
-            self.fail_with_error(error, 'getting ElastiCache clusters')
-
-        for replication_group in replication_groups:
-            self.add_elasticache_replication_group(replication_group, region)
-
-    def get_auth_error_message(self):
-        ''' create an informative error message if there is an issue authenticating'''
-        errors = ["Authentication error retrieving ec2 inventory."]
-        if None in [os.environ.get('AWS_ACCESS_KEY_ID'), os.environ.get('AWS_SECRET_ACCESS_KEY')]:
-            errors.append(' - No AWS_ACCESS_KEY_ID or AWS_SECRET_ACCESS_KEY environment vars found')
-        else:
-            errors.append(' - AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY environment vars found but may not be correct')
-
-        boto_paths = ['/etc/boto.cfg', '~/.boto', '~/.aws/credentials']
-        boto_config_found = list(p for p in boto_paths if os.path.isfile(os.path.expanduser(p)))
-        if len(boto_config_found) > 0:
-            errors.append(" - Boto configs found at '%s', but the credentials contained may not be correct" % ', '.join(boto_config_found))
-        else:
-            errors.append(" - No Boto config found at any expected location '%s'" % ', '.join(boto_paths))
-
-        return '\n'.join(errors)
-
-    def fail_with_error(self, err_msg, err_operation=None):
-        '''log an error to std err for ansible-playbook to consume and exit'''
-        if err_operation:
-            err_msg = 'ERROR: "{err_msg}", while: {err_operation}'.format(
-                    err_msg=err_msg, err_operation=err_operation)
-        sys.stderr.write(err_msg)
-        sys.exit(1)
-
-    def get_instance(self, region, instance_id):
-        conn = self.connect(region)
-
-        reservations = conn.get_all_instances([instance_id])
-        for reservation in reservations:
-            for instance in reservation.instances:
-                return instance
-
-    def add_instance(self, instance, region):
-        ''' Adds an instance to the inventory and index, as long as it is
-        addressable '''
-
-        # Only return instances with desired instance states
-        if instance.state not in self.ec2_instance_states:
-            return
-
-        # Select the best destination address
-        if self.destination_format and self.destination_format_tags:
-            dest = self.destination_format.format(*[ getattr(instance, 'tags').get(tag, '') for tag in self.destination_format_tags ])
-        elif instance.subnet_id:
-            dest = getattr(instance, self.vpc_destination_variable, None)
-            if dest is None:
-                dest = getattr(instance, 'tags').get(self.vpc_destination_variable, None)
-        else:
-            dest = getattr(instance, self.destination_variable, None)
-            if dest is None:
-                dest = getattr(instance, 'tags').get(self.destination_variable, None)
-
-        if not dest:
-            # Skip instances we cannot address (e.g. private VPC subnet)
-            return
-
-        # Set the inventory name
-        hostname = None
-        if self.hostname_variable:
-            if self.hostname_variable.startswith('tag_'):
-                hostname = instance.tags.get(self.hostname_variable[4:], None)
-            else:
-                hostname = getattr(instance, self.hostname_variable)
-
-        # If we can't get a nice hostname, use the destination address
-        if not hostname:
-            hostname = dest
-        else:
-            hostname = self.to_safe(hostname).lower()
-
-        # if we only want to include hosts that match a pattern, skip those that don't
-        if self.pattern_include and not self.pattern_include.match(hostname):
-            return
-
-        # if we need to exclude hosts that match a pattern, skip those
-        if self.pattern_exclude and self.pattern_exclude.match(hostname):
-            return
-
-        # Add to index
-        self.index[hostname] = [region, instance.id]
-
-        # Inventory: Group by instance ID (always a group of 1)
-        if self.group_by_instance_id:
-            self.inventory[instance.id] = [hostname]
-            if self.nested_groups:
-                self.push_group(self.inventory, 'instances', instance.id)
-
-        # Inventory: Group by region
-        if self.group_by_region:
-            self.push(self.inventory, region, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'regions', region)
-
-        # Inventory: Group by availability zone
-        if self.group_by_availability_zone:
-            self.push(self.inventory, instance.placement, hostname)
-            if self.nested_groups:
-                if self.group_by_region:
-                    self.push_group(self.inventory, region, instance.placement)
-                self.push_group(self.inventory, 'zones', instance.placement)
-
-        # Inventory: Group by Amazon Machine Image (AMI) ID
-        if self.group_by_ami_id:
-            ami_id = self.to_safe(instance.image_id)
-            self.push(self.inventory, ami_id, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'images', ami_id)
-
-        # Inventory: Group by instance type
-        if self.group_by_instance_type:
-            type_name = self.to_safe('type_' + instance.instance_type)
-            self.push(self.inventory, type_name, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'types', type_name)
-
-        # Inventory: Group by key pair
-        if self.group_by_key_pair and instance.key_name:
-            key_name = self.to_safe('key_' + instance.key_name)
-            self.push(self.inventory, key_name, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'keys', key_name)
-
-        # Inventory: Group by VPC
-        if self.group_by_vpc_id and instance.vpc_id:
-            vpc_id_name = self.to_safe('vpc_id_' + instance.vpc_id)
-            self.push(self.inventory, vpc_id_name, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'vpcs', vpc_id_name)
-
-        # Inventory: Group by security group
-        if self.group_by_security_group:
-            try:
-                for group in instance.groups:
-                    key = self.to_safe("security_group_" + group.name)
-                    self.push(self.inventory, key, hostname)
-                    if self.nested_groups:
-                        self.push_group(self.inventory, 'security_groups', key)
-            except AttributeError:
-                self.fail_with_error('\n'.join(['Package boto seems a bit older.',
-                                                'Please upgrade boto >= 2.3.0.']))
-
-        # Inventory: Group by tag keys
-        if self.group_by_tag_keys:
-            for k, v in instance.tags.items():
-                if self.expand_csv_tags and v and ',' in v:
-                    values = map(lambda x: x.strip(), v.split(','))
-                else:
-                    values = [v]
-
-                for v in values:
-                    if v:
-                        key = self.to_safe("tag_" + k + "=" + v)
-                    else:
-                        key = self.to_safe("tag_" + k)
-                    self.push(self.inventory, key, hostname)
-                    if self.nested_groups:
-                        self.push_group(self.inventory, 'tags', self.to_safe("tag_" + k))
-                        if v:
-                            self.push_group(self.inventory, self.to_safe("tag_" + k), key)
-
-        # Inventory: Group by Route53 domain names if enabled
-        if self.route53_enabled and self.group_by_route53_names:
-            route53_names = self.get_instance_route53_names(instance)
-            for name in route53_names:
-                self.push(self.inventory, name, hostname)
-                if self.nested_groups:
-                    self.push_group(self.inventory, 'route53', name)
-
-        # Global Tag: instances without tags
-        if self.group_by_tag_none and len(instance.tags) == 0:
-            self.push(self.inventory, 'tag_none', hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'tags', 'tag_none')
-
-        # Global Tag: tag all EC2 instances
-        self.push(self.inventory, 'ec2', hostname)
-
-        self.inventory["_meta"]["hostvars"][hostname] = self.get_host_info_dict_from_instance(instance)
-        self.inventory["_meta"]["hostvars"][hostname]['ansible_ssh_host'] = dest
-
-
-    def add_rds_instance(self, instance, region):
-        ''' Adds an RDS instance to the inventory and index, as long as it is
-        addressable '''
-
-        # Only want available instances unless all_rds_instances is True
-        if not self.all_rds_instances and instance.status != 'available':
-            return
-
-        # Select the best destination address
-        dest = instance.endpoint[0]
-
-        if not dest:
-            # Skip instances we cannot address (e.g. private VPC subnet)
-            return
-
-        # Set the inventory name
-        hostname = None
-        if self.hostname_variable:
-            if self.hostname_variable.startswith('tag_'):
-                hostname = instance.tags.get(self.hostname_variable[4:], None)
-            else:
-                hostname = getattr(instance, self.hostname_variable)
-
-        # If we can't get a nice hostname, use the destination address
-        if not hostname:
-            hostname = dest
-
-        hostname = self.to_safe(hostname).lower()
-
-        # Add to index
-        self.index[hostname] = [region, instance.id]
-
-        # Inventory: Group by instance ID (always a group of 1)
-        if self.group_by_instance_id:
-            self.inventory[instance.id] = [hostname]
-            if self.nested_groups:
-                self.push_group(self.inventory, 'instances', instance.id)
-
-        # Inventory: Group by region
-        if self.group_by_region:
-            self.push(self.inventory, region, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'regions', region)
-
-        # Inventory: Group by availability zone
-        if self.group_by_availability_zone:
-            self.push(self.inventory, instance.availability_zone, hostname)
-            if self.nested_groups:
-                if self.group_by_region:
-                    self.push_group(self.inventory, region, instance.availability_zone)
-                self.push_group(self.inventory, 'zones', instance.availability_zone)
-
-        # Inventory: Group by instance type
-        if self.group_by_instance_type:
-            type_name = self.to_safe('type_' + instance.instance_class)
-            self.push(self.inventory, type_name, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'types', type_name)
-
-        # Inventory: Group by VPC
-        if self.group_by_vpc_id and instance.subnet_group and instance.subnet_group.vpc_id:
-            vpc_id_name = self.to_safe('vpc_id_' + instance.subnet_group.vpc_id)
-            self.push(self.inventory, vpc_id_name, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'vpcs', vpc_id_name)
-
-        # Inventory: Group by security group
-        if self.group_by_security_group:
-            try:
-                if instance.security_group:
-                    key = self.to_safe("security_group_" + instance.security_group.name)
-                    self.push(self.inventory, key, hostname)
-                    if self.nested_groups:
-                        self.push_group(self.inventory, 'security_groups', key)
-
-            except AttributeError:
-                self.fail_with_error('\n'.join(['Package boto seems a bit older.',
-                                                'Please upgrade boto >= 2.3.0.']))
-
-
-        # Inventory: Group by engine
-        if self.group_by_rds_engine:
-            self.push(self.inventory, self.to_safe("rds_" + instance.engine), hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'rds_engines', self.to_safe("rds_" + instance.engine))
-
-        # Inventory: Group by parameter group
-        if self.group_by_rds_parameter_group:
-            self.push(self.inventory, self.to_safe("rds_parameter_group_" + instance.parameter_group.name), hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'rds_parameter_groups', self.to_safe("rds_parameter_group_" + instance.parameter_group.name))
-
-        # Global Tag: all RDS instances
-        self.push(self.inventory, 'rds', hostname)
-
-        self.inventory["_meta"]["hostvars"][hostname] = self.get_host_info_dict_from_instance(instance)
-        self.inventory["_meta"]["hostvars"][hostname]['ansible_ssh_host'] = dest
-
-    def add_elasticache_cluster(self, cluster, region):
-        ''' Adds an ElastiCache cluster to the inventory and index, as long as
-        it's nodes are addressable '''
-
-        # Only want available clusters unless all_elasticache_clusters is True
-        if not self.all_elasticache_clusters and cluster['CacheClusterStatus'] != 'available':
-            return
-
-        # Select the best destination address
-        if 'ConfigurationEndpoint' in cluster and cluster['ConfigurationEndpoint']:
-            # Memcached cluster
-            dest = cluster['ConfigurationEndpoint']['Address']
-            is_redis = False
-        else:
-            # Redis sigle node cluster
-            # Because all Redis clusters are single nodes, we'll merge the
-            # info from the cluster with info about the node
-            dest = cluster['CacheNodes'][0]['Endpoint']['Address']
-            is_redis = True
-
-        if not dest:
-            # Skip clusters we cannot address (e.g. private VPC subnet)
-            return
-
-        # Add to index
-        self.index[dest] = [region, cluster['CacheClusterId']]
-
-        # Inventory: Group by instance ID (always a group of 1)
-        if self.group_by_instance_id:
-            self.inventory[cluster['CacheClusterId']] = [dest]
-            if self.nested_groups:
-                self.push_group(self.inventory, 'instances', cluster['CacheClusterId'])
-
-        # Inventory: Group by region
-        if self.group_by_region and not is_redis:
-            self.push(self.inventory, region, dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'regions', region)
-
-        # Inventory: Group by availability zone
-        if self.group_by_availability_zone and not is_redis:
-            self.push(self.inventory, cluster['PreferredAvailabilityZone'], dest)
-            if self.nested_groups:
-                if self.group_by_region:
-                    self.push_group(self.inventory, region, cluster['PreferredAvailabilityZone'])
-                self.push_group(self.inventory, 'zones', cluster['PreferredAvailabilityZone'])
-
-        # Inventory: Group by node type
-        if self.group_by_instance_type and not is_redis:
-            type_name = self.to_safe('type_' + cluster['CacheNodeType'])
-            self.push(self.inventory, type_name, dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'types', type_name)
-
-        # Inventory: Group by VPC (information not available in the current
-        # AWS API version for ElastiCache)
-
-        # Inventory: Group by security group
-        if self.group_by_security_group and not is_redis:
-
-            # Check for the existence of the 'SecurityGroups' key and also if
-            # this key has some value. When the cluster is not placed in a SG
-            # the query can return None here and cause an error.
-            if 'SecurityGroups' in cluster and cluster['SecurityGroups'] is not None:
-                for security_group in cluster['SecurityGroups']:
-                    key = self.to_safe("security_group_" + security_group['SecurityGroupId'])
-                    self.push(self.inventory, key, dest)
-                    if self.nested_groups:
-                        self.push_group(self.inventory, 'security_groups', key)
-
-        # Inventory: Group by engine
-        if self.group_by_elasticache_engine and not is_redis:
-            self.push(self.inventory, self.to_safe("elasticache_" + cluster['Engine']), dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'elasticache_engines', self.to_safe(cluster['Engine']))
-
-        # Inventory: Group by parameter group
-        if self.group_by_elasticache_parameter_group:
-            self.push(self.inventory, self.to_safe("elasticache_parameter_group_" + cluster['CacheParameterGroup']['CacheParameterGroupName']), dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'elasticache_parameter_groups', self.to_safe(cluster['CacheParameterGroup']['CacheParameterGroupName']))
-
-        # Inventory: Group by replication group
-        if self.group_by_elasticache_replication_group and 'ReplicationGroupId' in cluster and cluster['ReplicationGroupId']:
-            self.push(self.inventory, self.to_safe("elasticache_replication_group_" + cluster['ReplicationGroupId']), dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'elasticache_replication_groups', self.to_safe(cluster['ReplicationGroupId']))
-
-        # Global Tag: all ElastiCache clusters
-        self.push(self.inventory, 'elasticache_clusters', cluster['CacheClusterId'])
-
-        host_info = self.get_host_info_dict_from_describe_dict(cluster)
-
-        self.inventory["_meta"]["hostvars"][dest] = host_info
-
-        # Add the nodes
-        for node in cluster['CacheNodes']:
-            self.add_elasticache_node(node, cluster, region)
-
-    def add_elasticache_node(self, node, cluster, region):
-        ''' Adds an ElastiCache node to the inventory and index, as long as
-        it is addressable '''
-
-        # Only want available nodes unless all_elasticache_nodes is True
-        if not self.all_elasticache_nodes and node['CacheNodeStatus'] != 'available':
-            return
-
-        # Select the best destination address
-        dest = node['Endpoint']['Address']
-
-        if not dest:
-            # Skip nodes we cannot address (e.g. private VPC subnet)
-            return
-
-        node_id = self.to_safe(cluster['CacheClusterId'] + '_' + node['CacheNodeId'])
-
-        # Add to index
-        self.index[dest] = [region, node_id]
-
-        # Inventory: Group by node ID (always a group of 1)
-        if self.group_by_instance_id:
-            self.inventory[node_id] = [dest]
-            if self.nested_groups:
-                self.push_group(self.inventory, 'instances', node_id)
-
-        # Inventory: Group by region
-        if self.group_by_region:
-            self.push(self.inventory, region, dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'regions', region)
-
-        # Inventory: Group by availability zone
-        if self.group_by_availability_zone:
-            self.push(self.inventory, cluster['PreferredAvailabilityZone'], dest)
-            if self.nested_groups:
-                if self.group_by_region:
-                    self.push_group(self.inventory, region, cluster['PreferredAvailabilityZone'])
-                self.push_group(self.inventory, 'zones', cluster['PreferredAvailabilityZone'])
-
-        # Inventory: Group by node type
-        if self.group_by_instance_type:
-            type_name = self.to_safe('type_' + cluster['CacheNodeType'])
-            self.push(self.inventory, type_name, dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'types', type_name)
-
-        # Inventory: Group by VPC (information not available in the current
-        # AWS API version for ElastiCache)
-
-        # Inventory: Group by security group
-        if self.group_by_security_group:
-
-            # Check for the existence of the 'SecurityGroups' key and also if
-            # this key has some value. When the cluster is not placed in a SG
-            # the query can return None here and cause an error.
-            if 'SecurityGroups' in cluster and cluster['SecurityGroups'] is not None:
-                for security_group in cluster['SecurityGroups']:
-                    key = self.to_safe("security_group_" + security_group['SecurityGroupId'])
-                    self.push(self.inventory, key, dest)
-                    if self.nested_groups:
-                        self.push_group(self.inventory, 'security_groups', key)
-
-        # Inventory: Group by engine
-        if self.group_by_elasticache_engine:
-            self.push(self.inventory, self.to_safe("elasticache_" + cluster['Engine']), dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'elasticache_engines', self.to_safe("elasticache_" + cluster['Engine']))
-
-        # Inventory: Group by parameter group (done at cluster level)
-
-        # Inventory: Group by replication group (done at cluster level)
-
-        # Inventory: Group by ElastiCache Cluster
-        if self.group_by_elasticache_cluster:
-            self.push(self.inventory, self.to_safe("elasticache_cluster_" + cluster['CacheClusterId']), dest)
-
-        # Global Tag: all ElastiCache nodes
-        self.push(self.inventory, 'elasticache_nodes', dest)
-
-        host_info = self.get_host_info_dict_from_describe_dict(node)
-
-        if dest in self.inventory["_meta"]["hostvars"]:
-            self.inventory["_meta"]["hostvars"][dest].update(host_info)
-        else:
-            self.inventory["_meta"]["hostvars"][dest] = host_info
-
-    def add_elasticache_replication_group(self, replication_group, region):
-        ''' Adds an ElastiCache replication group to the inventory and index '''
-
-        # Only want available clusters unless all_elasticache_replication_groups is True
-        if not self.all_elasticache_replication_groups and replication_group['Status'] != 'available':
-            return
-
-        # Select the best destination address (PrimaryEndpoint)
-        dest = replication_group['NodeGroups'][0]['PrimaryEndpoint']['Address']
-
-        if not dest:
-            # Skip clusters we cannot address (e.g. private VPC subnet)
-            return
-
-        # Add to index
-        self.index[dest] = [region, replication_group['ReplicationGroupId']]
-
-        # Inventory: Group by ID (always a group of 1)
-        if self.group_by_instance_id:
-            self.inventory[replication_group['ReplicationGroupId']] = [dest]
-            if self.nested_groups:
-                self.push_group(self.inventory, 'instances', replication_group['ReplicationGroupId'])
-
-        # Inventory: Group by region
-        if self.group_by_region:
-            self.push(self.inventory, region, dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'regions', region)
-
-        # Inventory: Group by availability zone (doesn't apply to replication groups)
-
-        # Inventory: Group by node type (doesn't apply to replication groups)
-
-        # Inventory: Group by VPC (information not available in the current
-        # AWS API version for replication groups
-
-        # Inventory: Group by security group (doesn't apply to replication groups)
-        # Check this value in cluster level
-
-        # Inventory: Group by engine (replication groups are always Redis)
-        if self.group_by_elasticache_engine:
-            self.push(self.inventory, 'elasticache_redis', dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'elasticache_engines', 'redis')
-
-        # Global Tag: all ElastiCache clusters
-        self.push(self.inventory, 'elasticache_replication_groups', replication_group['ReplicationGroupId'])
-
-        host_info = self.get_host_info_dict_from_describe_dict(replication_group)
-
-        self.inventory["_meta"]["hostvars"][dest] = host_info
-
-    def get_route53_records(self):
-        ''' Get and store the map of resource records to domain names that
-        point to them. '''
-
-        r53_conn = route53.Route53Connection()
-        all_zones = r53_conn.get_zones()
-
-        route53_zones = [ zone for zone in all_zones if zone.name[:-1]
-                          not in self.route53_excluded_zones ]
-
-        self.route53_records = {}
-
-        for zone in route53_zones:
-            rrsets = r53_conn.get_all_rrsets(zone.id)
-
-            for record_set in rrsets:
-                record_name = record_set.name
-
-                if record_name.endswith('.'):
-                    record_name = record_name[:-1]
-
-                for resource in record_set.resource_records:
-                    self.route53_records.setdefault(resource, set())
-                    self.route53_records[resource].add(record_name)
-
-
-    def get_instance_route53_names(self, instance):
-        ''' Check if an instance is referenced in the records we have from
-        Route53. If it is, return the list of domain names pointing to said
-        instance. If nothing points to it, return an empty list. '''
-
-        instance_attributes = [ 'public_dns_name', 'private_dns_name',
-                                'ip_address', 'private_ip_address' ]
-
-        name_list = set()
-
-        for attrib in instance_attributes:
-            try:
-                value = getattr(instance, attrib)
-            except AttributeError:
-                continue
-
-            if value in self.route53_records:
-                name_list.update(self.route53_records[value])
-
-        return list(name_list)
-
-    def get_host_info_dict_from_instance(self, instance):
-        instance_vars = {}
-        for key in vars(instance):
-            value = getattr(instance, key)
-            key = self.to_safe('ec2_' + key)
-
-            # Handle complex types
-            # state/previous_state changed to properties in boto in https://github.com/boto/boto/commit/a23c379837f698212252720d2af8dec0325c9518
-            if key == 'ec2__state':
-                instance_vars['ec2_state'] = instance.state or ''
-                instance_vars['ec2_state_code'] = instance.state_code
-            elif key == 'ec2__previous_state':
-                instance_vars['ec2_previous_state'] = instance.previous_state or ''
-                instance_vars['ec2_previous_state_code'] = instance.previous_state_code
-            elif type(value) in [int, bool]:
-                instance_vars[key] = value
-            elif isinstance(value, six.string_types):
-                instance_vars[key] = value.strip()
-            elif type(value) == type(None):
-                instance_vars[key] = ''
-            elif key == 'ec2_region':
-                instance_vars[key] = value.name
-            elif key == 'ec2__placement':
-                instance_vars['ec2_placement'] = value.zone
-            elif key == 'ec2_tags':
-                for k, v in value.items():
-                    if self.expand_csv_tags and ',' in v:
-                        v = map(lambda x: x.strip(), v.split(','))
-                    key = self.to_safe('ec2_tag_' + k)
-                    instance_vars[key] = v
-            elif key == 'ec2_groups':
-                group_ids = []
-                group_names = []
-                for group in value:
-                    group_ids.append(group.id)
-                    group_names.append(group.name)
-                instance_vars["ec2_security_group_ids"] = ','.join([str(i) for i in group_ids])
-                instance_vars["ec2_security_group_names"] = ','.join([str(i) for i in group_names])
-            else:
-                pass
-                # TODO Product codes if someone finds them useful
-                #print key
-                #print type(value)
-                #print value
-
-        return instance_vars
-
-    def get_host_info_dict_from_describe_dict(self, describe_dict):
-        ''' Parses the dictionary returned by the API call into a flat list
-            of parameters. This method should be used only when 'describe' is
-            used directly because Boto doesn't provide specific classes. '''
-
-        # I really don't agree with prefixing everything with 'ec2'
-        # because EC2, RDS and ElastiCache are different services.
-        # I'm just following the pattern used until now to not break any
-        # compatibility.
-
-        host_info = {}
-        for key in describe_dict:
-            value = describe_dict[key]
-            key = self.to_safe('ec2_' + self.uncammelize(key))
-
-            # Handle complex types
-
-            # Target: Memcached Cache Clusters
-            if key == 'ec2_configuration_endpoint' and value:
-                host_info['ec2_configuration_endpoint_address'] = value['Address']
-                host_info['ec2_configuration_endpoint_port'] = value['Port']
-
-            # Target: Cache Nodes and Redis Cache Clusters (single node)
-            if key == 'ec2_endpoint' and value:
-                host_info['ec2_endpoint_address'] = value['Address']
-                host_info['ec2_endpoint_port'] = value['Port']
-
-            # Target: Redis Replication Groups
-            if key == 'ec2_node_groups' and value:
-                host_info['ec2_endpoint_address'] = value[0]['PrimaryEndpoint']['Address']
-                host_info['ec2_endpoint_port'] = value[0]['PrimaryEndpoint']['Port']
-                replica_count = 0
-                for node in value[0]['NodeGroupMembers']:
-                    if node['CurrentRole'] == 'primary':
-                        host_info['ec2_primary_cluster_address'] = node['ReadEndpoint']['Address']
-                        host_info['ec2_primary_cluster_port'] = node['ReadEndpoint']['Port']
-                        host_info['ec2_primary_cluster_id'] = node['CacheClusterId']
-                    elif node['CurrentRole'] == 'replica':
-                        host_info['ec2_replica_cluster_address_'+ str(replica_count)] = node['ReadEndpoint']['Address']
-                        host_info['ec2_replica_cluster_port_'+ str(replica_count)] = node['ReadEndpoint']['Port']
-                        host_info['ec2_replica_cluster_id_'+ str(replica_count)] = node['CacheClusterId']
-                        replica_count += 1
-
-            # Target: Redis Replication Groups
-            if key == 'ec2_member_clusters' and value:
-                host_info['ec2_member_clusters'] = ','.join([str(i) for i in value])
-
-            # Target: All Cache Clusters
-            elif key == 'ec2_cache_parameter_group':
-                host_info["ec2_cache_node_ids_to_reboot"] = ','.join([str(i) for i in value['CacheNodeIdsToReboot']])
-                host_info['ec2_cache_parameter_group_name'] = value['CacheParameterGroupName']
-                host_info['ec2_cache_parameter_apply_status'] = value['ParameterApplyStatus']
-
-            # Target: Almost everything
-            elif key == 'ec2_security_groups':
-
-                # Skip if SecurityGroups is None
-                # (it is possible to have the key defined but no value in it).
-                if value is not None:
-                    sg_ids = []
-                    for sg in value:
-                        sg_ids.append(sg['SecurityGroupId'])
-                    host_info["ec2_security_group_ids"] = ','.join([str(i) for i in sg_ids])
-
-            # Target: Everything
-            # Preserve booleans and integers
-            elif type(value) in [int, bool]:
-                host_info[key] = value
-
-            # Target: Everything
-            # Sanitize string values
-            elif isinstance(value, six.string_types):
-                host_info[key] = value.strip()
-
-            # Target: Everything
-            # Replace None by an empty string
-            elif type(value) == type(None):
-                host_info[key] = ''
-
-            else:
-                # Remove non-processed complex types
-                pass
-
-        return host_info
-
-    def get_host_info(self):
-        ''' Get variables about a specific host '''
-
-        if len(self.index) == 0:
-            # Need to load index from cache
-            self.load_index_from_cache()
-
-        if not self.args.host in self.index:
-            # try updating the cache
-            self.do_api_calls_update_cache()
-            if not self.args.host in self.index:
-                # host might not exist anymore
-                return self.json_format_dict({}, True)
-
-        (region, instance_id) = self.index[self.args.host]
-
-        instance = self.get_instance(region, instance_id)
-        return self.json_format_dict(self.get_host_info_dict_from_instance(instance), True)
-
-    def push(self, my_dict, key, element):
-        ''' Push an element onto an array that may not have been defined in
-        the dict '''
-        group_info = my_dict.setdefault(key, [])
-        if isinstance(group_info, dict):
-            host_list = group_info.setdefault('hosts', [])
-            host_list.append(element)
-        else:
-            group_info.append(element)
-
-    def push_group(self, my_dict, key, element):
-        ''' Push a group as a child of another group. '''
-        parent_group = my_dict.setdefault(key, {})
-        if not isinstance(parent_group, dict):
-            parent_group = my_dict[key] = {'hosts': parent_group}
-        child_groups = parent_group.setdefault('children', [])
-        if element not in child_groups:
-            child_groups.append(element)
-
-    def get_inventory_from_cache(self):
-        ''' Reads the inventory from the cache file and returns it as a JSON
-        object '''
-
-        cache = open(self.cache_path_cache, 'r')
-        json_inventory = cache.read()
-        return json_inventory
-
-
-    def load_index_from_cache(self):
-        ''' Reads the index from the cache file sets self.index '''
-
-        cache = open(self.cache_path_index, 'r')
-        json_index = cache.read()
-        self.index = json.loads(json_index)
-
-
-    def write_to_cache(self, data, filename):
-        ''' Writes data in JSON format to a file '''
-
-        json_data = self.json_format_dict(data, True)
-        cache = open(filename, 'w')
-        cache.write(json_data)
-        cache.close()
-
-    def uncammelize(self, key):
-        temp = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', key)
-        return re.sub('([a-z0-9])([A-Z])', r'\1_\2', temp).lower()
-
-    def to_safe(self, word):
-        ''' Converts 'bad' characters in a string to underscores so they can be used as Ansible groups '''
-        regex = "[^A-Za-z0-9\_"
-        if not self.replace_dash_in_groups:
-            regex += "\-"
-        return re.sub(regex + "]", "_", word)
-
-    def json_format_dict(self, data, pretty=False):
-        ''' Converts a dict to a JSON object and dumps it as a formatted
-        string '''
-
-        if pretty:
-            return json.dumps(data, sort_keys=True, indent=2)
-        else:
-            return json.dumps(data)
-
-
-# Run the script
-Ec2Inventory()
diff --git a/edge-1605-dc3/inventory b/edge-1605-dc3/inventory
deleted file mode 100644
index 63fe321..0000000
--- a/edge-1605-dc3/inventory
+++ /dev/null
@@ -1,78 +0,0 @@
-[tag_Name_dc3_n1]
-[tag_Name_dc3_n2]
-[tag_Name_dc3_n3]
-[tag_Name_dc3_n4]
-[tag_Name_dc3_n5]
-[tag_Name_dc3_n6]
-
-[planet:children]
-dc-1
-
-[dc-1:children]
-tag_Name_dc3_n1
-tag_Name_dc3_n2
-tag_Name_dc3_n3
-tag_Name_dc3_n4
-tag_Name_dc3_n5
-
-[ds:children]
-dc-1-ds
-
-[dc-1-ds:children]
-tag_Name_dc3_n1
-tag_Name_dc3_n2
-tag_Name_dc3_n3
-
-[ms:children]
-dc-1-ms
-
-[dc-1-ms:children]
-tag_Name_dc3_n1
-
-[ui:children]
-dc-1-ui
-
-[dc-1-ui:children]
-tag_Name_dc3_n1
-
-[ldap:children]
-dc-1-ldap
-
-[dc-1-ldap:children]
-tag_Name_dc3_n1
-
-[rmp:children]
-dc-1-rmp
-
-[dc-1-rmp:children]
-tag_Name_dc3_n3
-tag_Name_dc3_n4
-
-[qpid:children]
-dc-1-qpid
-
-[dc-1-qpid:children]
-tag_Name_dc3_n4
-tag_Name_dc3_n5
-
-[pg:children]
-dc-1-pg
-
-[dc-1-pg:children]
-dc-1-pgmaster
-dc-1-pgstandby
-
-[pgmaster:children]
-dc-1-pgmaster
-
-[dc-1-pgmaster:children]
-tag_Name_dc3_n4
-
-[pgstandby:children]
-dc-1-pgstandby
-
-[dc-1-pgstandby:children]
-tag_Name_dc3_n5
-
-[mirror:children]
-tag_Name_dc3_n6
\ No newline at end of file
diff --git a/edge-1609-dc2/ec2.ini b/edge-1609-dc2/ec2.ini
deleted file mode 100644
index 36b3921..0000000
--- a/edge-1609-dc2/ec2.ini
+++ /dev/null
@@ -1,200 +0,0 @@
-# Ansible EC2 external inventory script settings
-#
-
-[ec2]
-
-# to talk to a private eucalyptus instance uncomment these lines
-# and edit edit eucalyptus_host to be the host name of your cloud controller
-#eucalyptus = True
-#eucalyptus_host = clc.cloud.domain.org
-
-# AWS regions to make calls to. Set this to 'all' to make request to all regions
-# in AWS and merge the results together. Alternatively, set this to a comma
-# separated list of regions. E.g. 'us-east-1,us-west-1,us-west-2'
-regions = all
-regions_exclude = us-gov-west-1,cn-north-1
-
-# When generating inventory, Ansible needs to know how to address a server.
-# Each EC2 instance has a lot of variables associated with it. Here is the list:
-#   http://docs.pythonboto.org/en/latest/ref/ec2.html#module-boto.ec2.instance
-# Below are 2 variables that are used as the address of a server:
-#   - destination_variable
-#   - vpc_destination_variable
-
-# This is the normal destination variable to use. If you are running Ansible
-# from outside EC2, then 'public_dns_name' makes the most sense. If you are
-# running Ansible from within EC2, then perhaps you want to use the internal
-# address, and should set this to 'private_dns_name'. The key of an EC2 tag
-# may optionally be used; however the boto instance variables hold precedence
-# in the event of a collision.
-destination_variable = public_dns_name
-
-# This allows you to override the inventory_name with an ec2 variable, instead
-# of using the destination_variable above. Addressing (aka ansible_ssh_host)
-# will still use destination_variable. Tags should be written as 'tag_TAGNAME'.
-#hostname_variable = tag_Name
-
-# For server inside a VPC, using DNS names may not make sense. When an instance
-# has 'subnet_id' set, this variable is used. If the subnet is public, setting
-# this to 'ip_address' will return the public IP address. For instances in a
-# private subnet, this should be set to 'private_ip_address', and Ansible must
-# be run from within EC2. The key of an EC2 tag may optionally be used; however
-# the boto instance variables hold precedence in the event of a collision.
-# WARNING: - instances that are in the private vpc, _without_ public ip address
-# will not be listed in the inventory until You set:
-# vpc_destination_variable = private_ip_address
-vpc_destination_variable = ip_address
-
-# The following two settings allow flexible ansible host naming based on a
-# python format string and a comma-separated list of ec2 tags.  Note that:
-#
-# 1) If the tags referenced are not present for some instances, empty strings
-#    will be substituted in the format string.
-# 2) This overrides both destination_variable and vpc_destination_variable.
-#
-#destination_format = {0}.{1}.example.com
-#destination_format_tags = Name,environment
-
-# To tag instances on EC2 with the resource records that point to them from
-# Route53, uncomment and set 'route53' to True.
-route53 = False
-
-# To exclude RDS instances from the inventory, uncomment and set to False.
-rds = False
-
-# To exclude ElastiCache instances from the inventory, uncomment and set to False.
-elasticache = False
-
-# Additionally, you can specify the list of zones to exclude looking up in
-# 'route53_excluded_zones' as a comma-separated list.
-# route53_excluded_zones = samplezone1.com, samplezone2.com
-
-# By default, only EC2 instances in the 'running' state are returned. Set
-# 'all_instances' to True to return all instances regardless of state.
-all_instances = True
-
-# By default, only EC2 instances in the 'running' state are returned. Specify
-# EC2 instance states to return as a comma-separated list. This
-# option is overriden when 'all_instances' is True.
-# instance_states = pending, running, shutting-down, terminated, stopping, stopped
-
-# By default, only RDS instances in the 'available' state are returned.  Set
-# 'all_rds_instances' to True return all RDS instances regardless of state.
-all_rds_instances = False
-
-# By default, only ElastiCache clusters and nodes in the 'available' state
-# are returned. Set 'all_elasticache_clusters' and/or 'all_elastic_nodes'
-# to True return all ElastiCache clusters and nodes, regardless of state.
-#
-# Note that all_elasticache_nodes only applies to listed clusters. That means
-# if you set all_elastic_clusters to false, no node will be return from
-# unavailable clusters, regardless of the state and to what you set for
-# all_elasticache_nodes.
-all_elasticache_replication_groups = False
-all_elasticache_clusters = False
-all_elasticache_nodes = False
-
-# API calls to EC2 are slow. For this reason, we cache the results of an API
-# call. Set this to the path you want cache files to be written to. Two files
-# will be written to this directory:
-#   - ansible-ec2.cache
-#   - ansible-ec2.index
-cache_path = ~/.ansible/tmp
-
-# The number of seconds a cache file is considered valid. After this many
-# seconds, a new API call will be made, and the cache file will be updated.
-# To disable the cache, set this value to 0
-cache_max_age = 300
-
-# Organize groups into a nested/hierarchy instead of a flat namespace.
-nested_groups = False
-
-# Replace - tags when creating groups to avoid issues with ansible
-replace_dash_in_groups = True
-
-# If set to true, any tag of the form "a,b,c" is expanded into a list
-# and the results are used to create additional tag_* inventory groups.
-expand_csv_tags = False
-
-# The EC2 inventory output can become very large. To manage its size,
-# configure which groups should be created.
-group_by_instance_id = True
-group_by_region = True
-group_by_availability_zone = True
-group_by_ami_id = True
-group_by_instance_type = True
-group_by_key_pair = True
-group_by_vpc_id = True
-group_by_security_group = True
-group_by_tag_keys = True
-group_by_tag_none = True
-group_by_route53_names = True
-group_by_rds_engine = False
-group_by_rds_parameter_group = False
-group_by_elasticache_engine = True
-group_by_elasticache_cluster = True
-group_by_elasticache_parameter_group = True
-group_by_elasticache_replication_group = True
-
-# If you only want to include hosts that match a certain regular expression
-# pattern_include = staging-*
-
-# If you want to exclude any hosts that match a certain regular expression
-# pattern_exclude = staging-*
-# Ansible EC2 external inventory script settings
-#
-
-##[ec2]
-##
-### to talk to a private eucalyptus instance uncomment these lines
-### and edit edit eucalyptus_host to be the host name of your cloud controller
-###eucalyptus = True
-###eucalyptus_host = clc.cloud.domain.org
-##
-### AWS regions to make calls to. Set this to 'all' to make request to all regions
-##
-### in AWS and merge the results together. Alternatively, set this to a comma
-### separated list of regions. E.g. 'us-east-1,us-west-1,us-west-2'
-##regions = all
-##regions_exclude = us-gov-west-1,cn-north-1
-##
-### When generating inventory, Ansible needs to know how to address a server.
-### Each EC2 instance has a lot of variables associated with it. Here is the list:
-###   http://docs.pythonboto.org/en/latest/ref/ec2.html#module-boto.ec2.instance
-### Below are 2 variables that are used as the address of a server:
-###   - destination_variable
-###   - vpc_destination_variable
-##
-### This is the normal destination variable to use. If you are running Ansible
-### from outside EC2, then 'public_dns_name' makes the most sense. If you are
-### running Ansible from within EC2, then perhaps you want to use the internal
-### address, and should set this to 'private_dns_name'. The key of an EC2 tag
-##...skipping...
-### pattern_include = staging-*
-##
-### If you want to exclude any hosts that match a certain regular expression
-### pattern_exclude = staging-*
-
-# Instance filters can be used to control which instances are retrieved for
-# inventory. For the full list of possible filters, please read the EC2 API
-# docs: http://docs.aws.amazon.com/AWSEC2/latest/APIReference/ApiReference-query-DescribeInstances.html#query-DescribeInstances-filters
-# Filters are key/value pairs separated by '=', to list multiple filters use
-# a list separated by commas. See examples below.
-
-# Retrieve only instances with (key=value) env=staging tag
-# instance_filters = tag:env=staging
-
-# Retrieve only instances with role=webservers OR role=dbservers tag
-# instance_filters = tag:role=webservers,tag:role=dbservers
-
-# Retrieve only t1.micro instances OR instances with tag env=staging
-# instance_filters = instance-type=t1.micro,tag:env=staging
-
-# You can use wildcards in filter values also. Below will list instances which
-# tag Name value matches webservers1*
-# (ex. webservers15, webservers1a, webservers123 etc)
-# instance_filters = tag:Name=webservers1*
-
-# A boto configuration profile may be used to separate out credentials
-# see http://boto.readthedocs.org/en/latest/boto_config_tut.html
-# boto_profile = some-boto-profile-name
diff --git a/edge-1609-dc2/ec2.py b/edge-1609-dc2/ec2.py
deleted file mode 100755
index f30958a..0000000
--- a/edge-1609-dc2/ec2.py
+++ /dev/null
@@ -1,1385 +0,0 @@
-#!/usr/bin/env python
-
-'''
-EC2 external inventory script
-=================================
-
-Generates inventory that Ansible can understand by making API request to
-AWS EC2 using the Boto library.
-
-NOTE: This script assumes Ansible is being executed where the environment
-variables needed for Boto have already been set:
-    export AWS_ACCESS_KEY_ID='AK123'
-    export AWS_SECRET_ACCESS_KEY='abc123'
-
-This script also assumes there is an ec2.ini file alongside it.  To specify a
-different path to ec2.ini, define the EC2_INI_PATH environment variable:
-
-    export EC2_INI_PATH=/path/to/my_ec2.ini
-
-If you're using eucalyptus you need to set the above variables and
-you need to define:
-
-    export EC2_URL=http://hostname_of_your_cc:port/services/Eucalyptus
-
-If you're using boto profiles (requires boto>=2.24.0) you can choose a profile
-using the --boto-profile command line argument (e.g. ec2.py --boto-profile prod) or using
-the AWS_PROFILE variable:
-
-    AWS_PROFILE=prod ansible-playbook -i ec2.py myplaybook.yml
-
-For more details, see: http://docs.pythonboto.org/en/latest/boto_config_tut.html
-
-When run against a specific host, this script returns the following variables:
- - ec2_ami_launch_index
- - ec2_architecture
- - ec2_association
- - ec2_attachTime
- - ec2_attachment
- - ec2_attachmentId
- - ec2_client_token
- - ec2_deleteOnTermination
- - ec2_description
- - ec2_deviceIndex
- - ec2_dns_name
- - ec2_eventsSet
- - ec2_group_name
- - ec2_hypervisor
- - ec2_id
- - ec2_image_id
- - ec2_instanceState
- - ec2_instance_type
- - ec2_ipOwnerId
- - ec2_ip_address
- - ec2_item
- - ec2_kernel
- - ec2_key_name
- - ec2_launch_time
- - ec2_monitored
- - ec2_monitoring
- - ec2_networkInterfaceId
- - ec2_ownerId
- - ec2_persistent
- - ec2_placement
- - ec2_platform
- - ec2_previous_state
- - ec2_private_dns_name
- - ec2_private_ip_address
- - ec2_publicIp
- - ec2_public_dns_name
- - ec2_ramdisk
- - ec2_reason
- - ec2_region
- - ec2_requester_id
- - ec2_root_device_name
- - ec2_root_device_type
- - ec2_security_group_ids
- - ec2_security_group_names
- - ec2_shutdown_state
- - ec2_sourceDestCheck
- - ec2_spot_instance_request_id
- - ec2_state
- - ec2_state_code
- - ec2_state_reason
- - ec2_status
- - ec2_subnet_id
- - ec2_tenancy
- - ec2_virtualization_type
- - ec2_vpc_id
-
-These variables are pulled out of a boto.ec2.instance object. There is a lack of
-consistency with variable spellings (camelCase and underscores) since this
-just loops through all variables the object exposes. It is preferred to use the
-ones with underscores when multiple exist.
-
-In addition, if an instance has AWS Tags associated with it, each tag is a new
-variable named:
- - ec2_tag_[Key] = [Value]
-
-Security groups are comma-separated in 'ec2_security_group_ids' and
-'ec2_security_group_names'.
-'''
-
-# (c) 2012, Peter Sankauskas
-#
-# This file is part of Ansible,
-#
-# Ansible is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# Ansible is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with Ansible.  If not, see <http://www.gnu.org/licenses/>.
-
-######################################################################
-
-import sys
-import os
-import argparse
-import re
-from time import time
-import boto
-from boto import ec2
-from boto import rds
-from boto import elasticache
-from boto import route53
-import six
-
-from six.moves import configparser
-from collections import defaultdict
-
-try:
-    import json
-except ImportError:
-    import simplejson as json
-
-
-class Ec2Inventory(object):
-
-    def _empty_inventory(self):
-        return {"_meta" : {"hostvars" : {}}}
-
-    def __init__(self):
-        ''' Main execution path '''
-
-        # Inventory grouped by instance IDs, tags, security groups, regions,
-        # and availability zones
-        self.inventory = self._empty_inventory()
-
-        # Index of hostname (address) to instance ID
-        self.index = {}
-
-        # Boto profile to use (if any)
-        self.boto_profile = None
-
-        # Read settings and parse CLI arguments
-        self.parse_cli_args()
-        self.read_settings()
-
-        # Make sure that profile_name is not passed at all if not set
-        # as pre 2.24 boto will fall over otherwise
-        if self.boto_profile:
-            if not hasattr(boto.ec2.EC2Connection, 'profile_name'):
-                self.fail_with_error("boto version must be >= 2.24 to use profile")
-
-        # Cache
-        if self.args.refresh_cache:
-            self.do_api_calls_update_cache()
-        elif not self.is_cache_valid():
-            self.do_api_calls_update_cache()
-
-        # Data to print
-        if self.args.host:
-            data_to_print = self.get_host_info()
-
-        elif self.args.list:
-            # Display list of instances for inventory
-            if self.inventory == self._empty_inventory():
-                data_to_print = self.get_inventory_from_cache()
-            else:
-                data_to_print = self.json_format_dict(self.inventory, True)
-
-        print(data_to_print)
-
-
-    def is_cache_valid(self):
-        ''' Determines if the cache files have expired, or if it is still valid '''
-
-        if os.path.isfile(self.cache_path_cache):
-            mod_time = os.path.getmtime(self.cache_path_cache)
-            current_time = time()
-            if (mod_time + self.cache_max_age) > current_time:
-                if os.path.isfile(self.cache_path_index):
-                    return True
-
-        return False
-
-
-    def read_settings(self):
-        ''' Reads the settings from the ec2.ini file '''
-        if six.PY3:
-            config = configparser.ConfigParser()
-        else:
-            config = configparser.SafeConfigParser()
-        ec2_default_ini_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'ec2.ini')
-        ec2_ini_path = os.path.expanduser(os.path.expandvars(os.environ.get('EC2_INI_PATH', ec2_default_ini_path)))
-        config.read(ec2_ini_path)
-
-        # is eucalyptus?
-        self.eucalyptus_host = None
-        self.eucalyptus = False
-        if config.has_option('ec2', 'eucalyptus'):
-            self.eucalyptus = config.getboolean('ec2', 'eucalyptus')
-        if self.eucalyptus and config.has_option('ec2', 'eucalyptus_host'):
-            self.eucalyptus_host = config.get('ec2', 'eucalyptus_host')
-
-        # Regions
-        self.regions = []
-        configRegions = config.get('ec2', 'regions')
-        configRegions_exclude = config.get('ec2', 'regions_exclude')
-        if (configRegions == 'all'):
-            if self.eucalyptus_host:
-                self.regions.append(boto.connect_euca(host=self.eucalyptus_host).region.name)
-            else:
-                for regionInfo in ec2.regions():
-                    if regionInfo.name not in configRegions_exclude:
-                        self.regions.append(regionInfo.name)
-        else:
-            self.regions = configRegions.split(",")
-
-        # Destination addresses
-        self.destination_variable = config.get('ec2', 'destination_variable')
-        self.vpc_destination_variable = config.get('ec2', 'vpc_destination_variable')
-
-        if config.has_option('ec2', 'hostname_variable'):
-            self.hostname_variable = config.get('ec2', 'hostname_variable')
-        else:
-            self.hostname_variable = None
-
-        if config.has_option('ec2', 'destination_format') and \
-                config.has_option('ec2', 'destination_format_tags'):
-            self.destination_format = config.get('ec2', 'destination_format')
-            self.destination_format_tags = config.get('ec2', 'destination_format_tags').split(',')
-        else:
-            self.destination_format = None
-            self.destination_format_tags = None
-
-        # Route53
-        self.route53_enabled = config.getboolean('ec2', 'route53')
-        self.route53_excluded_zones = []
-        if config.has_option('ec2', 'route53_excluded_zones'):
-            self.route53_excluded_zones.extend(
-                    config.get('ec2', 'route53_excluded_zones', '').split(','))
-
-        # Include RDS instances?
-        self.rds_enabled = True
-        if config.has_option('ec2', 'rds'):
-            self.rds_enabled = config.getboolean('ec2', 'rds')
-
-        # Include ElastiCache instances?
-        self.elasticache_enabled = True
-        if config.has_option('ec2', 'elasticache'):
-            self.elasticache_enabled = config.getboolean('ec2', 'elasticache')
-
-        # Return all EC2 instances?
-        if config.has_option('ec2', 'all_instances'):
-            self.all_instances = config.getboolean('ec2', 'all_instances')
-        else:
-            self.all_instances = False
-
-        # Instance states to be gathered in inventory. Default is 'running'.
-        # Setting 'all_instances' to 'yes' overrides this option.
-        ec2_valid_instance_states = [
-            'pending',
-            'running',
-            'shutting-down',
-            'terminated',
-            'stopping',
-            'stopped'
-        ]
-        self.ec2_instance_states = []
-        if self.all_instances:
-            self.ec2_instance_states = ec2_valid_instance_states
-        elif config.has_option('ec2', 'instance_states'):
-            for instance_state in config.get('ec2', 'instance_states').split(','):
-                instance_state = instance_state.strip()
-                if instance_state not in ec2_valid_instance_states:
-                    continue
-                self.ec2_instance_states.append(instance_state)
-        else:
-            self.ec2_instance_states = ['running']
-
-        # Return all RDS instances? (if RDS is enabled)
-        if config.has_option('ec2', 'all_rds_instances') and self.rds_enabled:
-            self.all_rds_instances = config.getboolean('ec2', 'all_rds_instances')
-        else:
-            self.all_rds_instances = False
-
-        # Return all ElastiCache replication groups? (if ElastiCache is enabled)
-        if config.has_option('ec2', 'all_elasticache_replication_groups') and self.elasticache_enabled:
-            self.all_elasticache_replication_groups = config.getboolean('ec2', 'all_elasticache_replication_groups')
-        else:
-            self.all_elasticache_replication_groups = False
-
-        # Return all ElastiCache clusters? (if ElastiCache is enabled)
-        if config.has_option('ec2', 'all_elasticache_clusters') and self.elasticache_enabled:
-            self.all_elasticache_clusters = config.getboolean('ec2', 'all_elasticache_clusters')
-        else:
-            self.all_elasticache_clusters = False
-
-        # Return all ElastiCache nodes? (if ElastiCache is enabled)
-        if config.has_option('ec2', 'all_elasticache_nodes') and self.elasticache_enabled:
-            self.all_elasticache_nodes = config.getboolean('ec2', 'all_elasticache_nodes')
-        else:
-            self.all_elasticache_nodes = False
-
-        # boto configuration profile (prefer CLI argument)
-        self.boto_profile = self.args.boto_profile
-        if config.has_option('ec2', 'boto_profile') and not self.boto_profile:
-            self.boto_profile = config.get('ec2', 'boto_profile')
-
-        # Cache related
-        cache_dir = os.path.expanduser(config.get('ec2', 'cache_path'))
-        if self.boto_profile:
-            cache_dir = os.path.join(cache_dir, 'profile_' + self.boto_profile)
-        if not os.path.exists(cache_dir):
-            os.makedirs(cache_dir)
-
-        cache_name = 'ansible-ec2'
-        aws_profile = lambda: (self.boto_profile or
-                               os.environ.get('AWS_PROFILE') or
-                               os.environ.get('AWS_ACCESS_KEY_ID'))
-        if aws_profile():
-            cache_name = '%s-%s' % (cache_name, aws_profile())
-        self.cache_path_cache = cache_dir + "/%s.cache" % cache_name
-        self.cache_path_index = cache_dir + "/%s.index" % cache_name
-        self.cache_max_age = config.getint('ec2', 'cache_max_age')
-
-        if config.has_option('ec2', 'expand_csv_tags'):
-            self.expand_csv_tags = config.getboolean('ec2', 'expand_csv_tags')
-        else:
-            self.expand_csv_tags = False
-
-        # Configure nested groups instead of flat namespace.
-        if config.has_option('ec2', 'nested_groups'):
-            self.nested_groups = config.getboolean('ec2', 'nested_groups')
-        else:
-            self.nested_groups = False
-
-        # Replace dash or not in group names
-        if config.has_option('ec2', 'replace_dash_in_groups'):
-            self.replace_dash_in_groups = config.getboolean('ec2', 'replace_dash_in_groups')
-        else:
-            self.replace_dash_in_groups = True
-
-        # Configure which groups should be created.
-        group_by_options = [
-            'group_by_instance_id',
-            'group_by_region',
-            'group_by_availability_zone',
-            'group_by_ami_id',
-            'group_by_instance_type',
-            'group_by_key_pair',
-            'group_by_vpc_id',
-            'group_by_security_group',
-            'group_by_tag_keys',
-            'group_by_tag_none',
-            'group_by_route53_names',
-            'group_by_rds_engine',
-            'group_by_rds_parameter_group',
-            'group_by_elasticache_engine',
-            'group_by_elasticache_cluster',
-            'group_by_elasticache_parameter_group',
-            'group_by_elasticache_replication_group',
-        ]
-        for option in group_by_options:
-            if config.has_option('ec2', option):
-                setattr(self, option, config.getboolean('ec2', option))
-            else:
-                setattr(self, option, True)
-
-        # Do we need to just include hosts that match a pattern?
-        try:
-            pattern_include = config.get('ec2', 'pattern_include')
-            if pattern_include and len(pattern_include) > 0:
-                self.pattern_include = re.compile(pattern_include)
-            else:
-                self.pattern_include = None
-        except configparser.NoOptionError:
-            self.pattern_include = None
-
-        # Do we need to exclude hosts that match a pattern?
-        try:
-            pattern_exclude = config.get('ec2', 'pattern_exclude');
-            if pattern_exclude and len(pattern_exclude) > 0:
-                self.pattern_exclude = re.compile(pattern_exclude)
-            else:
-                self.pattern_exclude = None
-        except configparser.NoOptionError:
-            self.pattern_exclude = None
-
-        # Instance filters (see boto and EC2 API docs). Ignore invalid filters.
-        self.ec2_instance_filters = defaultdict(list)
-        if config.has_option('ec2', 'instance_filters'):
-
-            filters = [f for f in config.get('ec2', 'instance_filters').split(',') if f]
-
-            for instance_filter in filters:
-                instance_filter = instance_filter.strip()
-                if not instance_filter or '=' not in instance_filter:
-                    continue
-                filter_key, filter_value = [x.strip() for x in instance_filter.split('=', 1)]
-                if not filter_key:
-                    continue
-                self.ec2_instance_filters[filter_key].append(filter_value)
-
-    def parse_cli_args(self):
-        ''' Command line argument processing '''
-
-        parser = argparse.ArgumentParser(description='Produce an Ansible Inventory file based on EC2')
-        parser.add_argument('--list', action='store_true', default=True,
-                            help='List instances (default: True)')
-        parser.add_argument('--host', action='store',
-                            help='Get all the variables about a specific instance')
-        parser.add_argument('--refresh-cache', action='store_true', default=False,
-                            help='Force refresh of cache by making API requests to EC2 (default: False - use cache files)')
-        parser.add_argument('--profile', '--boto-profile', action='store', dest='boto_profile',
-                            help='Use boto profile for connections to EC2')
-        self.args = parser.parse_args()
-
-
-    def do_api_calls_update_cache(self):
-        ''' Do API calls to each region, and save data in cache files '''
-
-        if self.route53_enabled:
-            self.get_route53_records()
-
-        for region in self.regions:
-            self.get_instances_by_region(region)
-            if self.rds_enabled:
-                self.get_rds_instances_by_region(region)
-            if self.elasticache_enabled:
-                self.get_elasticache_clusters_by_region(region)
-                self.get_elasticache_replication_groups_by_region(region)
-
-        self.write_to_cache(self.inventory, self.cache_path_cache)
-        self.write_to_cache(self.index, self.cache_path_index)
-
-    def connect(self, region):
-        ''' create connection to api server'''
-        if self.eucalyptus:
-            conn = boto.connect_euca(host=self.eucalyptus_host)
-            conn.APIVersion = '2010-08-31'
-        else:
-            conn = self.connect_to_aws(ec2, region)
-        return conn
-
-    def boto_fix_security_token_in_profile(self, connect_args):
-        ''' monkey patch for boto issue boto/boto#2100 '''
-        profile = 'profile ' + self.boto_profile
-        if boto.config.has_option(profile, 'aws_security_token'):
-            connect_args['security_token'] = boto.config.get(profile, 'aws_security_token')
-        return connect_args
-
-    def connect_to_aws(self, module, region):
-        connect_args = {}
-
-        # only pass the profile name if it's set (as it is not supported by older boto versions)
-        if self.boto_profile:
-            connect_args['profile_name'] = self.boto_profile
-            self.boto_fix_security_token_in_profile(connect_args)
-
-        conn = module.connect_to_region(region, **connect_args)
-        # connect_to_region will fail "silently" by returning None if the region name is wrong or not supported
-        if conn is None:
-            self.fail_with_error("region name: %s likely not supported, or AWS is down.  connection to region failed." % region)
-        return conn
-
-    def get_instances_by_region(self, region):
-        ''' Makes an AWS EC2 API call to the list of instances in a particular
-        region '''
-
-        try:
-            conn = self.connect(region)
-            reservations = []
-            if self.ec2_instance_filters:
-                for filter_key, filter_values in self.ec2_instance_filters.items():
-                    reservations.extend(conn.get_all_instances(filters = { filter_key : filter_values }))
-            else:
-                reservations = conn.get_all_instances()
-
-            for reservation in reservations:
-                for instance in reservation.instances:
-                    self.add_instance(instance, region)
-
-        except boto.exception.BotoServerError as e:
-            if e.error_code == 'AuthFailure':
-                error = self.get_auth_error_message()
-            else:
-                backend = 'Eucalyptus' if self.eucalyptus else 'AWS'
-                error = "Error connecting to %s backend.\n%s" % (backend, e.message)
-            self.fail_with_error(error, 'getting EC2 instances')
-
-    def get_rds_instances_by_region(self, region):
-        ''' Makes an AWS API call to the list of RDS instances in a particular
-        region '''
-
-        try:
-            conn = self.connect_to_aws(rds, region)
-            if conn:
-                marker = None
-                while True:
-                    instances = conn.get_all_dbinstances(marker=marker)
-                    marker = instances.marker
-                    for instance in instances:
-                        self.add_rds_instance(instance, region)
-                    if not marker:
-                        break
-        except boto.exception.BotoServerError as e:
-            error = e.reason
-
-            if e.error_code == 'AuthFailure':
-                error = self.get_auth_error_message()
-            if not e.reason == "Forbidden":
-                error = "Looks like AWS RDS is down:\n%s" % e.message
-            self.fail_with_error(error, 'getting RDS instances')
-
-    def get_elasticache_clusters_by_region(self, region):
-        ''' Makes an AWS API call to the list of ElastiCache clusters (with
-        nodes' info) in a particular region.'''
-
-        # ElastiCache boto module doesn't provide a get_all_intances method,
-        # that's why we need to call describe directly (it would be called by
-        # the shorthand method anyway...)
-        try:
-            conn = self.connect_to_aws(elasticache, region)
-            if conn:
-                # show_cache_node_info = True
-                # because we also want nodes' information
-                response = conn.describe_cache_clusters(None, None, None, True)
-
-        except boto.exception.BotoServerError as e:
-            error = e.reason
-
-            if e.error_code == 'AuthFailure':
-                error = self.get_auth_error_message()
-            if not e.reason == "Forbidden":
-                error = "Looks like AWS ElastiCache is down:\n%s" % e.message
-            self.fail_with_error(error, 'getting ElastiCache clusters')
-
-        try:
-            # Boto also doesn't provide wrapper classes to CacheClusters or
-            # CacheNodes. Because of that wo can't make use of the get_list
-            # method in the AWSQueryConnection. Let's do the work manually
-            clusters = response['DescribeCacheClustersResponse']['DescribeCacheClustersResult']['CacheClusters']
-
-        except KeyError as e:
-            error = "ElastiCache query to AWS failed (unexpected format)."
-            self.fail_with_error(error, 'getting ElastiCache clusters')
-
-        for cluster in clusters:
-            self.add_elasticache_cluster(cluster, region)
-
-    def get_elasticache_replication_groups_by_region(self, region):
-        ''' Makes an AWS API call to the list of ElastiCache replication groups
-        in a particular region.'''
-
-        # ElastiCache boto module doesn't provide a get_all_intances method,
-        # that's why we need to call describe directly (it would be called by
-        # the shorthand method anyway...)
-        try:
-            conn = self.connect_to_aws(elasticache, region)
-            if conn:
-                response = conn.describe_replication_groups()
-
-        except boto.exception.BotoServerError as e:
-            error = e.reason
-
-            if e.error_code == 'AuthFailure':
-                error = self.get_auth_error_message()
-            if not e.reason == "Forbidden":
-                error = "Looks like AWS ElastiCache [Replication Groups] is down:\n%s" % e.message
-            self.fail_with_error(error, 'getting ElastiCache clusters')
-
-        try:
-            # Boto also doesn't provide wrapper classes to ReplicationGroups
-            # Because of that wo can't make use of the get_list method in the
-            # AWSQueryConnection. Let's do the work manually
-            replication_groups = response['DescribeReplicationGroupsResponse']['DescribeReplicationGroupsResult']['ReplicationGroups']
-
-        except KeyError as e:
-            error = "ElastiCache [Replication Groups] query to AWS failed (unexpected format)."
-            self.fail_with_error(error, 'getting ElastiCache clusters')
-
-        for replication_group in replication_groups:
-            self.add_elasticache_replication_group(replication_group, region)
-
-    def get_auth_error_message(self):
-        ''' create an informative error message if there is an issue authenticating'''
-        errors = ["Authentication error retrieving ec2 inventory."]
-        if None in [os.environ.get('AWS_ACCESS_KEY_ID'), os.environ.get('AWS_SECRET_ACCESS_KEY')]:
-            errors.append(' - No AWS_ACCESS_KEY_ID or AWS_SECRET_ACCESS_KEY environment vars found')
-        else:
-            errors.append(' - AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY environment vars found but may not be correct')
-
-        boto_paths = ['/etc/boto.cfg', '~/.boto', '~/.aws/credentials']
-        boto_config_found = list(p for p in boto_paths if os.path.isfile(os.path.expanduser(p)))
-        if len(boto_config_found) > 0:
-            errors.append(" - Boto configs found at '%s', but the credentials contained may not be correct" % ', '.join(boto_config_found))
-        else:
-            errors.append(" - No Boto config found at any expected location '%s'" % ', '.join(boto_paths))
-
-        return '\n'.join(errors)
-
-    def fail_with_error(self, err_msg, err_operation=None):
-        '''log an error to std err for ansible-playbook to consume and exit'''
-        if err_operation:
-            err_msg = 'ERROR: "{err_msg}", while: {err_operation}'.format(
-                    err_msg=err_msg, err_operation=err_operation)
-        sys.stderr.write(err_msg)
-        sys.exit(1)
-
-    def get_instance(self, region, instance_id):
-        conn = self.connect(region)
-
-        reservations = conn.get_all_instances([instance_id])
-        for reservation in reservations:
-            for instance in reservation.instances:
-                return instance
-
-    def add_instance(self, instance, region):
-        ''' Adds an instance to the inventory and index, as long as it is
-        addressable '''
-
-        # Only return instances with desired instance states
-        if instance.state not in self.ec2_instance_states:
-            return
-
-        # Select the best destination address
-        if self.destination_format and self.destination_format_tags:
-            dest = self.destination_format.format(*[ getattr(instance, 'tags').get(tag, '') for tag in self.destination_format_tags ])
-        elif instance.subnet_id:
-            dest = getattr(instance, self.vpc_destination_variable, None)
-            if dest is None:
-                dest = getattr(instance, 'tags').get(self.vpc_destination_variable, None)
-        else:
-            dest = getattr(instance, self.destination_variable, None)
-            if dest is None:
-                dest = getattr(instance, 'tags').get(self.destination_variable, None)
-
-        if not dest:
-            # Skip instances we cannot address (e.g. private VPC subnet)
-            return
-
-        # Set the inventory name
-        hostname = None
-        if self.hostname_variable:
-            if self.hostname_variable.startswith('tag_'):
-                hostname = instance.tags.get(self.hostname_variable[4:], None)
-            else:
-                hostname = getattr(instance, self.hostname_variable)
-
-        # If we can't get a nice hostname, use the destination address
-        if not hostname:
-            hostname = dest
-        else:
-            hostname = self.to_safe(hostname).lower()
-
-        # if we only want to include hosts that match a pattern, skip those that don't
-        if self.pattern_include and not self.pattern_include.match(hostname):
-            return
-
-        # if we need to exclude hosts that match a pattern, skip those
-        if self.pattern_exclude and self.pattern_exclude.match(hostname):
-            return
-
-        # Add to index
-        self.index[hostname] = [region, instance.id]
-
-        # Inventory: Group by instance ID (always a group of 1)
-        if self.group_by_instance_id:
-            self.inventory[instance.id] = [hostname]
-            if self.nested_groups:
-                self.push_group(self.inventory, 'instances', instance.id)
-
-        # Inventory: Group by region
-        if self.group_by_region:
-            self.push(self.inventory, region, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'regions', region)
-
-        # Inventory: Group by availability zone
-        if self.group_by_availability_zone:
-            self.push(self.inventory, instance.placement, hostname)
-            if self.nested_groups:
-                if self.group_by_region:
-                    self.push_group(self.inventory, region, instance.placement)
-                self.push_group(self.inventory, 'zones', instance.placement)
-
-        # Inventory: Group by Amazon Machine Image (AMI) ID
-        if self.group_by_ami_id:
-            ami_id = self.to_safe(instance.image_id)
-            self.push(self.inventory, ami_id, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'images', ami_id)
-
-        # Inventory: Group by instance type
-        if self.group_by_instance_type:
-            type_name = self.to_safe('type_' + instance.instance_type)
-            self.push(self.inventory, type_name, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'types', type_name)
-
-        # Inventory: Group by key pair
-        if self.group_by_key_pair and instance.key_name:
-            key_name = self.to_safe('key_' + instance.key_name)
-            self.push(self.inventory, key_name, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'keys', key_name)
-
-        # Inventory: Group by VPC
-        if self.group_by_vpc_id and instance.vpc_id:
-            vpc_id_name = self.to_safe('vpc_id_' + instance.vpc_id)
-            self.push(self.inventory, vpc_id_name, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'vpcs', vpc_id_name)
-
-        # Inventory: Group by security group
-        if self.group_by_security_group:
-            try:
-                for group in instance.groups:
-                    key = self.to_safe("security_group_" + group.name)
-                    self.push(self.inventory, key, hostname)
-                    if self.nested_groups:
-                        self.push_group(self.inventory, 'security_groups', key)
-            except AttributeError:
-                self.fail_with_error('\n'.join(['Package boto seems a bit older.',
-                                                'Please upgrade boto >= 2.3.0.']))
-
-        # Inventory: Group by tag keys
-        if self.group_by_tag_keys:
-            for k, v in instance.tags.items():
-                if self.expand_csv_tags and v and ',' in v:
-                    values = map(lambda x: x.strip(), v.split(','))
-                else:
-                    values = [v]
-
-                for v in values:
-                    if v:
-                        key = self.to_safe("tag_" + k + "=" + v)
-                    else:
-                        key = self.to_safe("tag_" + k)
-                    self.push(self.inventory, key, hostname)
-                    if self.nested_groups:
-                        self.push_group(self.inventory, 'tags', self.to_safe("tag_" + k))
-                        if v:
-                            self.push_group(self.inventory, self.to_safe("tag_" + k), key)
-
-        # Inventory: Group by Route53 domain names if enabled
-        if self.route53_enabled and self.group_by_route53_names:
-            route53_names = self.get_instance_route53_names(instance)
-            for name in route53_names:
-                self.push(self.inventory, name, hostname)
-                if self.nested_groups:
-                    self.push_group(self.inventory, 'route53', name)
-
-        # Global Tag: instances without tags
-        if self.group_by_tag_none and len(instance.tags) == 0:
-            self.push(self.inventory, 'tag_none', hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'tags', 'tag_none')
-
-        # Global Tag: tag all EC2 instances
-        self.push(self.inventory, 'ec2', hostname)
-
-        self.inventory["_meta"]["hostvars"][hostname] = self.get_host_info_dict_from_instance(instance)
-        self.inventory["_meta"]["hostvars"][hostname]['ansible_ssh_host'] = dest
-
-
-    def add_rds_instance(self, instance, region):
-        ''' Adds an RDS instance to the inventory and index, as long as it is
-        addressable '''
-
-        # Only want available instances unless all_rds_instances is True
-        if not self.all_rds_instances and instance.status != 'available':
-            return
-
-        # Select the best destination address
-        dest = instance.endpoint[0]
-
-        if not dest:
-            # Skip instances we cannot address (e.g. private VPC subnet)
-            return
-
-        # Set the inventory name
-        hostname = None
-        if self.hostname_variable:
-            if self.hostname_variable.startswith('tag_'):
-                hostname = instance.tags.get(self.hostname_variable[4:], None)
-            else:
-                hostname = getattr(instance, self.hostname_variable)
-
-        # If we can't get a nice hostname, use the destination address
-        if not hostname:
-            hostname = dest
-
-        hostname = self.to_safe(hostname).lower()
-
-        # Add to index
-        self.index[hostname] = [region, instance.id]
-
-        # Inventory: Group by instance ID (always a group of 1)
-        if self.group_by_instance_id:
-            self.inventory[instance.id] = [hostname]
-            if self.nested_groups:
-                self.push_group(self.inventory, 'instances', instance.id)
-
-        # Inventory: Group by region
-        if self.group_by_region:
-            self.push(self.inventory, region, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'regions', region)
-
-        # Inventory: Group by availability zone
-        if self.group_by_availability_zone:
-            self.push(self.inventory, instance.availability_zone, hostname)
-            if self.nested_groups:
-                if self.group_by_region:
-                    self.push_group(self.inventory, region, instance.availability_zone)
-                self.push_group(self.inventory, 'zones', instance.availability_zone)
-
-        # Inventory: Group by instance type
-        if self.group_by_instance_type:
-            type_name = self.to_safe('type_' + instance.instance_class)
-            self.push(self.inventory, type_name, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'types', type_name)
-
-        # Inventory: Group by VPC
-        if self.group_by_vpc_id and instance.subnet_group and instance.subnet_group.vpc_id:
-            vpc_id_name = self.to_safe('vpc_id_' + instance.subnet_group.vpc_id)
-            self.push(self.inventory, vpc_id_name, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'vpcs', vpc_id_name)
-
-        # Inventory: Group by security group
-        if self.group_by_security_group:
-            try:
-                if instance.security_group:
-                    key = self.to_safe("security_group_" + instance.security_group.name)
-                    self.push(self.inventory, key, hostname)
-                    if self.nested_groups:
-                        self.push_group(self.inventory, 'security_groups', key)
-
-            except AttributeError:
-                self.fail_with_error('\n'.join(['Package boto seems a bit older.',
-                                                'Please upgrade boto >= 2.3.0.']))
-
-
-        # Inventory: Group by engine
-        if self.group_by_rds_engine:
-            self.push(self.inventory, self.to_safe("rds_" + instance.engine), hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'rds_engines', self.to_safe("rds_" + instance.engine))
-
-        # Inventory: Group by parameter group
-        if self.group_by_rds_parameter_group:
-            self.push(self.inventory, self.to_safe("rds_parameter_group_" + instance.parameter_group.name), hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'rds_parameter_groups', self.to_safe("rds_parameter_group_" + instance.parameter_group.name))
-
-        # Global Tag: all RDS instances
-        self.push(self.inventory, 'rds', hostname)
-
-        self.inventory["_meta"]["hostvars"][hostname] = self.get_host_info_dict_from_instance(instance)
-        self.inventory["_meta"]["hostvars"][hostname]['ansible_ssh_host'] = dest
-
-    def add_elasticache_cluster(self, cluster, region):
-        ''' Adds an ElastiCache cluster to the inventory and index, as long as
-        it's nodes are addressable '''
-
-        # Only want available clusters unless all_elasticache_clusters is True
-        if not self.all_elasticache_clusters and cluster['CacheClusterStatus'] != 'available':
-            return
-
-        # Select the best destination address
-        if 'ConfigurationEndpoint' in cluster and cluster['ConfigurationEndpoint']:
-            # Memcached cluster
-            dest = cluster['ConfigurationEndpoint']['Address']
-            is_redis = False
-        else:
-            # Redis sigle node cluster
-            # Because all Redis clusters are single nodes, we'll merge the
-            # info from the cluster with info about the node
-            dest = cluster['CacheNodes'][0]['Endpoint']['Address']
-            is_redis = True
-
-        if not dest:
-            # Skip clusters we cannot address (e.g. private VPC subnet)
-            return
-
-        # Add to index
-        self.index[dest] = [region, cluster['CacheClusterId']]
-
-        # Inventory: Group by instance ID (always a group of 1)
-        if self.group_by_instance_id:
-            self.inventory[cluster['CacheClusterId']] = [dest]
-            if self.nested_groups:
-                self.push_group(self.inventory, 'instances', cluster['CacheClusterId'])
-
-        # Inventory: Group by region
-        if self.group_by_region and not is_redis:
-            self.push(self.inventory, region, dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'regions', region)
-
-        # Inventory: Group by availability zone
-        if self.group_by_availability_zone and not is_redis:
-            self.push(self.inventory, cluster['PreferredAvailabilityZone'], dest)
-            if self.nested_groups:
-                if self.group_by_region:
-                    self.push_group(self.inventory, region, cluster['PreferredAvailabilityZone'])
-                self.push_group(self.inventory, 'zones', cluster['PreferredAvailabilityZone'])
-
-        # Inventory: Group by node type
-        if self.group_by_instance_type and not is_redis:
-            type_name = self.to_safe('type_' + cluster['CacheNodeType'])
-            self.push(self.inventory, type_name, dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'types', type_name)
-
-        # Inventory: Group by VPC (information not available in the current
-        # AWS API version for ElastiCache)
-
-        # Inventory: Group by security group
-        if self.group_by_security_group and not is_redis:
-
-            # Check for the existence of the 'SecurityGroups' key and also if
-            # this key has some value. When the cluster is not placed in a SG
-            # the query can return None here and cause an error.
-            if 'SecurityGroups' in cluster and cluster['SecurityGroups'] is not None:
-                for security_group in cluster['SecurityGroups']:
-                    key = self.to_safe("security_group_" + security_group['SecurityGroupId'])
-                    self.push(self.inventory, key, dest)
-                    if self.nested_groups:
-                        self.push_group(self.inventory, 'security_groups', key)
-
-        # Inventory: Group by engine
-        if self.group_by_elasticache_engine and not is_redis:
-            self.push(self.inventory, self.to_safe("elasticache_" + cluster['Engine']), dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'elasticache_engines', self.to_safe(cluster['Engine']))
-
-        # Inventory: Group by parameter group
-        if self.group_by_elasticache_parameter_group:
-            self.push(self.inventory, self.to_safe("elasticache_parameter_group_" + cluster['CacheParameterGroup']['CacheParameterGroupName']), dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'elasticache_parameter_groups', self.to_safe(cluster['CacheParameterGroup']['CacheParameterGroupName']))
-
-        # Inventory: Group by replication group
-        if self.group_by_elasticache_replication_group and 'ReplicationGroupId' in cluster and cluster['ReplicationGroupId']:
-            self.push(self.inventory, self.to_safe("elasticache_replication_group_" + cluster['ReplicationGroupId']), dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'elasticache_replication_groups', self.to_safe(cluster['ReplicationGroupId']))
-
-        # Global Tag: all ElastiCache clusters
-        self.push(self.inventory, 'elasticache_clusters', cluster['CacheClusterId'])
-
-        host_info = self.get_host_info_dict_from_describe_dict(cluster)
-
-        self.inventory["_meta"]["hostvars"][dest] = host_info
-
-        # Add the nodes
-        for node in cluster['CacheNodes']:
-            self.add_elasticache_node(node, cluster, region)
-
-    def add_elasticache_node(self, node, cluster, region):
-        ''' Adds an ElastiCache node to the inventory and index, as long as
-        it is addressable '''
-
-        # Only want available nodes unless all_elasticache_nodes is True
-        if not self.all_elasticache_nodes and node['CacheNodeStatus'] != 'available':
-            return
-
-        # Select the best destination address
-        dest = node['Endpoint']['Address']
-
-        if not dest:
-            # Skip nodes we cannot address (e.g. private VPC subnet)
-            return
-
-        node_id = self.to_safe(cluster['CacheClusterId'] + '_' + node['CacheNodeId'])
-
-        # Add to index
-        self.index[dest] = [region, node_id]
-
-        # Inventory: Group by node ID (always a group of 1)
-        if self.group_by_instance_id:
-            self.inventory[node_id] = [dest]
-            if self.nested_groups:
-                self.push_group(self.inventory, 'instances', node_id)
-
-        # Inventory: Group by region
-        if self.group_by_region:
-            self.push(self.inventory, region, dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'regions', region)
-
-        # Inventory: Group by availability zone
-        if self.group_by_availability_zone:
-            self.push(self.inventory, cluster['PreferredAvailabilityZone'], dest)
-            if self.nested_groups:
-                if self.group_by_region:
-                    self.push_group(self.inventory, region, cluster['PreferredAvailabilityZone'])
-                self.push_group(self.inventory, 'zones', cluster['PreferredAvailabilityZone'])
-
-        # Inventory: Group by node type
-        if self.group_by_instance_type:
-            type_name = self.to_safe('type_' + cluster['CacheNodeType'])
-            self.push(self.inventory, type_name, dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'types', type_name)
-
-        # Inventory: Group by VPC (information not available in the current
-        # AWS API version for ElastiCache)
-
-        # Inventory: Group by security group
-        if self.group_by_security_group:
-
-            # Check for the existence of the 'SecurityGroups' key and also if
-            # this key has some value. When the cluster is not placed in a SG
-            # the query can return None here and cause an error.
-            if 'SecurityGroups' in cluster and cluster['SecurityGroups'] is not None:
-                for security_group in cluster['SecurityGroups']:
-                    key = self.to_safe("security_group_" + security_group['SecurityGroupId'])
-                    self.push(self.inventory, key, dest)
-                    if self.nested_groups:
-                        self.push_group(self.inventory, 'security_groups', key)
-
-        # Inventory: Group by engine
-        if self.group_by_elasticache_engine:
-            self.push(self.inventory, self.to_safe("elasticache_" + cluster['Engine']), dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'elasticache_engines', self.to_safe("elasticache_" + cluster['Engine']))
-
-        # Inventory: Group by parameter group (done at cluster level)
-
-        # Inventory: Group by replication group (done at cluster level)
-
-        # Inventory: Group by ElastiCache Cluster
-        if self.group_by_elasticache_cluster:
-            self.push(self.inventory, self.to_safe("elasticache_cluster_" + cluster['CacheClusterId']), dest)
-
-        # Global Tag: all ElastiCache nodes
-        self.push(self.inventory, 'elasticache_nodes', dest)
-
-        host_info = self.get_host_info_dict_from_describe_dict(node)
-
-        if dest in self.inventory["_meta"]["hostvars"]:
-            self.inventory["_meta"]["hostvars"][dest].update(host_info)
-        else:
-            self.inventory["_meta"]["hostvars"][dest] = host_info
-
-    def add_elasticache_replication_group(self, replication_group, region):
-        ''' Adds an ElastiCache replication group to the inventory and index '''
-
-        # Only want available clusters unless all_elasticache_replication_groups is True
-        if not self.all_elasticache_replication_groups and replication_group['Status'] != 'available':
-            return
-
-        # Select the best destination address (PrimaryEndpoint)
-        dest = replication_group['NodeGroups'][0]['PrimaryEndpoint']['Address']
-
-        if not dest:
-            # Skip clusters we cannot address (e.g. private VPC subnet)
-            return
-
-        # Add to index
-        self.index[dest] = [region, replication_group['ReplicationGroupId']]
-
-        # Inventory: Group by ID (always a group of 1)
-        if self.group_by_instance_id:
-            self.inventory[replication_group['ReplicationGroupId']] = [dest]
-            if self.nested_groups:
-                self.push_group(self.inventory, 'instances', replication_group['ReplicationGroupId'])
-
-        # Inventory: Group by region
-        if self.group_by_region:
-            self.push(self.inventory, region, dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'regions', region)
-
-        # Inventory: Group by availability zone (doesn't apply to replication groups)
-
-        # Inventory: Group by node type (doesn't apply to replication groups)
-
-        # Inventory: Group by VPC (information not available in the current
-        # AWS API version for replication groups
-
-        # Inventory: Group by security group (doesn't apply to replication groups)
-        # Check this value in cluster level
-
-        # Inventory: Group by engine (replication groups are always Redis)
-        if self.group_by_elasticache_engine:
-            self.push(self.inventory, 'elasticache_redis', dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'elasticache_engines', 'redis')
-
-        # Global Tag: all ElastiCache clusters
-        self.push(self.inventory, 'elasticache_replication_groups', replication_group['ReplicationGroupId'])
-
-        host_info = self.get_host_info_dict_from_describe_dict(replication_group)
-
-        self.inventory["_meta"]["hostvars"][dest] = host_info
-
-    def get_route53_records(self):
-        ''' Get and store the map of resource records to domain names that
-        point to them. '''
-
-        r53_conn = route53.Route53Connection()
-        all_zones = r53_conn.get_zones()
-
-        route53_zones = [ zone for zone in all_zones if zone.name[:-1]
-                          not in self.route53_excluded_zones ]
-
-        self.route53_records = {}
-
-        for zone in route53_zones:
-            rrsets = r53_conn.get_all_rrsets(zone.id)
-
-            for record_set in rrsets:
-                record_name = record_set.name
-
-                if record_name.endswith('.'):
-                    record_name = record_name[:-1]
-
-                for resource in record_set.resource_records:
-                    self.route53_records.setdefault(resource, set())
-                    self.route53_records[resource].add(record_name)
-
-
-    def get_instance_route53_names(self, instance):
-        ''' Check if an instance is referenced in the records we have from
-        Route53. If it is, return the list of domain names pointing to said
-        instance. If nothing points to it, return an empty list. '''
-
-        instance_attributes = [ 'public_dns_name', 'private_dns_name',
-                                'ip_address', 'private_ip_address' ]
-
-        name_list = set()
-
-        for attrib in instance_attributes:
-            try:
-                value = getattr(instance, attrib)
-            except AttributeError:
-                continue
-
-            if value in self.route53_records:
-                name_list.update(self.route53_records[value])
-
-        return list(name_list)
-
-    def get_host_info_dict_from_instance(self, instance):
-        instance_vars = {}
-        for key in vars(instance):
-            value = getattr(instance, key)
-            key = self.to_safe('ec2_' + key)
-
-            # Handle complex types
-            # state/previous_state changed to properties in boto in https://github.com/boto/boto/commit/a23c379837f698212252720d2af8dec0325c9518
-            if key == 'ec2__state':
-                instance_vars['ec2_state'] = instance.state or ''
-                instance_vars['ec2_state_code'] = instance.state_code
-            elif key == 'ec2__previous_state':
-                instance_vars['ec2_previous_state'] = instance.previous_state or ''
-                instance_vars['ec2_previous_state_code'] = instance.previous_state_code
-            elif type(value) in [int, bool]:
-                instance_vars[key] = value
-            elif isinstance(value, six.string_types):
-                instance_vars[key] = value.strip()
-            elif type(value) == type(None):
-                instance_vars[key] = ''
-            elif key == 'ec2_region':
-                instance_vars[key] = value.name
-            elif key == 'ec2__placement':
-                instance_vars['ec2_placement'] = value.zone
-            elif key == 'ec2_tags':
-                for k, v in value.items():
-                    if self.expand_csv_tags and ',' in v:
-                        v = map(lambda x: x.strip(), v.split(','))
-                    key = self.to_safe('ec2_tag_' + k)
-                    instance_vars[key] = v
-            elif key == 'ec2_groups':
-                group_ids = []
-                group_names = []
-                for group in value:
-                    group_ids.append(group.id)
-                    group_names.append(group.name)
-                instance_vars["ec2_security_group_ids"] = ','.join([str(i) for i in group_ids])
-                instance_vars["ec2_security_group_names"] = ','.join([str(i) for i in group_names])
-            else:
-                pass
-                # TODO Product codes if someone finds them useful
-                #print key
-                #print type(value)
-                #print value
-
-        return instance_vars
-
-    def get_host_info_dict_from_describe_dict(self, describe_dict):
-        ''' Parses the dictionary returned by the API call into a flat list
-            of parameters. This method should be used only when 'describe' is
-            used directly because Boto doesn't provide specific classes. '''
-
-        # I really don't agree with prefixing everything with 'ec2'
-        # because EC2, RDS and ElastiCache are different services.
-        # I'm just following the pattern used until now to not break any
-        # compatibility.
-
-        host_info = {}
-        for key in describe_dict:
-            value = describe_dict[key]
-            key = self.to_safe('ec2_' + self.uncammelize(key))
-
-            # Handle complex types
-
-            # Target: Memcached Cache Clusters
-            if key == 'ec2_configuration_endpoint' and value:
-                host_info['ec2_configuration_endpoint_address'] = value['Address']
-                host_info['ec2_configuration_endpoint_port'] = value['Port']
-
-            # Target: Cache Nodes and Redis Cache Clusters (single node)
-            if key == 'ec2_endpoint' and value:
-                host_info['ec2_endpoint_address'] = value['Address']
-                host_info['ec2_endpoint_port'] = value['Port']
-
-            # Target: Redis Replication Groups
-            if key == 'ec2_node_groups' and value:
-                host_info['ec2_endpoint_address'] = value[0]['PrimaryEndpoint']['Address']
-                host_info['ec2_endpoint_port'] = value[0]['PrimaryEndpoint']['Port']
-                replica_count = 0
-                for node in value[0]['NodeGroupMembers']:
-                    if node['CurrentRole'] == 'primary':
-                        host_info['ec2_primary_cluster_address'] = node['ReadEndpoint']['Address']
-                        host_info['ec2_primary_cluster_port'] = node['ReadEndpoint']['Port']
-                        host_info['ec2_primary_cluster_id'] = node['CacheClusterId']
-                    elif node['CurrentRole'] == 'replica':
-                        host_info['ec2_replica_cluster_address_'+ str(replica_count)] = node['ReadEndpoint']['Address']
-                        host_info['ec2_replica_cluster_port_'+ str(replica_count)] = node['ReadEndpoint']['Port']
-                        host_info['ec2_replica_cluster_id_'+ str(replica_count)] = node['CacheClusterId']
-                        replica_count += 1
-
-            # Target: Redis Replication Groups
-            if key == 'ec2_member_clusters' and value:
-                host_info['ec2_member_clusters'] = ','.join([str(i) for i in value])
-
-            # Target: All Cache Clusters
-            elif key == 'ec2_cache_parameter_group':
-                host_info["ec2_cache_node_ids_to_reboot"] = ','.join([str(i) for i in value['CacheNodeIdsToReboot']])
-                host_info['ec2_cache_parameter_group_name'] = value['CacheParameterGroupName']
-                host_info['ec2_cache_parameter_apply_status'] = value['ParameterApplyStatus']
-
-            # Target: Almost everything
-            elif key == 'ec2_security_groups':
-
-                # Skip if SecurityGroups is None
-                # (it is possible to have the key defined but no value in it).
-                if value is not None:
-                    sg_ids = []
-                    for sg in value:
-                        sg_ids.append(sg['SecurityGroupId'])
-                    host_info["ec2_security_group_ids"] = ','.join([str(i) for i in sg_ids])
-
-            # Target: Everything
-            # Preserve booleans and integers
-            elif type(value) in [int, bool]:
-                host_info[key] = value
-
-            # Target: Everything
-            # Sanitize string values
-            elif isinstance(value, six.string_types):
-                host_info[key] = value.strip()
-
-            # Target: Everything
-            # Replace None by an empty string
-            elif type(value) == type(None):
-                host_info[key] = ''
-
-            else:
-                # Remove non-processed complex types
-                pass
-
-        return host_info
-
-    def get_host_info(self):
-        ''' Get variables about a specific host '''
-
-        if len(self.index) == 0:
-            # Need to load index from cache
-            self.load_index_from_cache()
-
-        if not self.args.host in self.index:
-            # try updating the cache
-            self.do_api_calls_update_cache()
-            if not self.args.host in self.index:
-                # host might not exist anymore
-                return self.json_format_dict({}, True)
-
-        (region, instance_id) = self.index[self.args.host]
-
-        instance = self.get_instance(region, instance_id)
-        return self.json_format_dict(self.get_host_info_dict_from_instance(instance), True)
-
-    def push(self, my_dict, key, element):
-        ''' Push an element onto an array that may not have been defined in
-        the dict '''
-        group_info = my_dict.setdefault(key, [])
-        if isinstance(group_info, dict):
-            host_list = group_info.setdefault('hosts', [])
-            host_list.append(element)
-        else:
-            group_info.append(element)
-
-    def push_group(self, my_dict, key, element):
-        ''' Push a group as a child of another group. '''
-        parent_group = my_dict.setdefault(key, {})
-        if not isinstance(parent_group, dict):
-            parent_group = my_dict[key] = {'hosts': parent_group}
-        child_groups = parent_group.setdefault('children', [])
-        if element not in child_groups:
-            child_groups.append(element)
-
-    def get_inventory_from_cache(self):
-        ''' Reads the inventory from the cache file and returns it as a JSON
-        object '''
-
-        cache = open(self.cache_path_cache, 'r')
-        json_inventory = cache.read()
-        return json_inventory
-
-
-    def load_index_from_cache(self):
-        ''' Reads the index from the cache file sets self.index '''
-
-        cache = open(self.cache_path_index, 'r')
-        json_index = cache.read()
-        self.index = json.loads(json_index)
-
-
-    def write_to_cache(self, data, filename):
-        ''' Writes data in JSON format to a file '''
-
-        json_data = self.json_format_dict(data, True)
-        cache = open(filename, 'w')
-        cache.write(json_data)
-        cache.close()
-
-    def uncammelize(self, key):
-        temp = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', key)
-        return re.sub('([a-z0-9])([A-Z])', r'\1_\2', temp).lower()
-
-    def to_safe(self, word):
-        ''' Converts 'bad' characters in a string to underscores so they can be used as Ansible groups '''
-        regex = "[^A-Za-z0-9\_"
-        if not self.replace_dash_in_groups:
-            regex += "\-"
-        return re.sub(regex + "]", "_", word)
-
-    def json_format_dict(self, data, pretty=False):
-        ''' Converts a dict to a JSON object and dumps it as a formatted
-        string '''
-
-        if pretty:
-            return json.dumps(data, sort_keys=True, indent=2)
-        else:
-            return json.dumps(data)
-
-
-# Run the script
-Ec2Inventory()
diff --git a/edge-1609-dc2/inventory b/edge-1609-dc2/inventory
deleted file mode 100644
index 436da8b..0000000
--- a/edge-1609-dc2/inventory
+++ /dev/null
@@ -1,75 +0,0 @@
-[tag_Name_dc2_n1]
-[tag_Name_dc2_n2]
-[tag_Name_dc2_n3]
-[tag_Name_dc2_n4]
-[tag_Name_dc2_n5]
-
-[planet:children]
-dc-1
-
-[dc-1:children]
-tag_Name_dc2_n1
-tag_Name_dc2_n2
-tag_Name_dc2_n3
-tag_Name_dc2_n4
-tag_Name_dc2_n5
-
-[ds:children]
-dc-1-ds
-
-[dc-1-ds:children]
-tag_Name_dc2_n1
-tag_Name_dc2_n2
-tag_Name_dc2_n3
-
-[ms:children]
-dc-1-ms
-
-[dc-1-ms:children]
-tag_Name_dc2_n1
-
-[ui:children]
-dc-1-ui
-
-[dc-1-ui:children]
-tag_Name_dc2_n1
-
-[ldap:children]
-dc-1-ldap
-
-[dc-1-ldap:children]
-tag_Name_dc2_n1
-
-[rmp:children]
-dc-1-rmp
-
-[dc-1-rmp:children]
-tag_Name_dc2_n2
-tag_Name_dc2_n3
-
-[qpid:children]
-dc-1-qpid
-
-[dc-1-qpid:children]
-tag_Name_dc2_n4
-tag_Name_dc2_n5
-
-[pg:children]
-dc-1-pg
-
-[dc-1-pg:children]
-dc-1-pgmaster
-dc-1-pgstandby
-
-[pgmaster:children]
-dc-1-pgmaster
-
-[dc-1-pgmaster:children]
-tag_Name_dc2_n4
-
-[pgstandby:children]
-dc-1-pgstandby
-
-[dc-1-pgstandby:children]
-tag_Name_dc2_n5
-
diff --git a/edge-1609-dc3-dc4/ec2.ini b/edge-1609-dc3-dc4/ec2.ini
deleted file mode 100644
index 36b3921..0000000
--- a/edge-1609-dc3-dc4/ec2.ini
+++ /dev/null
@@ -1,200 +0,0 @@
-# Ansible EC2 external inventory script settings
-#
-
-[ec2]
-
-# to talk to a private eucalyptus instance uncomment these lines
-# and edit edit eucalyptus_host to be the host name of your cloud controller
-#eucalyptus = True
-#eucalyptus_host = clc.cloud.domain.org
-
-# AWS regions to make calls to. Set this to 'all' to make request to all regions
-# in AWS and merge the results together. Alternatively, set this to a comma
-# separated list of regions. E.g. 'us-east-1,us-west-1,us-west-2'
-regions = all
-regions_exclude = us-gov-west-1,cn-north-1
-
-# When generating inventory, Ansible needs to know how to address a server.
-# Each EC2 instance has a lot of variables associated with it. Here is the list:
-#   http://docs.pythonboto.org/en/latest/ref/ec2.html#module-boto.ec2.instance
-# Below are 2 variables that are used as the address of a server:
-#   - destination_variable
-#   - vpc_destination_variable
-
-# This is the normal destination variable to use. If you are running Ansible
-# from outside EC2, then 'public_dns_name' makes the most sense. If you are
-# running Ansible from within EC2, then perhaps you want to use the internal
-# address, and should set this to 'private_dns_name'. The key of an EC2 tag
-# may optionally be used; however the boto instance variables hold precedence
-# in the event of a collision.
-destination_variable = public_dns_name
-
-# This allows you to override the inventory_name with an ec2 variable, instead
-# of using the destination_variable above. Addressing (aka ansible_ssh_host)
-# will still use destination_variable. Tags should be written as 'tag_TAGNAME'.
-#hostname_variable = tag_Name
-
-# For server inside a VPC, using DNS names may not make sense. When an instance
-# has 'subnet_id' set, this variable is used. If the subnet is public, setting
-# this to 'ip_address' will return the public IP address. For instances in a
-# private subnet, this should be set to 'private_ip_address', and Ansible must
-# be run from within EC2. The key of an EC2 tag may optionally be used; however
-# the boto instance variables hold precedence in the event of a collision.
-# WARNING: - instances that are in the private vpc, _without_ public ip address
-# will not be listed in the inventory until You set:
-# vpc_destination_variable = private_ip_address
-vpc_destination_variable = ip_address
-
-# The following two settings allow flexible ansible host naming based on a
-# python format string and a comma-separated list of ec2 tags.  Note that:
-#
-# 1) If the tags referenced are not present for some instances, empty strings
-#    will be substituted in the format string.
-# 2) This overrides both destination_variable and vpc_destination_variable.
-#
-#destination_format = {0}.{1}.example.com
-#destination_format_tags = Name,environment
-
-# To tag instances on EC2 with the resource records that point to them from
-# Route53, uncomment and set 'route53' to True.
-route53 = False
-
-# To exclude RDS instances from the inventory, uncomment and set to False.
-rds = False
-
-# To exclude ElastiCache instances from the inventory, uncomment and set to False.
-elasticache = False
-
-# Additionally, you can specify the list of zones to exclude looking up in
-# 'route53_excluded_zones' as a comma-separated list.
-# route53_excluded_zones = samplezone1.com, samplezone2.com
-
-# By default, only EC2 instances in the 'running' state are returned. Set
-# 'all_instances' to True to return all instances regardless of state.
-all_instances = True
-
-# By default, only EC2 instances in the 'running' state are returned. Specify
-# EC2 instance states to return as a comma-separated list. This
-# option is overriden when 'all_instances' is True.
-# instance_states = pending, running, shutting-down, terminated, stopping, stopped
-
-# By default, only RDS instances in the 'available' state are returned.  Set
-# 'all_rds_instances' to True return all RDS instances regardless of state.
-all_rds_instances = False
-
-# By default, only ElastiCache clusters and nodes in the 'available' state
-# are returned. Set 'all_elasticache_clusters' and/or 'all_elastic_nodes'
-# to True return all ElastiCache clusters and nodes, regardless of state.
-#
-# Note that all_elasticache_nodes only applies to listed clusters. That means
-# if you set all_elastic_clusters to false, no node will be return from
-# unavailable clusters, regardless of the state and to what you set for
-# all_elasticache_nodes.
-all_elasticache_replication_groups = False
-all_elasticache_clusters = False
-all_elasticache_nodes = False
-
-# API calls to EC2 are slow. For this reason, we cache the results of an API
-# call. Set this to the path you want cache files to be written to. Two files
-# will be written to this directory:
-#   - ansible-ec2.cache
-#   - ansible-ec2.index
-cache_path = ~/.ansible/tmp
-
-# The number of seconds a cache file is considered valid. After this many
-# seconds, a new API call will be made, and the cache file will be updated.
-# To disable the cache, set this value to 0
-cache_max_age = 300
-
-# Organize groups into a nested/hierarchy instead of a flat namespace.
-nested_groups = False
-
-# Replace - tags when creating groups to avoid issues with ansible
-replace_dash_in_groups = True
-
-# If set to true, any tag of the form "a,b,c" is expanded into a list
-# and the results are used to create additional tag_* inventory groups.
-expand_csv_tags = False
-
-# The EC2 inventory output can become very large. To manage its size,
-# configure which groups should be created.
-group_by_instance_id = True
-group_by_region = True
-group_by_availability_zone = True
-group_by_ami_id = True
-group_by_instance_type = True
-group_by_key_pair = True
-group_by_vpc_id = True
-group_by_security_group = True
-group_by_tag_keys = True
-group_by_tag_none = True
-group_by_route53_names = True
-group_by_rds_engine = False
-group_by_rds_parameter_group = False
-group_by_elasticache_engine = True
-group_by_elasticache_cluster = True
-group_by_elasticache_parameter_group = True
-group_by_elasticache_replication_group = True
-
-# If you only want to include hosts that match a certain regular expression
-# pattern_include = staging-*
-
-# If you want to exclude any hosts that match a certain regular expression
-# pattern_exclude = staging-*
-# Ansible EC2 external inventory script settings
-#
-
-##[ec2]
-##
-### to talk to a private eucalyptus instance uncomment these lines
-### and edit edit eucalyptus_host to be the host name of your cloud controller
-###eucalyptus = True
-###eucalyptus_host = clc.cloud.domain.org
-##
-### AWS regions to make calls to. Set this to 'all' to make request to all regions
-##
-### in AWS and merge the results together. Alternatively, set this to a comma
-### separated list of regions. E.g. 'us-east-1,us-west-1,us-west-2'
-##regions = all
-##regions_exclude = us-gov-west-1,cn-north-1
-##
-### When generating inventory, Ansible needs to know how to address a server.
-### Each EC2 instance has a lot of variables associated with it. Here is the list:
-###   http://docs.pythonboto.org/en/latest/ref/ec2.html#module-boto.ec2.instance
-### Below are 2 variables that are used as the address of a server:
-###   - destination_variable
-###   - vpc_destination_variable
-##
-### This is the normal destination variable to use. If you are running Ansible
-### from outside EC2, then 'public_dns_name' makes the most sense. If you are
-### running Ansible from within EC2, then perhaps you want to use the internal
-### address, and should set this to 'private_dns_name'. The key of an EC2 tag
-##...skipping...
-### pattern_include = staging-*
-##
-### If you want to exclude any hosts that match a certain regular expression
-### pattern_exclude = staging-*
-
-# Instance filters can be used to control which instances are retrieved for
-# inventory. For the full list of possible filters, please read the EC2 API
-# docs: http://docs.aws.amazon.com/AWSEC2/latest/APIReference/ApiReference-query-DescribeInstances.html#query-DescribeInstances-filters
-# Filters are key/value pairs separated by '=', to list multiple filters use
-# a list separated by commas. See examples below.
-
-# Retrieve only instances with (key=value) env=staging tag
-# instance_filters = tag:env=staging
-
-# Retrieve only instances with role=webservers OR role=dbservers tag
-# instance_filters = tag:role=webservers,tag:role=dbservers
-
-# Retrieve only t1.micro instances OR instances with tag env=staging
-# instance_filters = instance-type=t1.micro,tag:env=staging
-
-# You can use wildcards in filter values also. Below will list instances which
-# tag Name value matches webservers1*
-# (ex. webservers15, webservers1a, webservers123 etc)
-# instance_filters = tag:Name=webservers1*
-
-# A boto configuration profile may be used to separate out credentials
-# see http://boto.readthedocs.org/en/latest/boto_config_tut.html
-# boto_profile = some-boto-profile-name
diff --git a/edge-1609-dc3-dc4/ec2.py b/edge-1609-dc3-dc4/ec2.py
deleted file mode 100755
index f30958a..0000000
--- a/edge-1609-dc3-dc4/ec2.py
+++ /dev/null
@@ -1,1385 +0,0 @@
-#!/usr/bin/env python
-
-'''
-EC2 external inventory script
-=================================
-
-Generates inventory that Ansible can understand by making API request to
-AWS EC2 using the Boto library.
-
-NOTE: This script assumes Ansible is being executed where the environment
-variables needed for Boto have already been set:
-    export AWS_ACCESS_KEY_ID='AK123'
-    export AWS_SECRET_ACCESS_KEY='abc123'
-
-This script also assumes there is an ec2.ini file alongside it.  To specify a
-different path to ec2.ini, define the EC2_INI_PATH environment variable:
-
-    export EC2_INI_PATH=/path/to/my_ec2.ini
-
-If you're using eucalyptus you need to set the above variables and
-you need to define:
-
-    export EC2_URL=http://hostname_of_your_cc:port/services/Eucalyptus
-
-If you're using boto profiles (requires boto>=2.24.0) you can choose a profile
-using the --boto-profile command line argument (e.g. ec2.py --boto-profile prod) or using
-the AWS_PROFILE variable:
-
-    AWS_PROFILE=prod ansible-playbook -i ec2.py myplaybook.yml
-
-For more details, see: http://docs.pythonboto.org/en/latest/boto_config_tut.html
-
-When run against a specific host, this script returns the following variables:
- - ec2_ami_launch_index
- - ec2_architecture
- - ec2_association
- - ec2_attachTime
- - ec2_attachment
- - ec2_attachmentId
- - ec2_client_token
- - ec2_deleteOnTermination
- - ec2_description
- - ec2_deviceIndex
- - ec2_dns_name
- - ec2_eventsSet
- - ec2_group_name
- - ec2_hypervisor
- - ec2_id
- - ec2_image_id
- - ec2_instanceState
- - ec2_instance_type
- - ec2_ipOwnerId
- - ec2_ip_address
- - ec2_item
- - ec2_kernel
- - ec2_key_name
- - ec2_launch_time
- - ec2_monitored
- - ec2_monitoring
- - ec2_networkInterfaceId
- - ec2_ownerId
- - ec2_persistent
- - ec2_placement
- - ec2_platform
- - ec2_previous_state
- - ec2_private_dns_name
- - ec2_private_ip_address
- - ec2_publicIp
- - ec2_public_dns_name
- - ec2_ramdisk
- - ec2_reason
- - ec2_region
- - ec2_requester_id
- - ec2_root_device_name
- - ec2_root_device_type
- - ec2_security_group_ids
- - ec2_security_group_names
- - ec2_shutdown_state
- - ec2_sourceDestCheck
- - ec2_spot_instance_request_id
- - ec2_state
- - ec2_state_code
- - ec2_state_reason
- - ec2_status
- - ec2_subnet_id
- - ec2_tenancy
- - ec2_virtualization_type
- - ec2_vpc_id
-
-These variables are pulled out of a boto.ec2.instance object. There is a lack of
-consistency with variable spellings (camelCase and underscores) since this
-just loops through all variables the object exposes. It is preferred to use the
-ones with underscores when multiple exist.
-
-In addition, if an instance has AWS Tags associated with it, each tag is a new
-variable named:
- - ec2_tag_[Key] = [Value]
-
-Security groups are comma-separated in 'ec2_security_group_ids' and
-'ec2_security_group_names'.
-'''
-
-# (c) 2012, Peter Sankauskas
-#
-# This file is part of Ansible,
-#
-# Ansible is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# Ansible is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with Ansible.  If not, see <http://www.gnu.org/licenses/>.
-
-######################################################################
-
-import sys
-import os
-import argparse
-import re
-from time import time
-import boto
-from boto import ec2
-from boto import rds
-from boto import elasticache
-from boto import route53
-import six
-
-from six.moves import configparser
-from collections import defaultdict
-
-try:
-    import json
-except ImportError:
-    import simplejson as json
-
-
-class Ec2Inventory(object):
-
-    def _empty_inventory(self):
-        return {"_meta" : {"hostvars" : {}}}
-
-    def __init__(self):
-        ''' Main execution path '''
-
-        # Inventory grouped by instance IDs, tags, security groups, regions,
-        # and availability zones
-        self.inventory = self._empty_inventory()
-
-        # Index of hostname (address) to instance ID
-        self.index = {}
-
-        # Boto profile to use (if any)
-        self.boto_profile = None
-
-        # Read settings and parse CLI arguments
-        self.parse_cli_args()
-        self.read_settings()
-
-        # Make sure that profile_name is not passed at all if not set
-        # as pre 2.24 boto will fall over otherwise
-        if self.boto_profile:
-            if not hasattr(boto.ec2.EC2Connection, 'profile_name'):
-                self.fail_with_error("boto version must be >= 2.24 to use profile")
-
-        # Cache
-        if self.args.refresh_cache:
-            self.do_api_calls_update_cache()
-        elif not self.is_cache_valid():
-            self.do_api_calls_update_cache()
-
-        # Data to print
-        if self.args.host:
-            data_to_print = self.get_host_info()
-
-        elif self.args.list:
-            # Display list of instances for inventory
-            if self.inventory == self._empty_inventory():
-                data_to_print = self.get_inventory_from_cache()
-            else:
-                data_to_print = self.json_format_dict(self.inventory, True)
-
-        print(data_to_print)
-
-
-    def is_cache_valid(self):
-        ''' Determines if the cache files have expired, or if it is still valid '''
-
-        if os.path.isfile(self.cache_path_cache):
-            mod_time = os.path.getmtime(self.cache_path_cache)
-            current_time = time()
-            if (mod_time + self.cache_max_age) > current_time:
-                if os.path.isfile(self.cache_path_index):
-                    return True
-
-        return False
-
-
-    def read_settings(self):
-        ''' Reads the settings from the ec2.ini file '''
-        if six.PY3:
-            config = configparser.ConfigParser()
-        else:
-            config = configparser.SafeConfigParser()
-        ec2_default_ini_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'ec2.ini')
-        ec2_ini_path = os.path.expanduser(os.path.expandvars(os.environ.get('EC2_INI_PATH', ec2_default_ini_path)))
-        config.read(ec2_ini_path)
-
-        # is eucalyptus?
-        self.eucalyptus_host = None
-        self.eucalyptus = False
-        if config.has_option('ec2', 'eucalyptus'):
-            self.eucalyptus = config.getboolean('ec2', 'eucalyptus')
-        if self.eucalyptus and config.has_option('ec2', 'eucalyptus_host'):
-            self.eucalyptus_host = config.get('ec2', 'eucalyptus_host')
-
-        # Regions
-        self.regions = []
-        configRegions = config.get('ec2', 'regions')
-        configRegions_exclude = config.get('ec2', 'regions_exclude')
-        if (configRegions == 'all'):
-            if self.eucalyptus_host:
-                self.regions.append(boto.connect_euca(host=self.eucalyptus_host).region.name)
-            else:
-                for regionInfo in ec2.regions():
-                    if regionInfo.name not in configRegions_exclude:
-                        self.regions.append(regionInfo.name)
-        else:
-            self.regions = configRegions.split(",")
-
-        # Destination addresses
-        self.destination_variable = config.get('ec2', 'destination_variable')
-        self.vpc_destination_variable = config.get('ec2', 'vpc_destination_variable')
-
-        if config.has_option('ec2', 'hostname_variable'):
-            self.hostname_variable = config.get('ec2', 'hostname_variable')
-        else:
-            self.hostname_variable = None
-
-        if config.has_option('ec2', 'destination_format') and \
-                config.has_option('ec2', 'destination_format_tags'):
-            self.destination_format = config.get('ec2', 'destination_format')
-            self.destination_format_tags = config.get('ec2', 'destination_format_tags').split(',')
-        else:
-            self.destination_format = None
-            self.destination_format_tags = None
-
-        # Route53
-        self.route53_enabled = config.getboolean('ec2', 'route53')
-        self.route53_excluded_zones = []
-        if config.has_option('ec2', 'route53_excluded_zones'):
-            self.route53_excluded_zones.extend(
-                    config.get('ec2', 'route53_excluded_zones', '').split(','))
-
-        # Include RDS instances?
-        self.rds_enabled = True
-        if config.has_option('ec2', 'rds'):
-            self.rds_enabled = config.getboolean('ec2', 'rds')
-
-        # Include ElastiCache instances?
-        self.elasticache_enabled = True
-        if config.has_option('ec2', 'elasticache'):
-            self.elasticache_enabled = config.getboolean('ec2', 'elasticache')
-
-        # Return all EC2 instances?
-        if config.has_option('ec2', 'all_instances'):
-            self.all_instances = config.getboolean('ec2', 'all_instances')
-        else:
-            self.all_instances = False
-
-        # Instance states to be gathered in inventory. Default is 'running'.
-        # Setting 'all_instances' to 'yes' overrides this option.
-        ec2_valid_instance_states = [
-            'pending',
-            'running',
-            'shutting-down',
-            'terminated',
-            'stopping',
-            'stopped'
-        ]
-        self.ec2_instance_states = []
-        if self.all_instances:
-            self.ec2_instance_states = ec2_valid_instance_states
-        elif config.has_option('ec2', 'instance_states'):
-            for instance_state in config.get('ec2', 'instance_states').split(','):
-                instance_state = instance_state.strip()
-                if instance_state not in ec2_valid_instance_states:
-                    continue
-                self.ec2_instance_states.append(instance_state)
-        else:
-            self.ec2_instance_states = ['running']
-
-        # Return all RDS instances? (if RDS is enabled)
-        if config.has_option('ec2', 'all_rds_instances') and self.rds_enabled:
-            self.all_rds_instances = config.getboolean('ec2', 'all_rds_instances')
-        else:
-            self.all_rds_instances = False
-
-        # Return all ElastiCache replication groups? (if ElastiCache is enabled)
-        if config.has_option('ec2', 'all_elasticache_replication_groups') and self.elasticache_enabled:
-            self.all_elasticache_replication_groups = config.getboolean('ec2', 'all_elasticache_replication_groups')
-        else:
-            self.all_elasticache_replication_groups = False
-
-        # Return all ElastiCache clusters? (if ElastiCache is enabled)
-        if config.has_option('ec2', 'all_elasticache_clusters') and self.elasticache_enabled:
-            self.all_elasticache_clusters = config.getboolean('ec2', 'all_elasticache_clusters')
-        else:
-            self.all_elasticache_clusters = False
-
-        # Return all ElastiCache nodes? (if ElastiCache is enabled)
-        if config.has_option('ec2', 'all_elasticache_nodes') and self.elasticache_enabled:
-            self.all_elasticache_nodes = config.getboolean('ec2', 'all_elasticache_nodes')
-        else:
-            self.all_elasticache_nodes = False
-
-        # boto configuration profile (prefer CLI argument)
-        self.boto_profile = self.args.boto_profile
-        if config.has_option('ec2', 'boto_profile') and not self.boto_profile:
-            self.boto_profile = config.get('ec2', 'boto_profile')
-
-        # Cache related
-        cache_dir = os.path.expanduser(config.get('ec2', 'cache_path'))
-        if self.boto_profile:
-            cache_dir = os.path.join(cache_dir, 'profile_' + self.boto_profile)
-        if not os.path.exists(cache_dir):
-            os.makedirs(cache_dir)
-
-        cache_name = 'ansible-ec2'
-        aws_profile = lambda: (self.boto_profile or
-                               os.environ.get('AWS_PROFILE') or
-                               os.environ.get('AWS_ACCESS_KEY_ID'))
-        if aws_profile():
-            cache_name = '%s-%s' % (cache_name, aws_profile())
-        self.cache_path_cache = cache_dir + "/%s.cache" % cache_name
-        self.cache_path_index = cache_dir + "/%s.index" % cache_name
-        self.cache_max_age = config.getint('ec2', 'cache_max_age')
-
-        if config.has_option('ec2', 'expand_csv_tags'):
-            self.expand_csv_tags = config.getboolean('ec2', 'expand_csv_tags')
-        else:
-            self.expand_csv_tags = False
-
-        # Configure nested groups instead of flat namespace.
-        if config.has_option('ec2', 'nested_groups'):
-            self.nested_groups = config.getboolean('ec2', 'nested_groups')
-        else:
-            self.nested_groups = False
-
-        # Replace dash or not in group names
-        if config.has_option('ec2', 'replace_dash_in_groups'):
-            self.replace_dash_in_groups = config.getboolean('ec2', 'replace_dash_in_groups')
-        else:
-            self.replace_dash_in_groups = True
-
-        # Configure which groups should be created.
-        group_by_options = [
-            'group_by_instance_id',
-            'group_by_region',
-            'group_by_availability_zone',
-            'group_by_ami_id',
-            'group_by_instance_type',
-            'group_by_key_pair',
-            'group_by_vpc_id',
-            'group_by_security_group',
-            'group_by_tag_keys',
-            'group_by_tag_none',
-            'group_by_route53_names',
-            'group_by_rds_engine',
-            'group_by_rds_parameter_group',
-            'group_by_elasticache_engine',
-            'group_by_elasticache_cluster',
-            'group_by_elasticache_parameter_group',
-            'group_by_elasticache_replication_group',
-        ]
-        for option in group_by_options:
-            if config.has_option('ec2', option):
-                setattr(self, option, config.getboolean('ec2', option))
-            else:
-                setattr(self, option, True)
-
-        # Do we need to just include hosts that match a pattern?
-        try:
-            pattern_include = config.get('ec2', 'pattern_include')
-            if pattern_include and len(pattern_include) > 0:
-                self.pattern_include = re.compile(pattern_include)
-            else:
-                self.pattern_include = None
-        except configparser.NoOptionError:
-            self.pattern_include = None
-
-        # Do we need to exclude hosts that match a pattern?
-        try:
-            pattern_exclude = config.get('ec2', 'pattern_exclude');
-            if pattern_exclude and len(pattern_exclude) > 0:
-                self.pattern_exclude = re.compile(pattern_exclude)
-            else:
-                self.pattern_exclude = None
-        except configparser.NoOptionError:
-            self.pattern_exclude = None
-
-        # Instance filters (see boto and EC2 API docs). Ignore invalid filters.
-        self.ec2_instance_filters = defaultdict(list)
-        if config.has_option('ec2', 'instance_filters'):
-
-            filters = [f for f in config.get('ec2', 'instance_filters').split(',') if f]
-
-            for instance_filter in filters:
-                instance_filter = instance_filter.strip()
-                if not instance_filter or '=' not in instance_filter:
-                    continue
-                filter_key, filter_value = [x.strip() for x in instance_filter.split('=', 1)]
-                if not filter_key:
-                    continue
-                self.ec2_instance_filters[filter_key].append(filter_value)
-
-    def parse_cli_args(self):
-        ''' Command line argument processing '''
-
-        parser = argparse.ArgumentParser(description='Produce an Ansible Inventory file based on EC2')
-        parser.add_argument('--list', action='store_true', default=True,
-                            help='List instances (default: True)')
-        parser.add_argument('--host', action='store',
-                            help='Get all the variables about a specific instance')
-        parser.add_argument('--refresh-cache', action='store_true', default=False,
-                            help='Force refresh of cache by making API requests to EC2 (default: False - use cache files)')
-        parser.add_argument('--profile', '--boto-profile', action='store', dest='boto_profile',
-                            help='Use boto profile for connections to EC2')
-        self.args = parser.parse_args()
-
-
-    def do_api_calls_update_cache(self):
-        ''' Do API calls to each region, and save data in cache files '''
-
-        if self.route53_enabled:
-            self.get_route53_records()
-
-        for region in self.regions:
-            self.get_instances_by_region(region)
-            if self.rds_enabled:
-                self.get_rds_instances_by_region(region)
-            if self.elasticache_enabled:
-                self.get_elasticache_clusters_by_region(region)
-                self.get_elasticache_replication_groups_by_region(region)
-
-        self.write_to_cache(self.inventory, self.cache_path_cache)
-        self.write_to_cache(self.index, self.cache_path_index)
-
-    def connect(self, region):
-        ''' create connection to api server'''
-        if self.eucalyptus:
-            conn = boto.connect_euca(host=self.eucalyptus_host)
-            conn.APIVersion = '2010-08-31'
-        else:
-            conn = self.connect_to_aws(ec2, region)
-        return conn
-
-    def boto_fix_security_token_in_profile(self, connect_args):
-        ''' monkey patch for boto issue boto/boto#2100 '''
-        profile = 'profile ' + self.boto_profile
-        if boto.config.has_option(profile, 'aws_security_token'):
-            connect_args['security_token'] = boto.config.get(profile, 'aws_security_token')
-        return connect_args
-
-    def connect_to_aws(self, module, region):
-        connect_args = {}
-
-        # only pass the profile name if it's set (as it is not supported by older boto versions)
-        if self.boto_profile:
-            connect_args['profile_name'] = self.boto_profile
-            self.boto_fix_security_token_in_profile(connect_args)
-
-        conn = module.connect_to_region(region, **connect_args)
-        # connect_to_region will fail "silently" by returning None if the region name is wrong or not supported
-        if conn is None:
-            self.fail_with_error("region name: %s likely not supported, or AWS is down.  connection to region failed." % region)
-        return conn
-
-    def get_instances_by_region(self, region):
-        ''' Makes an AWS EC2 API call to the list of instances in a particular
-        region '''
-
-        try:
-            conn = self.connect(region)
-            reservations = []
-            if self.ec2_instance_filters:
-                for filter_key, filter_values in self.ec2_instance_filters.items():
-                    reservations.extend(conn.get_all_instances(filters = { filter_key : filter_values }))
-            else:
-                reservations = conn.get_all_instances()
-
-            for reservation in reservations:
-                for instance in reservation.instances:
-                    self.add_instance(instance, region)
-
-        except boto.exception.BotoServerError as e:
-            if e.error_code == 'AuthFailure':
-                error = self.get_auth_error_message()
-            else:
-                backend = 'Eucalyptus' if self.eucalyptus else 'AWS'
-                error = "Error connecting to %s backend.\n%s" % (backend, e.message)
-            self.fail_with_error(error, 'getting EC2 instances')
-
-    def get_rds_instances_by_region(self, region):
-        ''' Makes an AWS API call to the list of RDS instances in a particular
-        region '''
-
-        try:
-            conn = self.connect_to_aws(rds, region)
-            if conn:
-                marker = None
-                while True:
-                    instances = conn.get_all_dbinstances(marker=marker)
-                    marker = instances.marker
-                    for instance in instances:
-                        self.add_rds_instance(instance, region)
-                    if not marker:
-                        break
-        except boto.exception.BotoServerError as e:
-            error = e.reason
-
-            if e.error_code == 'AuthFailure':
-                error = self.get_auth_error_message()
-            if not e.reason == "Forbidden":
-                error = "Looks like AWS RDS is down:\n%s" % e.message
-            self.fail_with_error(error, 'getting RDS instances')
-
-    def get_elasticache_clusters_by_region(self, region):
-        ''' Makes an AWS API call to the list of ElastiCache clusters (with
-        nodes' info) in a particular region.'''
-
-        # ElastiCache boto module doesn't provide a get_all_intances method,
-        # that's why we need to call describe directly (it would be called by
-        # the shorthand method anyway...)
-        try:
-            conn = self.connect_to_aws(elasticache, region)
-            if conn:
-                # show_cache_node_info = True
-                # because we also want nodes' information
-                response = conn.describe_cache_clusters(None, None, None, True)
-
-        except boto.exception.BotoServerError as e:
-            error = e.reason
-
-            if e.error_code == 'AuthFailure':
-                error = self.get_auth_error_message()
-            if not e.reason == "Forbidden":
-                error = "Looks like AWS ElastiCache is down:\n%s" % e.message
-            self.fail_with_error(error, 'getting ElastiCache clusters')
-
-        try:
-            # Boto also doesn't provide wrapper classes to CacheClusters or
-            # CacheNodes. Because of that wo can't make use of the get_list
-            # method in the AWSQueryConnection. Let's do the work manually
-            clusters = response['DescribeCacheClustersResponse']['DescribeCacheClustersResult']['CacheClusters']
-
-        except KeyError as e:
-            error = "ElastiCache query to AWS failed (unexpected format)."
-            self.fail_with_error(error, 'getting ElastiCache clusters')
-
-        for cluster in clusters:
-            self.add_elasticache_cluster(cluster, region)
-
-    def get_elasticache_replication_groups_by_region(self, region):
-        ''' Makes an AWS API call to the list of ElastiCache replication groups
-        in a particular region.'''
-
-        # ElastiCache boto module doesn't provide a get_all_intances method,
-        # that's why we need to call describe directly (it would be called by
-        # the shorthand method anyway...)
-        try:
-            conn = self.connect_to_aws(elasticache, region)
-            if conn:
-                response = conn.describe_replication_groups()
-
-        except boto.exception.BotoServerError as e:
-            error = e.reason
-
-            if e.error_code == 'AuthFailure':
-                error = self.get_auth_error_message()
-            if not e.reason == "Forbidden":
-                error = "Looks like AWS ElastiCache [Replication Groups] is down:\n%s" % e.message
-            self.fail_with_error(error, 'getting ElastiCache clusters')
-
-        try:
-            # Boto also doesn't provide wrapper classes to ReplicationGroups
-            # Because of that wo can't make use of the get_list method in the
-            # AWSQueryConnection. Let's do the work manually
-            replication_groups = response['DescribeReplicationGroupsResponse']['DescribeReplicationGroupsResult']['ReplicationGroups']
-
-        except KeyError as e:
-            error = "ElastiCache [Replication Groups] query to AWS failed (unexpected format)."
-            self.fail_with_error(error, 'getting ElastiCache clusters')
-
-        for replication_group in replication_groups:
-            self.add_elasticache_replication_group(replication_group, region)
-
-    def get_auth_error_message(self):
-        ''' create an informative error message if there is an issue authenticating'''
-        errors = ["Authentication error retrieving ec2 inventory."]
-        if None in [os.environ.get('AWS_ACCESS_KEY_ID'), os.environ.get('AWS_SECRET_ACCESS_KEY')]:
-            errors.append(' - No AWS_ACCESS_KEY_ID or AWS_SECRET_ACCESS_KEY environment vars found')
-        else:
-            errors.append(' - AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY environment vars found but may not be correct')
-
-        boto_paths = ['/etc/boto.cfg', '~/.boto', '~/.aws/credentials']
-        boto_config_found = list(p for p in boto_paths if os.path.isfile(os.path.expanduser(p)))
-        if len(boto_config_found) > 0:
-            errors.append(" - Boto configs found at '%s', but the credentials contained may not be correct" % ', '.join(boto_config_found))
-        else:
-            errors.append(" - No Boto config found at any expected location '%s'" % ', '.join(boto_paths))
-
-        return '\n'.join(errors)
-
-    def fail_with_error(self, err_msg, err_operation=None):
-        '''log an error to std err for ansible-playbook to consume and exit'''
-        if err_operation:
-            err_msg = 'ERROR: "{err_msg}", while: {err_operation}'.format(
-                    err_msg=err_msg, err_operation=err_operation)
-        sys.stderr.write(err_msg)
-        sys.exit(1)
-
-    def get_instance(self, region, instance_id):
-        conn = self.connect(region)
-
-        reservations = conn.get_all_instances([instance_id])
-        for reservation in reservations:
-            for instance in reservation.instances:
-                return instance
-
-    def add_instance(self, instance, region):
-        ''' Adds an instance to the inventory and index, as long as it is
-        addressable '''
-
-        # Only return instances with desired instance states
-        if instance.state not in self.ec2_instance_states:
-            return
-
-        # Select the best destination address
-        if self.destination_format and self.destination_format_tags:
-            dest = self.destination_format.format(*[ getattr(instance, 'tags').get(tag, '') for tag in self.destination_format_tags ])
-        elif instance.subnet_id:
-            dest = getattr(instance, self.vpc_destination_variable, None)
-            if dest is None:
-                dest = getattr(instance, 'tags').get(self.vpc_destination_variable, None)
-        else:
-            dest = getattr(instance, self.destination_variable, None)
-            if dest is None:
-                dest = getattr(instance, 'tags').get(self.destination_variable, None)
-
-        if not dest:
-            # Skip instances we cannot address (e.g. private VPC subnet)
-            return
-
-        # Set the inventory name
-        hostname = None
-        if self.hostname_variable:
-            if self.hostname_variable.startswith('tag_'):
-                hostname = instance.tags.get(self.hostname_variable[4:], None)
-            else:
-                hostname = getattr(instance, self.hostname_variable)
-
-        # If we can't get a nice hostname, use the destination address
-        if not hostname:
-            hostname = dest
-        else:
-            hostname = self.to_safe(hostname).lower()
-
-        # if we only want to include hosts that match a pattern, skip those that don't
-        if self.pattern_include and not self.pattern_include.match(hostname):
-            return
-
-        # if we need to exclude hosts that match a pattern, skip those
-        if self.pattern_exclude and self.pattern_exclude.match(hostname):
-            return
-
-        # Add to index
-        self.index[hostname] = [region, instance.id]
-
-        # Inventory: Group by instance ID (always a group of 1)
-        if self.group_by_instance_id:
-            self.inventory[instance.id] = [hostname]
-            if self.nested_groups:
-                self.push_group(self.inventory, 'instances', instance.id)
-
-        # Inventory: Group by region
-        if self.group_by_region:
-            self.push(self.inventory, region, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'regions', region)
-
-        # Inventory: Group by availability zone
-        if self.group_by_availability_zone:
-            self.push(self.inventory, instance.placement, hostname)
-            if self.nested_groups:
-                if self.group_by_region:
-                    self.push_group(self.inventory, region, instance.placement)
-                self.push_group(self.inventory, 'zones', instance.placement)
-
-        # Inventory: Group by Amazon Machine Image (AMI) ID
-        if self.group_by_ami_id:
-            ami_id = self.to_safe(instance.image_id)
-            self.push(self.inventory, ami_id, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'images', ami_id)
-
-        # Inventory: Group by instance type
-        if self.group_by_instance_type:
-            type_name = self.to_safe('type_' + instance.instance_type)
-            self.push(self.inventory, type_name, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'types', type_name)
-
-        # Inventory: Group by key pair
-        if self.group_by_key_pair and instance.key_name:
-            key_name = self.to_safe('key_' + instance.key_name)
-            self.push(self.inventory, key_name, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'keys', key_name)
-
-        # Inventory: Group by VPC
-        if self.group_by_vpc_id and instance.vpc_id:
-            vpc_id_name = self.to_safe('vpc_id_' + instance.vpc_id)
-            self.push(self.inventory, vpc_id_name, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'vpcs', vpc_id_name)
-
-        # Inventory: Group by security group
-        if self.group_by_security_group:
-            try:
-                for group in instance.groups:
-                    key = self.to_safe("security_group_" + group.name)
-                    self.push(self.inventory, key, hostname)
-                    if self.nested_groups:
-                        self.push_group(self.inventory, 'security_groups', key)
-            except AttributeError:
-                self.fail_with_error('\n'.join(['Package boto seems a bit older.',
-                                                'Please upgrade boto >= 2.3.0.']))
-
-        # Inventory: Group by tag keys
-        if self.group_by_tag_keys:
-            for k, v in instance.tags.items():
-                if self.expand_csv_tags and v and ',' in v:
-                    values = map(lambda x: x.strip(), v.split(','))
-                else:
-                    values = [v]
-
-                for v in values:
-                    if v:
-                        key = self.to_safe("tag_" + k + "=" + v)
-                    else:
-                        key = self.to_safe("tag_" + k)
-                    self.push(self.inventory, key, hostname)
-                    if self.nested_groups:
-                        self.push_group(self.inventory, 'tags', self.to_safe("tag_" + k))
-                        if v:
-                            self.push_group(self.inventory, self.to_safe("tag_" + k), key)
-
-        # Inventory: Group by Route53 domain names if enabled
-        if self.route53_enabled and self.group_by_route53_names:
-            route53_names = self.get_instance_route53_names(instance)
-            for name in route53_names:
-                self.push(self.inventory, name, hostname)
-                if self.nested_groups:
-                    self.push_group(self.inventory, 'route53', name)
-
-        # Global Tag: instances without tags
-        if self.group_by_tag_none and len(instance.tags) == 0:
-            self.push(self.inventory, 'tag_none', hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'tags', 'tag_none')
-
-        # Global Tag: tag all EC2 instances
-        self.push(self.inventory, 'ec2', hostname)
-
-        self.inventory["_meta"]["hostvars"][hostname] = self.get_host_info_dict_from_instance(instance)
-        self.inventory["_meta"]["hostvars"][hostname]['ansible_ssh_host'] = dest
-
-
-    def add_rds_instance(self, instance, region):
-        ''' Adds an RDS instance to the inventory and index, as long as it is
-        addressable '''
-
-        # Only want available instances unless all_rds_instances is True
-        if not self.all_rds_instances and instance.status != 'available':
-            return
-
-        # Select the best destination address
-        dest = instance.endpoint[0]
-
-        if not dest:
-            # Skip instances we cannot address (e.g. private VPC subnet)
-            return
-
-        # Set the inventory name
-        hostname = None
-        if self.hostname_variable:
-            if self.hostname_variable.startswith('tag_'):
-                hostname = instance.tags.get(self.hostname_variable[4:], None)
-            else:
-                hostname = getattr(instance, self.hostname_variable)
-
-        # If we can't get a nice hostname, use the destination address
-        if not hostname:
-            hostname = dest
-
-        hostname = self.to_safe(hostname).lower()
-
-        # Add to index
-        self.index[hostname] = [region, instance.id]
-
-        # Inventory: Group by instance ID (always a group of 1)
-        if self.group_by_instance_id:
-            self.inventory[instance.id] = [hostname]
-            if self.nested_groups:
-                self.push_group(self.inventory, 'instances', instance.id)
-
-        # Inventory: Group by region
-        if self.group_by_region:
-            self.push(self.inventory, region, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'regions', region)
-
-        # Inventory: Group by availability zone
-        if self.group_by_availability_zone:
-            self.push(self.inventory, instance.availability_zone, hostname)
-            if self.nested_groups:
-                if self.group_by_region:
-                    self.push_group(self.inventory, region, instance.availability_zone)
-                self.push_group(self.inventory, 'zones', instance.availability_zone)
-
-        # Inventory: Group by instance type
-        if self.group_by_instance_type:
-            type_name = self.to_safe('type_' + instance.instance_class)
-            self.push(self.inventory, type_name, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'types', type_name)
-
-        # Inventory: Group by VPC
-        if self.group_by_vpc_id and instance.subnet_group and instance.subnet_group.vpc_id:
-            vpc_id_name = self.to_safe('vpc_id_' + instance.subnet_group.vpc_id)
-            self.push(self.inventory, vpc_id_name, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'vpcs', vpc_id_name)
-
-        # Inventory: Group by security group
-        if self.group_by_security_group:
-            try:
-                if instance.security_group:
-                    key = self.to_safe("security_group_" + instance.security_group.name)
-                    self.push(self.inventory, key, hostname)
-                    if self.nested_groups:
-                        self.push_group(self.inventory, 'security_groups', key)
-
-            except AttributeError:
-                self.fail_with_error('\n'.join(['Package boto seems a bit older.',
-                                                'Please upgrade boto >= 2.3.0.']))
-
-
-        # Inventory: Group by engine
-        if self.group_by_rds_engine:
-            self.push(self.inventory, self.to_safe("rds_" + instance.engine), hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'rds_engines', self.to_safe("rds_" + instance.engine))
-
-        # Inventory: Group by parameter group
-        if self.group_by_rds_parameter_group:
-            self.push(self.inventory, self.to_safe("rds_parameter_group_" + instance.parameter_group.name), hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'rds_parameter_groups', self.to_safe("rds_parameter_group_" + instance.parameter_group.name))
-
-        # Global Tag: all RDS instances
-        self.push(self.inventory, 'rds', hostname)
-
-        self.inventory["_meta"]["hostvars"][hostname] = self.get_host_info_dict_from_instance(instance)
-        self.inventory["_meta"]["hostvars"][hostname]['ansible_ssh_host'] = dest
-
-    def add_elasticache_cluster(self, cluster, region):
-        ''' Adds an ElastiCache cluster to the inventory and index, as long as
-        it's nodes are addressable '''
-
-        # Only want available clusters unless all_elasticache_clusters is True
-        if not self.all_elasticache_clusters and cluster['CacheClusterStatus'] != 'available':
-            return
-
-        # Select the best destination address
-        if 'ConfigurationEndpoint' in cluster and cluster['ConfigurationEndpoint']:
-            # Memcached cluster
-            dest = cluster['ConfigurationEndpoint']['Address']
-            is_redis = False
-        else:
-            # Redis sigle node cluster
-            # Because all Redis clusters are single nodes, we'll merge the
-            # info from the cluster with info about the node
-            dest = cluster['CacheNodes'][0]['Endpoint']['Address']
-            is_redis = True
-
-        if not dest:
-            # Skip clusters we cannot address (e.g. private VPC subnet)
-            return
-
-        # Add to index
-        self.index[dest] = [region, cluster['CacheClusterId']]
-
-        # Inventory: Group by instance ID (always a group of 1)
-        if self.group_by_instance_id:
-            self.inventory[cluster['CacheClusterId']] = [dest]
-            if self.nested_groups:
-                self.push_group(self.inventory, 'instances', cluster['CacheClusterId'])
-
-        # Inventory: Group by region
-        if self.group_by_region and not is_redis:
-            self.push(self.inventory, region, dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'regions', region)
-
-        # Inventory: Group by availability zone
-        if self.group_by_availability_zone and not is_redis:
-            self.push(self.inventory, cluster['PreferredAvailabilityZone'], dest)
-            if self.nested_groups:
-                if self.group_by_region:
-                    self.push_group(self.inventory, region, cluster['PreferredAvailabilityZone'])
-                self.push_group(self.inventory, 'zones', cluster['PreferredAvailabilityZone'])
-
-        # Inventory: Group by node type
-        if self.group_by_instance_type and not is_redis:
-            type_name = self.to_safe('type_' + cluster['CacheNodeType'])
-            self.push(self.inventory, type_name, dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'types', type_name)
-
-        # Inventory: Group by VPC (information not available in the current
-        # AWS API version for ElastiCache)
-
-        # Inventory: Group by security group
-        if self.group_by_security_group and not is_redis:
-
-            # Check for the existence of the 'SecurityGroups' key and also if
-            # this key has some value. When the cluster is not placed in a SG
-            # the query can return None here and cause an error.
-            if 'SecurityGroups' in cluster and cluster['SecurityGroups'] is not None:
-                for security_group in cluster['SecurityGroups']:
-                    key = self.to_safe("security_group_" + security_group['SecurityGroupId'])
-                    self.push(self.inventory, key, dest)
-                    if self.nested_groups:
-                        self.push_group(self.inventory, 'security_groups', key)
-
-        # Inventory: Group by engine
-        if self.group_by_elasticache_engine and not is_redis:
-            self.push(self.inventory, self.to_safe("elasticache_" + cluster['Engine']), dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'elasticache_engines', self.to_safe(cluster['Engine']))
-
-        # Inventory: Group by parameter group
-        if self.group_by_elasticache_parameter_group:
-            self.push(self.inventory, self.to_safe("elasticache_parameter_group_" + cluster['CacheParameterGroup']['CacheParameterGroupName']), dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'elasticache_parameter_groups', self.to_safe(cluster['CacheParameterGroup']['CacheParameterGroupName']))
-
-        # Inventory: Group by replication group
-        if self.group_by_elasticache_replication_group and 'ReplicationGroupId' in cluster and cluster['ReplicationGroupId']:
-            self.push(self.inventory, self.to_safe("elasticache_replication_group_" + cluster['ReplicationGroupId']), dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'elasticache_replication_groups', self.to_safe(cluster['ReplicationGroupId']))
-
-        # Global Tag: all ElastiCache clusters
-        self.push(self.inventory, 'elasticache_clusters', cluster['CacheClusterId'])
-
-        host_info = self.get_host_info_dict_from_describe_dict(cluster)
-
-        self.inventory["_meta"]["hostvars"][dest] = host_info
-
-        # Add the nodes
-        for node in cluster['CacheNodes']:
-            self.add_elasticache_node(node, cluster, region)
-
-    def add_elasticache_node(self, node, cluster, region):
-        ''' Adds an ElastiCache node to the inventory and index, as long as
-        it is addressable '''
-
-        # Only want available nodes unless all_elasticache_nodes is True
-        if not self.all_elasticache_nodes and node['CacheNodeStatus'] != 'available':
-            return
-
-        # Select the best destination address
-        dest = node['Endpoint']['Address']
-
-        if not dest:
-            # Skip nodes we cannot address (e.g. private VPC subnet)
-            return
-
-        node_id = self.to_safe(cluster['CacheClusterId'] + '_' + node['CacheNodeId'])
-
-        # Add to index
-        self.index[dest] = [region, node_id]
-
-        # Inventory: Group by node ID (always a group of 1)
-        if self.group_by_instance_id:
-            self.inventory[node_id] = [dest]
-            if self.nested_groups:
-                self.push_group(self.inventory, 'instances', node_id)
-
-        # Inventory: Group by region
-        if self.group_by_region:
-            self.push(self.inventory, region, dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'regions', region)
-
-        # Inventory: Group by availability zone
-        if self.group_by_availability_zone:
-            self.push(self.inventory, cluster['PreferredAvailabilityZone'], dest)
-            if self.nested_groups:
-                if self.group_by_region:
-                    self.push_group(self.inventory, region, cluster['PreferredAvailabilityZone'])
-                self.push_group(self.inventory, 'zones', cluster['PreferredAvailabilityZone'])
-
-        # Inventory: Group by node type
-        if self.group_by_instance_type:
-            type_name = self.to_safe('type_' + cluster['CacheNodeType'])
-            self.push(self.inventory, type_name, dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'types', type_name)
-
-        # Inventory: Group by VPC (information not available in the current
-        # AWS API version for ElastiCache)
-
-        # Inventory: Group by security group
-        if self.group_by_security_group:
-
-            # Check for the existence of the 'SecurityGroups' key and also if
-            # this key has some value. When the cluster is not placed in a SG
-            # the query can return None here and cause an error.
-            if 'SecurityGroups' in cluster and cluster['SecurityGroups'] is not None:
-                for security_group in cluster['SecurityGroups']:
-                    key = self.to_safe("security_group_" + security_group['SecurityGroupId'])
-                    self.push(self.inventory, key, dest)
-                    if self.nested_groups:
-                        self.push_group(self.inventory, 'security_groups', key)
-
-        # Inventory: Group by engine
-        if self.group_by_elasticache_engine:
-            self.push(self.inventory, self.to_safe("elasticache_" + cluster['Engine']), dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'elasticache_engines', self.to_safe("elasticache_" + cluster['Engine']))
-
-        # Inventory: Group by parameter group (done at cluster level)
-
-        # Inventory: Group by replication group (done at cluster level)
-
-        # Inventory: Group by ElastiCache Cluster
-        if self.group_by_elasticache_cluster:
-            self.push(self.inventory, self.to_safe("elasticache_cluster_" + cluster['CacheClusterId']), dest)
-
-        # Global Tag: all ElastiCache nodes
-        self.push(self.inventory, 'elasticache_nodes', dest)
-
-        host_info = self.get_host_info_dict_from_describe_dict(node)
-
-        if dest in self.inventory["_meta"]["hostvars"]:
-            self.inventory["_meta"]["hostvars"][dest].update(host_info)
-        else:
-            self.inventory["_meta"]["hostvars"][dest] = host_info
-
-    def add_elasticache_replication_group(self, replication_group, region):
-        ''' Adds an ElastiCache replication group to the inventory and index '''
-
-        # Only want available clusters unless all_elasticache_replication_groups is True
-        if not self.all_elasticache_replication_groups and replication_group['Status'] != 'available':
-            return
-
-        # Select the best destination address (PrimaryEndpoint)
-        dest = replication_group['NodeGroups'][0]['PrimaryEndpoint']['Address']
-
-        if not dest:
-            # Skip clusters we cannot address (e.g. private VPC subnet)
-            return
-
-        # Add to index
-        self.index[dest] = [region, replication_group['ReplicationGroupId']]
-
-        # Inventory: Group by ID (always a group of 1)
-        if self.group_by_instance_id:
-            self.inventory[replication_group['ReplicationGroupId']] = [dest]
-            if self.nested_groups:
-                self.push_group(self.inventory, 'instances', replication_group['ReplicationGroupId'])
-
-        # Inventory: Group by region
-        if self.group_by_region:
-            self.push(self.inventory, region, dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'regions', region)
-
-        # Inventory: Group by availability zone (doesn't apply to replication groups)
-
-        # Inventory: Group by node type (doesn't apply to replication groups)
-
-        # Inventory: Group by VPC (information not available in the current
-        # AWS API version for replication groups
-
-        # Inventory: Group by security group (doesn't apply to replication groups)
-        # Check this value in cluster level
-
-        # Inventory: Group by engine (replication groups are always Redis)
-        if self.group_by_elasticache_engine:
-            self.push(self.inventory, 'elasticache_redis', dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'elasticache_engines', 'redis')
-
-        # Global Tag: all ElastiCache clusters
-        self.push(self.inventory, 'elasticache_replication_groups', replication_group['ReplicationGroupId'])
-
-        host_info = self.get_host_info_dict_from_describe_dict(replication_group)
-
-        self.inventory["_meta"]["hostvars"][dest] = host_info
-
-    def get_route53_records(self):
-        ''' Get and store the map of resource records to domain names that
-        point to them. '''
-
-        r53_conn = route53.Route53Connection()
-        all_zones = r53_conn.get_zones()
-
-        route53_zones = [ zone for zone in all_zones if zone.name[:-1]
-                          not in self.route53_excluded_zones ]
-
-        self.route53_records = {}
-
-        for zone in route53_zones:
-            rrsets = r53_conn.get_all_rrsets(zone.id)
-
-            for record_set in rrsets:
-                record_name = record_set.name
-
-                if record_name.endswith('.'):
-                    record_name = record_name[:-1]
-
-                for resource in record_set.resource_records:
-                    self.route53_records.setdefault(resource, set())
-                    self.route53_records[resource].add(record_name)
-
-
-    def get_instance_route53_names(self, instance):
-        ''' Check if an instance is referenced in the records we have from
-        Route53. If it is, return the list of domain names pointing to said
-        instance. If nothing points to it, return an empty list. '''
-
-        instance_attributes = [ 'public_dns_name', 'private_dns_name',
-                                'ip_address', 'private_ip_address' ]
-
-        name_list = set()
-
-        for attrib in instance_attributes:
-            try:
-                value = getattr(instance, attrib)
-            except AttributeError:
-                continue
-
-            if value in self.route53_records:
-                name_list.update(self.route53_records[value])
-
-        return list(name_list)
-
-    def get_host_info_dict_from_instance(self, instance):
-        instance_vars = {}
-        for key in vars(instance):
-            value = getattr(instance, key)
-            key = self.to_safe('ec2_' + key)
-
-            # Handle complex types
-            # state/previous_state changed to properties in boto in https://github.com/boto/boto/commit/a23c379837f698212252720d2af8dec0325c9518
-            if key == 'ec2__state':
-                instance_vars['ec2_state'] = instance.state or ''
-                instance_vars['ec2_state_code'] = instance.state_code
-            elif key == 'ec2__previous_state':
-                instance_vars['ec2_previous_state'] = instance.previous_state or ''
-                instance_vars['ec2_previous_state_code'] = instance.previous_state_code
-            elif type(value) in [int, bool]:
-                instance_vars[key] = value
-            elif isinstance(value, six.string_types):
-                instance_vars[key] = value.strip()
-            elif type(value) == type(None):
-                instance_vars[key] = ''
-            elif key == 'ec2_region':
-                instance_vars[key] = value.name
-            elif key == 'ec2__placement':
-                instance_vars['ec2_placement'] = value.zone
-            elif key == 'ec2_tags':
-                for k, v in value.items():
-                    if self.expand_csv_tags and ',' in v:
-                        v = map(lambda x: x.strip(), v.split(','))
-                    key = self.to_safe('ec2_tag_' + k)
-                    instance_vars[key] = v
-            elif key == 'ec2_groups':
-                group_ids = []
-                group_names = []
-                for group in value:
-                    group_ids.append(group.id)
-                    group_names.append(group.name)
-                instance_vars["ec2_security_group_ids"] = ','.join([str(i) for i in group_ids])
-                instance_vars["ec2_security_group_names"] = ','.join([str(i) for i in group_names])
-            else:
-                pass
-                # TODO Product codes if someone finds them useful
-                #print key
-                #print type(value)
-                #print value
-
-        return instance_vars
-
-    def get_host_info_dict_from_describe_dict(self, describe_dict):
-        ''' Parses the dictionary returned by the API call into a flat list
-            of parameters. This method should be used only when 'describe' is
-            used directly because Boto doesn't provide specific classes. '''
-
-        # I really don't agree with prefixing everything with 'ec2'
-        # because EC2, RDS and ElastiCache are different services.
-        # I'm just following the pattern used until now to not break any
-        # compatibility.
-
-        host_info = {}
-        for key in describe_dict:
-            value = describe_dict[key]
-            key = self.to_safe('ec2_' + self.uncammelize(key))
-
-            # Handle complex types
-
-            # Target: Memcached Cache Clusters
-            if key == 'ec2_configuration_endpoint' and value:
-                host_info['ec2_configuration_endpoint_address'] = value['Address']
-                host_info['ec2_configuration_endpoint_port'] = value['Port']
-
-            # Target: Cache Nodes and Redis Cache Clusters (single node)
-            if key == 'ec2_endpoint' and value:
-                host_info['ec2_endpoint_address'] = value['Address']
-                host_info['ec2_endpoint_port'] = value['Port']
-
-            # Target: Redis Replication Groups
-            if key == 'ec2_node_groups' and value:
-                host_info['ec2_endpoint_address'] = value[0]['PrimaryEndpoint']['Address']
-                host_info['ec2_endpoint_port'] = value[0]['PrimaryEndpoint']['Port']
-                replica_count = 0
-                for node in value[0]['NodeGroupMembers']:
-                    if node['CurrentRole'] == 'primary':
-                        host_info['ec2_primary_cluster_address'] = node['ReadEndpoint']['Address']
-                        host_info['ec2_primary_cluster_port'] = node['ReadEndpoint']['Port']
-                        host_info['ec2_primary_cluster_id'] = node['CacheClusterId']
-                    elif node['CurrentRole'] == 'replica':
-                        host_info['ec2_replica_cluster_address_'+ str(replica_count)] = node['ReadEndpoint']['Address']
-                        host_info['ec2_replica_cluster_port_'+ str(replica_count)] = node['ReadEndpoint']['Port']
-                        host_info['ec2_replica_cluster_id_'+ str(replica_count)] = node['CacheClusterId']
-                        replica_count += 1
-
-            # Target: Redis Replication Groups
-            if key == 'ec2_member_clusters' and value:
-                host_info['ec2_member_clusters'] = ','.join([str(i) for i in value])
-
-            # Target: All Cache Clusters
-            elif key == 'ec2_cache_parameter_group':
-                host_info["ec2_cache_node_ids_to_reboot"] = ','.join([str(i) for i in value['CacheNodeIdsToReboot']])
-                host_info['ec2_cache_parameter_group_name'] = value['CacheParameterGroupName']
-                host_info['ec2_cache_parameter_apply_status'] = value['ParameterApplyStatus']
-
-            # Target: Almost everything
-            elif key == 'ec2_security_groups':
-
-                # Skip if SecurityGroups is None
-                # (it is possible to have the key defined but no value in it).
-                if value is not None:
-                    sg_ids = []
-                    for sg in value:
-                        sg_ids.append(sg['SecurityGroupId'])
-                    host_info["ec2_security_group_ids"] = ','.join([str(i) for i in sg_ids])
-
-            # Target: Everything
-            # Preserve booleans and integers
-            elif type(value) in [int, bool]:
-                host_info[key] = value
-
-            # Target: Everything
-            # Sanitize string values
-            elif isinstance(value, six.string_types):
-                host_info[key] = value.strip()
-
-            # Target: Everything
-            # Replace None by an empty string
-            elif type(value) == type(None):
-                host_info[key] = ''
-
-            else:
-                # Remove non-processed complex types
-                pass
-
-        return host_info
-
-    def get_host_info(self):
-        ''' Get variables about a specific host '''
-
-        if len(self.index) == 0:
-            # Need to load index from cache
-            self.load_index_from_cache()
-
-        if not self.args.host in self.index:
-            # try updating the cache
-            self.do_api_calls_update_cache()
-            if not self.args.host in self.index:
-                # host might not exist anymore
-                return self.json_format_dict({}, True)
-
-        (region, instance_id) = self.index[self.args.host]
-
-        instance = self.get_instance(region, instance_id)
-        return self.json_format_dict(self.get_host_info_dict_from_instance(instance), True)
-
-    def push(self, my_dict, key, element):
-        ''' Push an element onto an array that may not have been defined in
-        the dict '''
-        group_info = my_dict.setdefault(key, [])
-        if isinstance(group_info, dict):
-            host_list = group_info.setdefault('hosts', [])
-            host_list.append(element)
-        else:
-            group_info.append(element)
-
-    def push_group(self, my_dict, key, element):
-        ''' Push a group as a child of another group. '''
-        parent_group = my_dict.setdefault(key, {})
-        if not isinstance(parent_group, dict):
-            parent_group = my_dict[key] = {'hosts': parent_group}
-        child_groups = parent_group.setdefault('children', [])
-        if element not in child_groups:
-            child_groups.append(element)
-
-    def get_inventory_from_cache(self):
-        ''' Reads the inventory from the cache file and returns it as a JSON
-        object '''
-
-        cache = open(self.cache_path_cache, 'r')
-        json_inventory = cache.read()
-        return json_inventory
-
-
-    def load_index_from_cache(self):
-        ''' Reads the index from the cache file sets self.index '''
-
-        cache = open(self.cache_path_index, 'r')
-        json_index = cache.read()
-        self.index = json.loads(json_index)
-
-
-    def write_to_cache(self, data, filename):
-        ''' Writes data in JSON format to a file '''
-
-        json_data = self.json_format_dict(data, True)
-        cache = open(filename, 'w')
-        cache.write(json_data)
-        cache.close()
-
-    def uncammelize(self, key):
-        temp = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', key)
-        return re.sub('([a-z0-9])([A-Z])', r'\1_\2', temp).lower()
-
-    def to_safe(self, word):
-        ''' Converts 'bad' characters in a string to underscores so they can be used as Ansible groups '''
-        regex = "[^A-Za-z0-9\_"
-        if not self.replace_dash_in_groups:
-            regex += "\-"
-        return re.sub(regex + "]", "_", word)
-
-    def json_format_dict(self, data, pretty=False):
-        ''' Converts a dict to a JSON object and dumps it as a formatted
-        string '''
-
-        if pretty:
-            return json.dumps(data, sort_keys=True, indent=2)
-        else:
-            return json.dumps(data)
-
-
-# Run the script
-Ec2Inventory()
diff --git a/edge-1609-dc3-dc4/inventory-dc3 b/edge-1609-dc3-dc4/inventory-dc3
deleted file mode 100644
index 27e2114..0000000
--- a/edge-1609-dc3-dc4/inventory-dc3
+++ /dev/null
@@ -1,87 +0,0 @@
-[tag_Name_dc3_n1]
-[tag_Name_dc3_n2]
-[tag_Name_dc3_n3]
-[tag_Name_dc3_n4]
-[tag_Name_dc3_n5]
-[tag_Name_dc3_n6]
-[tag_Name_dc3_n7]
-[tag_Name_dc3_n8]
-[tag_Name_dc3_n9]
-[tag_Name_dc3_n10]
-[tag_Name_dc3_n11]
-
-[planet:children]
-dc-1
-
-[dc-1:children]
-tag_Name_dc3_n1
-tag_Name_dc3_n2
-tag_Name_dc3_n3
-tag_Name_dc3_n4
-tag_Name_dc3_n5
-tag_Name_dc3_n6
-tag_Name_dc3_n7
-tag_Name_dc3_n8
-tag_Name_dc3_n9
-tag_Name_dc3_n10
-tag_Name_dc3_n11
-
-[ds:children]
-dc-1-ds
-
-[dc-1-ds:children]
-tag_Name_dc3_n2
-tag_Name_dc3_n3
-tag_Name_dc3_n4
-
-[ms:children]
-dc-1-ms
-
-[dc-1-ms:children]
-tag_Name_dc3_n1
-
-[ui:children]
-dc-1-ui
-
-[dc-1-ui:children]
-tag_Name_dc3_n1
-
-[ldap:children]
-dc-1-ldap
-
-[dc-1-ldap:children]
-tag_Name_dc3_n1
-
-[rmp:children]
-dc-1-rmp
-
-[dc-1-rmp:children]
-tag_Name_dc3_n5
-tag_Name_dc3_n6
-
-[qpid:children]
-dc-1-qpid
-
-[dc-1-qpid:children]
-tag_Name_dc3_n7
-tag_Name_dc3_n8
-
-[pg:children]
-dc-1-pg
-
-[dc-1-pg:children]
-dc-1-pgmaster
-dc-1-pgstandby
-
-[pgmaster:children]
-dc-1-pgmaster
-
-[dc-1-pgmaster:children]
-tag_Name_dc3_n9
-
-[pgstandby:children]
-dc-1-pgstandby
-
-[dc-1-pgstandby:children]
-tag_Name_dc3_n10
-
diff --git a/edge-1609-dc3-dc4/inventory-dc4 b/edge-1609-dc3-dc4/inventory-dc4
deleted file mode 100644
index 1fa13b5..0000000
--- a/edge-1609-dc3-dc4/inventory-dc4
+++ /dev/null
@@ -1,87 +0,0 @@
-[tag_Name_dc4_n1]
-[tag_Name_dc4_n2]
-[tag_Name_dc4_n3]
-[tag_Name_dc4_n4]
-[tag_Name_dc4_n5]
-[tag_Name_dc4_n6]
-[tag_Name_dc4_n7]
-[tag_Name_dc4_n8]
-[tag_Name_dc4_n9]
-[tag_Name_dc4_n10]
-[tag_Name_dc4_n11]
-
-[planet:children]
-dc-2
-
-[dc-2:children]
-tag_Name_dc4_n1
-tag_Name_dc4_n2
-tag_Name_dc4_n3
-tag_Name_dc4_n4
-tag_Name_dc4_n5
-tag_Name_dc4_n6
-tag_Name_dc4_n7
-tag_Name_dc4_n8
-tag_Name_dc4_n9
-tag_Name_dc4_n10
-tag_Name_dc4_n11
-
-[ds:children]
-dc-2-ds
-
-[dc-2-ds:children]
-tag_Name_dc4_n2
-tag_Name_dc4_n3
-tag_Name_dc4_n4
-
-[ms:children]
-dc-2-ms
-
-[dc-2-ms:children]
-tag_Name_dc4_n1
-
-[ui:children]
-dc-2-ui
-
-[dc-2-ui:children]
-tag_Name_dc4_n1
-
-[ldap:children]
-dc-2-ldap
-
-[dc-2-ldap:children]
-tag_Name_dc4_n1
-
-[rmp:children]
-dc-2-rmp
-
-[dc-2-rmp:children]
-tag_Name_dc4_n5
-tag_Name_dc4_n6
-
-[qpid:children]
-dc-2-qpid
-
-[dc-2-qpid:children]
-tag_Name_dc4_n7
-tag_Name_dc4_n8
-
-[pg:children]
-dc-2-pg
-
-[dc-2-pg:children]
-dc-2-pgmaster
-dc-2-pgstandby
-
-[pgmaster:children]
-dc-2-pgmaster
-
-[dc-2-pgmaster:children]
-tag_Name_dc4_n9
-
-[pgstandby:children]
-dc-2-pgstandby
-
-[dc-2-pgstandby:children]
-tag_Name_dc4_n10
-
diff --git a/edge-1609-dc3/ec2.ini b/edge-1609-dc3/ec2.ini
deleted file mode 100644
index 36b3921..0000000
--- a/edge-1609-dc3/ec2.ini
+++ /dev/null
@@ -1,200 +0,0 @@
-# Ansible EC2 external inventory script settings
-#
-
-[ec2]
-
-# to talk to a private eucalyptus instance uncomment these lines
-# and edit edit eucalyptus_host to be the host name of your cloud controller
-#eucalyptus = True
-#eucalyptus_host = clc.cloud.domain.org
-
-# AWS regions to make calls to. Set this to 'all' to make request to all regions
-# in AWS and merge the results together. Alternatively, set this to a comma
-# separated list of regions. E.g. 'us-east-1,us-west-1,us-west-2'
-regions = all
-regions_exclude = us-gov-west-1,cn-north-1
-
-# When generating inventory, Ansible needs to know how to address a server.
-# Each EC2 instance has a lot of variables associated with it. Here is the list:
-#   http://docs.pythonboto.org/en/latest/ref/ec2.html#module-boto.ec2.instance
-# Below are 2 variables that are used as the address of a server:
-#   - destination_variable
-#   - vpc_destination_variable
-
-# This is the normal destination variable to use. If you are running Ansible
-# from outside EC2, then 'public_dns_name' makes the most sense. If you are
-# running Ansible from within EC2, then perhaps you want to use the internal
-# address, and should set this to 'private_dns_name'. The key of an EC2 tag
-# may optionally be used; however the boto instance variables hold precedence
-# in the event of a collision.
-destination_variable = public_dns_name
-
-# This allows you to override the inventory_name with an ec2 variable, instead
-# of using the destination_variable above. Addressing (aka ansible_ssh_host)
-# will still use destination_variable. Tags should be written as 'tag_TAGNAME'.
-#hostname_variable = tag_Name
-
-# For server inside a VPC, using DNS names may not make sense. When an instance
-# has 'subnet_id' set, this variable is used. If the subnet is public, setting
-# this to 'ip_address' will return the public IP address. For instances in a
-# private subnet, this should be set to 'private_ip_address', and Ansible must
-# be run from within EC2. The key of an EC2 tag may optionally be used; however
-# the boto instance variables hold precedence in the event of a collision.
-# WARNING: - instances that are in the private vpc, _without_ public ip address
-# will not be listed in the inventory until You set:
-# vpc_destination_variable = private_ip_address
-vpc_destination_variable = ip_address
-
-# The following two settings allow flexible ansible host naming based on a
-# python format string and a comma-separated list of ec2 tags.  Note that:
-#
-# 1) If the tags referenced are not present for some instances, empty strings
-#    will be substituted in the format string.
-# 2) This overrides both destination_variable and vpc_destination_variable.
-#
-#destination_format = {0}.{1}.example.com
-#destination_format_tags = Name,environment
-
-# To tag instances on EC2 with the resource records that point to them from
-# Route53, uncomment and set 'route53' to True.
-route53 = False
-
-# To exclude RDS instances from the inventory, uncomment and set to False.
-rds = False
-
-# To exclude ElastiCache instances from the inventory, uncomment and set to False.
-elasticache = False
-
-# Additionally, you can specify the list of zones to exclude looking up in
-# 'route53_excluded_zones' as a comma-separated list.
-# route53_excluded_zones = samplezone1.com, samplezone2.com
-
-# By default, only EC2 instances in the 'running' state are returned. Set
-# 'all_instances' to True to return all instances regardless of state.
-all_instances = True
-
-# By default, only EC2 instances in the 'running' state are returned. Specify
-# EC2 instance states to return as a comma-separated list. This
-# option is overriden when 'all_instances' is True.
-# instance_states = pending, running, shutting-down, terminated, stopping, stopped
-
-# By default, only RDS instances in the 'available' state are returned.  Set
-# 'all_rds_instances' to True return all RDS instances regardless of state.
-all_rds_instances = False
-
-# By default, only ElastiCache clusters and nodes in the 'available' state
-# are returned. Set 'all_elasticache_clusters' and/or 'all_elastic_nodes'
-# to True return all ElastiCache clusters and nodes, regardless of state.
-#
-# Note that all_elasticache_nodes only applies to listed clusters. That means
-# if you set all_elastic_clusters to false, no node will be return from
-# unavailable clusters, regardless of the state and to what you set for
-# all_elasticache_nodes.
-all_elasticache_replication_groups = False
-all_elasticache_clusters = False
-all_elasticache_nodes = False
-
-# API calls to EC2 are slow. For this reason, we cache the results of an API
-# call. Set this to the path you want cache files to be written to. Two files
-# will be written to this directory:
-#   - ansible-ec2.cache
-#   - ansible-ec2.index
-cache_path = ~/.ansible/tmp
-
-# The number of seconds a cache file is considered valid. After this many
-# seconds, a new API call will be made, and the cache file will be updated.
-# To disable the cache, set this value to 0
-cache_max_age = 300
-
-# Organize groups into a nested/hierarchy instead of a flat namespace.
-nested_groups = False
-
-# Replace - tags when creating groups to avoid issues with ansible
-replace_dash_in_groups = True
-
-# If set to true, any tag of the form "a,b,c" is expanded into a list
-# and the results are used to create additional tag_* inventory groups.
-expand_csv_tags = False
-
-# The EC2 inventory output can become very large. To manage its size,
-# configure which groups should be created.
-group_by_instance_id = True
-group_by_region = True
-group_by_availability_zone = True
-group_by_ami_id = True
-group_by_instance_type = True
-group_by_key_pair = True
-group_by_vpc_id = True
-group_by_security_group = True
-group_by_tag_keys = True
-group_by_tag_none = True
-group_by_route53_names = True
-group_by_rds_engine = False
-group_by_rds_parameter_group = False
-group_by_elasticache_engine = True
-group_by_elasticache_cluster = True
-group_by_elasticache_parameter_group = True
-group_by_elasticache_replication_group = True
-
-# If you only want to include hosts that match a certain regular expression
-# pattern_include = staging-*
-
-# If you want to exclude any hosts that match a certain regular expression
-# pattern_exclude = staging-*
-# Ansible EC2 external inventory script settings
-#
-
-##[ec2]
-##
-### to talk to a private eucalyptus instance uncomment these lines
-### and edit edit eucalyptus_host to be the host name of your cloud controller
-###eucalyptus = True
-###eucalyptus_host = clc.cloud.domain.org
-##
-### AWS regions to make calls to. Set this to 'all' to make request to all regions
-##
-### in AWS and merge the results together. Alternatively, set this to a comma
-### separated list of regions. E.g. 'us-east-1,us-west-1,us-west-2'
-##regions = all
-##regions_exclude = us-gov-west-1,cn-north-1
-##
-### When generating inventory, Ansible needs to know how to address a server.
-### Each EC2 instance has a lot of variables associated with it. Here is the list:
-###   http://docs.pythonboto.org/en/latest/ref/ec2.html#module-boto.ec2.instance
-### Below are 2 variables that are used as the address of a server:
-###   - destination_variable
-###   - vpc_destination_variable
-##
-### This is the normal destination variable to use. If you are running Ansible
-### from outside EC2, then 'public_dns_name' makes the most sense. If you are
-### running Ansible from within EC2, then perhaps you want to use the internal
-### address, and should set this to 'private_dns_name'. The key of an EC2 tag
-##...skipping...
-### pattern_include = staging-*
-##
-### If you want to exclude any hosts that match a certain regular expression
-### pattern_exclude = staging-*
-
-# Instance filters can be used to control which instances are retrieved for
-# inventory. For the full list of possible filters, please read the EC2 API
-# docs: http://docs.aws.amazon.com/AWSEC2/latest/APIReference/ApiReference-query-DescribeInstances.html#query-DescribeInstances-filters
-# Filters are key/value pairs separated by '=', to list multiple filters use
-# a list separated by commas. See examples below.
-
-# Retrieve only instances with (key=value) env=staging tag
-# instance_filters = tag:env=staging
-
-# Retrieve only instances with role=webservers OR role=dbservers tag
-# instance_filters = tag:role=webservers,tag:role=dbservers
-
-# Retrieve only t1.micro instances OR instances with tag env=staging
-# instance_filters = instance-type=t1.micro,tag:env=staging
-
-# You can use wildcards in filter values also. Below will list instances which
-# tag Name value matches webservers1*
-# (ex. webservers15, webservers1a, webservers123 etc)
-# instance_filters = tag:Name=webservers1*
-
-# A boto configuration profile may be used to separate out credentials
-# see http://boto.readthedocs.org/en/latest/boto_config_tut.html
-# boto_profile = some-boto-profile-name
diff --git a/edge-1609-dc3/ec2.py b/edge-1609-dc3/ec2.py
deleted file mode 100755
index f30958a..0000000
--- a/edge-1609-dc3/ec2.py
+++ /dev/null
@@ -1,1385 +0,0 @@
-#!/usr/bin/env python
-
-'''
-EC2 external inventory script
-=================================
-
-Generates inventory that Ansible can understand by making API request to
-AWS EC2 using the Boto library.
-
-NOTE: This script assumes Ansible is being executed where the environment
-variables needed for Boto have already been set:
-    export AWS_ACCESS_KEY_ID='AK123'
-    export AWS_SECRET_ACCESS_KEY='abc123'
-
-This script also assumes there is an ec2.ini file alongside it.  To specify a
-different path to ec2.ini, define the EC2_INI_PATH environment variable:
-
-    export EC2_INI_PATH=/path/to/my_ec2.ini
-
-If you're using eucalyptus you need to set the above variables and
-you need to define:
-
-    export EC2_URL=http://hostname_of_your_cc:port/services/Eucalyptus
-
-If you're using boto profiles (requires boto>=2.24.0) you can choose a profile
-using the --boto-profile command line argument (e.g. ec2.py --boto-profile prod) or using
-the AWS_PROFILE variable:
-
-    AWS_PROFILE=prod ansible-playbook -i ec2.py myplaybook.yml
-
-For more details, see: http://docs.pythonboto.org/en/latest/boto_config_tut.html
-
-When run against a specific host, this script returns the following variables:
- - ec2_ami_launch_index
- - ec2_architecture
- - ec2_association
- - ec2_attachTime
- - ec2_attachment
- - ec2_attachmentId
- - ec2_client_token
- - ec2_deleteOnTermination
- - ec2_description
- - ec2_deviceIndex
- - ec2_dns_name
- - ec2_eventsSet
- - ec2_group_name
- - ec2_hypervisor
- - ec2_id
- - ec2_image_id
- - ec2_instanceState
- - ec2_instance_type
- - ec2_ipOwnerId
- - ec2_ip_address
- - ec2_item
- - ec2_kernel
- - ec2_key_name
- - ec2_launch_time
- - ec2_monitored
- - ec2_monitoring
- - ec2_networkInterfaceId
- - ec2_ownerId
- - ec2_persistent
- - ec2_placement
- - ec2_platform
- - ec2_previous_state
- - ec2_private_dns_name
- - ec2_private_ip_address
- - ec2_publicIp
- - ec2_public_dns_name
- - ec2_ramdisk
- - ec2_reason
- - ec2_region
- - ec2_requester_id
- - ec2_root_device_name
- - ec2_root_device_type
- - ec2_security_group_ids
- - ec2_security_group_names
- - ec2_shutdown_state
- - ec2_sourceDestCheck
- - ec2_spot_instance_request_id
- - ec2_state
- - ec2_state_code
- - ec2_state_reason
- - ec2_status
- - ec2_subnet_id
- - ec2_tenancy
- - ec2_virtualization_type
- - ec2_vpc_id
-
-These variables are pulled out of a boto.ec2.instance object. There is a lack of
-consistency with variable spellings (camelCase and underscores) since this
-just loops through all variables the object exposes. It is preferred to use the
-ones with underscores when multiple exist.
-
-In addition, if an instance has AWS Tags associated with it, each tag is a new
-variable named:
- - ec2_tag_[Key] = [Value]
-
-Security groups are comma-separated in 'ec2_security_group_ids' and
-'ec2_security_group_names'.
-'''
-
-# (c) 2012, Peter Sankauskas
-#
-# This file is part of Ansible,
-#
-# Ansible is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# Ansible is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with Ansible.  If not, see <http://www.gnu.org/licenses/>.
-
-######################################################################
-
-import sys
-import os
-import argparse
-import re
-from time import time
-import boto
-from boto import ec2
-from boto import rds
-from boto import elasticache
-from boto import route53
-import six
-
-from six.moves import configparser
-from collections import defaultdict
-
-try:
-    import json
-except ImportError:
-    import simplejson as json
-
-
-class Ec2Inventory(object):
-
-    def _empty_inventory(self):
-        return {"_meta" : {"hostvars" : {}}}
-
-    def __init__(self):
-        ''' Main execution path '''
-
-        # Inventory grouped by instance IDs, tags, security groups, regions,
-        # and availability zones
-        self.inventory = self._empty_inventory()
-
-        # Index of hostname (address) to instance ID
-        self.index = {}
-
-        # Boto profile to use (if any)
-        self.boto_profile = None
-
-        # Read settings and parse CLI arguments
-        self.parse_cli_args()
-        self.read_settings()
-
-        # Make sure that profile_name is not passed at all if not set
-        # as pre 2.24 boto will fall over otherwise
-        if self.boto_profile:
-            if not hasattr(boto.ec2.EC2Connection, 'profile_name'):
-                self.fail_with_error("boto version must be >= 2.24 to use profile")
-
-        # Cache
-        if self.args.refresh_cache:
-            self.do_api_calls_update_cache()
-        elif not self.is_cache_valid():
-            self.do_api_calls_update_cache()
-
-        # Data to print
-        if self.args.host:
-            data_to_print = self.get_host_info()
-
-        elif self.args.list:
-            # Display list of instances for inventory
-            if self.inventory == self._empty_inventory():
-                data_to_print = self.get_inventory_from_cache()
-            else:
-                data_to_print = self.json_format_dict(self.inventory, True)
-
-        print(data_to_print)
-
-
-    def is_cache_valid(self):
-        ''' Determines if the cache files have expired, or if it is still valid '''
-
-        if os.path.isfile(self.cache_path_cache):
-            mod_time = os.path.getmtime(self.cache_path_cache)
-            current_time = time()
-            if (mod_time + self.cache_max_age) > current_time:
-                if os.path.isfile(self.cache_path_index):
-                    return True
-
-        return False
-
-
-    def read_settings(self):
-        ''' Reads the settings from the ec2.ini file '''
-        if six.PY3:
-            config = configparser.ConfigParser()
-        else:
-            config = configparser.SafeConfigParser()
-        ec2_default_ini_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'ec2.ini')
-        ec2_ini_path = os.path.expanduser(os.path.expandvars(os.environ.get('EC2_INI_PATH', ec2_default_ini_path)))
-        config.read(ec2_ini_path)
-
-        # is eucalyptus?
-        self.eucalyptus_host = None
-        self.eucalyptus = False
-        if config.has_option('ec2', 'eucalyptus'):
-            self.eucalyptus = config.getboolean('ec2', 'eucalyptus')
-        if self.eucalyptus and config.has_option('ec2', 'eucalyptus_host'):
-            self.eucalyptus_host = config.get('ec2', 'eucalyptus_host')
-
-        # Regions
-        self.regions = []
-        configRegions = config.get('ec2', 'regions')
-        configRegions_exclude = config.get('ec2', 'regions_exclude')
-        if (configRegions == 'all'):
-            if self.eucalyptus_host:
-                self.regions.append(boto.connect_euca(host=self.eucalyptus_host).region.name)
-            else:
-                for regionInfo in ec2.regions():
-                    if regionInfo.name not in configRegions_exclude:
-                        self.regions.append(regionInfo.name)
-        else:
-            self.regions = configRegions.split(",")
-
-        # Destination addresses
-        self.destination_variable = config.get('ec2', 'destination_variable')
-        self.vpc_destination_variable = config.get('ec2', 'vpc_destination_variable')
-
-        if config.has_option('ec2', 'hostname_variable'):
-            self.hostname_variable = config.get('ec2', 'hostname_variable')
-        else:
-            self.hostname_variable = None
-
-        if config.has_option('ec2', 'destination_format') and \
-                config.has_option('ec2', 'destination_format_tags'):
-            self.destination_format = config.get('ec2', 'destination_format')
-            self.destination_format_tags = config.get('ec2', 'destination_format_tags').split(',')
-        else:
-            self.destination_format = None
-            self.destination_format_tags = None
-
-        # Route53
-        self.route53_enabled = config.getboolean('ec2', 'route53')
-        self.route53_excluded_zones = []
-        if config.has_option('ec2', 'route53_excluded_zones'):
-            self.route53_excluded_zones.extend(
-                    config.get('ec2', 'route53_excluded_zones', '').split(','))
-
-        # Include RDS instances?
-        self.rds_enabled = True
-        if config.has_option('ec2', 'rds'):
-            self.rds_enabled = config.getboolean('ec2', 'rds')
-
-        # Include ElastiCache instances?
-        self.elasticache_enabled = True
-        if config.has_option('ec2', 'elasticache'):
-            self.elasticache_enabled = config.getboolean('ec2', 'elasticache')
-
-        # Return all EC2 instances?
-        if config.has_option('ec2', 'all_instances'):
-            self.all_instances = config.getboolean('ec2', 'all_instances')
-        else:
-            self.all_instances = False
-
-        # Instance states to be gathered in inventory. Default is 'running'.
-        # Setting 'all_instances' to 'yes' overrides this option.
-        ec2_valid_instance_states = [
-            'pending',
-            'running',
-            'shutting-down',
-            'terminated',
-            'stopping',
-            'stopped'
-        ]
-        self.ec2_instance_states = []
-        if self.all_instances:
-            self.ec2_instance_states = ec2_valid_instance_states
-        elif config.has_option('ec2', 'instance_states'):
-            for instance_state in config.get('ec2', 'instance_states').split(','):
-                instance_state = instance_state.strip()
-                if instance_state not in ec2_valid_instance_states:
-                    continue
-                self.ec2_instance_states.append(instance_state)
-        else:
-            self.ec2_instance_states = ['running']
-
-        # Return all RDS instances? (if RDS is enabled)
-        if config.has_option('ec2', 'all_rds_instances') and self.rds_enabled:
-            self.all_rds_instances = config.getboolean('ec2', 'all_rds_instances')
-        else:
-            self.all_rds_instances = False
-
-        # Return all ElastiCache replication groups? (if ElastiCache is enabled)
-        if config.has_option('ec2', 'all_elasticache_replication_groups') and self.elasticache_enabled:
-            self.all_elasticache_replication_groups = config.getboolean('ec2', 'all_elasticache_replication_groups')
-        else:
-            self.all_elasticache_replication_groups = False
-
-        # Return all ElastiCache clusters? (if ElastiCache is enabled)
-        if config.has_option('ec2', 'all_elasticache_clusters') and self.elasticache_enabled:
-            self.all_elasticache_clusters = config.getboolean('ec2', 'all_elasticache_clusters')
-        else:
-            self.all_elasticache_clusters = False
-
-        # Return all ElastiCache nodes? (if ElastiCache is enabled)
-        if config.has_option('ec2', 'all_elasticache_nodes') and self.elasticache_enabled:
-            self.all_elasticache_nodes = config.getboolean('ec2', 'all_elasticache_nodes')
-        else:
-            self.all_elasticache_nodes = False
-
-        # boto configuration profile (prefer CLI argument)
-        self.boto_profile = self.args.boto_profile
-        if config.has_option('ec2', 'boto_profile') and not self.boto_profile:
-            self.boto_profile = config.get('ec2', 'boto_profile')
-
-        # Cache related
-        cache_dir = os.path.expanduser(config.get('ec2', 'cache_path'))
-        if self.boto_profile:
-            cache_dir = os.path.join(cache_dir, 'profile_' + self.boto_profile)
-        if not os.path.exists(cache_dir):
-            os.makedirs(cache_dir)
-
-        cache_name = 'ansible-ec2'
-        aws_profile = lambda: (self.boto_profile or
-                               os.environ.get('AWS_PROFILE') or
-                               os.environ.get('AWS_ACCESS_KEY_ID'))
-        if aws_profile():
-            cache_name = '%s-%s' % (cache_name, aws_profile())
-        self.cache_path_cache = cache_dir + "/%s.cache" % cache_name
-        self.cache_path_index = cache_dir + "/%s.index" % cache_name
-        self.cache_max_age = config.getint('ec2', 'cache_max_age')
-
-        if config.has_option('ec2', 'expand_csv_tags'):
-            self.expand_csv_tags = config.getboolean('ec2', 'expand_csv_tags')
-        else:
-            self.expand_csv_tags = False
-
-        # Configure nested groups instead of flat namespace.
-        if config.has_option('ec2', 'nested_groups'):
-            self.nested_groups = config.getboolean('ec2', 'nested_groups')
-        else:
-            self.nested_groups = False
-
-        # Replace dash or not in group names
-        if config.has_option('ec2', 'replace_dash_in_groups'):
-            self.replace_dash_in_groups = config.getboolean('ec2', 'replace_dash_in_groups')
-        else:
-            self.replace_dash_in_groups = True
-
-        # Configure which groups should be created.
-        group_by_options = [
-            'group_by_instance_id',
-            'group_by_region',
-            'group_by_availability_zone',
-            'group_by_ami_id',
-            'group_by_instance_type',
-            'group_by_key_pair',
-            'group_by_vpc_id',
-            'group_by_security_group',
-            'group_by_tag_keys',
-            'group_by_tag_none',
-            'group_by_route53_names',
-            'group_by_rds_engine',
-            'group_by_rds_parameter_group',
-            'group_by_elasticache_engine',
-            'group_by_elasticache_cluster',
-            'group_by_elasticache_parameter_group',
-            'group_by_elasticache_replication_group',
-        ]
-        for option in group_by_options:
-            if config.has_option('ec2', option):
-                setattr(self, option, config.getboolean('ec2', option))
-            else:
-                setattr(self, option, True)
-
-        # Do we need to just include hosts that match a pattern?
-        try:
-            pattern_include = config.get('ec2', 'pattern_include')
-            if pattern_include and len(pattern_include) > 0:
-                self.pattern_include = re.compile(pattern_include)
-            else:
-                self.pattern_include = None
-        except configparser.NoOptionError:
-            self.pattern_include = None
-
-        # Do we need to exclude hosts that match a pattern?
-        try:
-            pattern_exclude = config.get('ec2', 'pattern_exclude');
-            if pattern_exclude and len(pattern_exclude) > 0:
-                self.pattern_exclude = re.compile(pattern_exclude)
-            else:
-                self.pattern_exclude = None
-        except configparser.NoOptionError:
-            self.pattern_exclude = None
-
-        # Instance filters (see boto and EC2 API docs). Ignore invalid filters.
-        self.ec2_instance_filters = defaultdict(list)
-        if config.has_option('ec2', 'instance_filters'):
-
-            filters = [f for f in config.get('ec2', 'instance_filters').split(',') if f]
-
-            for instance_filter in filters:
-                instance_filter = instance_filter.strip()
-                if not instance_filter or '=' not in instance_filter:
-                    continue
-                filter_key, filter_value = [x.strip() for x in instance_filter.split('=', 1)]
-                if not filter_key:
-                    continue
-                self.ec2_instance_filters[filter_key].append(filter_value)
-
-    def parse_cli_args(self):
-        ''' Command line argument processing '''
-
-        parser = argparse.ArgumentParser(description='Produce an Ansible Inventory file based on EC2')
-        parser.add_argument('--list', action='store_true', default=True,
-                            help='List instances (default: True)')
-        parser.add_argument('--host', action='store',
-                            help='Get all the variables about a specific instance')
-        parser.add_argument('--refresh-cache', action='store_true', default=False,
-                            help='Force refresh of cache by making API requests to EC2 (default: False - use cache files)')
-        parser.add_argument('--profile', '--boto-profile', action='store', dest='boto_profile',
-                            help='Use boto profile for connections to EC2')
-        self.args = parser.parse_args()
-
-
-    def do_api_calls_update_cache(self):
-        ''' Do API calls to each region, and save data in cache files '''
-
-        if self.route53_enabled:
-            self.get_route53_records()
-
-        for region in self.regions:
-            self.get_instances_by_region(region)
-            if self.rds_enabled:
-                self.get_rds_instances_by_region(region)
-            if self.elasticache_enabled:
-                self.get_elasticache_clusters_by_region(region)
-                self.get_elasticache_replication_groups_by_region(region)
-
-        self.write_to_cache(self.inventory, self.cache_path_cache)
-        self.write_to_cache(self.index, self.cache_path_index)
-
-    def connect(self, region):
-        ''' create connection to api server'''
-        if self.eucalyptus:
-            conn = boto.connect_euca(host=self.eucalyptus_host)
-            conn.APIVersion = '2010-08-31'
-        else:
-            conn = self.connect_to_aws(ec2, region)
-        return conn
-
-    def boto_fix_security_token_in_profile(self, connect_args):
-        ''' monkey patch for boto issue boto/boto#2100 '''
-        profile = 'profile ' + self.boto_profile
-        if boto.config.has_option(profile, 'aws_security_token'):
-            connect_args['security_token'] = boto.config.get(profile, 'aws_security_token')
-        return connect_args
-
-    def connect_to_aws(self, module, region):
-        connect_args = {}
-
-        # only pass the profile name if it's set (as it is not supported by older boto versions)
-        if self.boto_profile:
-            connect_args['profile_name'] = self.boto_profile
-            self.boto_fix_security_token_in_profile(connect_args)
-
-        conn = module.connect_to_region(region, **connect_args)
-        # connect_to_region will fail "silently" by returning None if the region name is wrong or not supported
-        if conn is None:
-            self.fail_with_error("region name: %s likely not supported, or AWS is down.  connection to region failed." % region)
-        return conn
-
-    def get_instances_by_region(self, region):
-        ''' Makes an AWS EC2 API call to the list of instances in a particular
-        region '''
-
-        try:
-            conn = self.connect(region)
-            reservations = []
-            if self.ec2_instance_filters:
-                for filter_key, filter_values in self.ec2_instance_filters.items():
-                    reservations.extend(conn.get_all_instances(filters = { filter_key : filter_values }))
-            else:
-                reservations = conn.get_all_instances()
-
-            for reservation in reservations:
-                for instance in reservation.instances:
-                    self.add_instance(instance, region)
-
-        except boto.exception.BotoServerError as e:
-            if e.error_code == 'AuthFailure':
-                error = self.get_auth_error_message()
-            else:
-                backend = 'Eucalyptus' if self.eucalyptus else 'AWS'
-                error = "Error connecting to %s backend.\n%s" % (backend, e.message)
-            self.fail_with_error(error, 'getting EC2 instances')
-
-    def get_rds_instances_by_region(self, region):
-        ''' Makes an AWS API call to the list of RDS instances in a particular
-        region '''
-
-        try:
-            conn = self.connect_to_aws(rds, region)
-            if conn:
-                marker = None
-                while True:
-                    instances = conn.get_all_dbinstances(marker=marker)
-                    marker = instances.marker
-                    for instance in instances:
-                        self.add_rds_instance(instance, region)
-                    if not marker:
-                        break
-        except boto.exception.BotoServerError as e:
-            error = e.reason
-
-            if e.error_code == 'AuthFailure':
-                error = self.get_auth_error_message()
-            if not e.reason == "Forbidden":
-                error = "Looks like AWS RDS is down:\n%s" % e.message
-            self.fail_with_error(error, 'getting RDS instances')
-
-    def get_elasticache_clusters_by_region(self, region):
-        ''' Makes an AWS API call to the list of ElastiCache clusters (with
-        nodes' info) in a particular region.'''
-
-        # ElastiCache boto module doesn't provide a get_all_intances method,
-        # that's why we need to call describe directly (it would be called by
-        # the shorthand method anyway...)
-        try:
-            conn = self.connect_to_aws(elasticache, region)
-            if conn:
-                # show_cache_node_info = True
-                # because we also want nodes' information
-                response = conn.describe_cache_clusters(None, None, None, True)
-
-        except boto.exception.BotoServerError as e:
-            error = e.reason
-
-            if e.error_code == 'AuthFailure':
-                error = self.get_auth_error_message()
-            if not e.reason == "Forbidden":
-                error = "Looks like AWS ElastiCache is down:\n%s" % e.message
-            self.fail_with_error(error, 'getting ElastiCache clusters')
-
-        try:
-            # Boto also doesn't provide wrapper classes to CacheClusters or
-            # CacheNodes. Because of that wo can't make use of the get_list
-            # method in the AWSQueryConnection. Let's do the work manually
-            clusters = response['DescribeCacheClustersResponse']['DescribeCacheClustersResult']['CacheClusters']
-
-        except KeyError as e:
-            error = "ElastiCache query to AWS failed (unexpected format)."
-            self.fail_with_error(error, 'getting ElastiCache clusters')
-
-        for cluster in clusters:
-            self.add_elasticache_cluster(cluster, region)
-
-    def get_elasticache_replication_groups_by_region(self, region):
-        ''' Makes an AWS API call to the list of ElastiCache replication groups
-        in a particular region.'''
-
-        # ElastiCache boto module doesn't provide a get_all_intances method,
-        # that's why we need to call describe directly (it would be called by
-        # the shorthand method anyway...)
-        try:
-            conn = self.connect_to_aws(elasticache, region)
-            if conn:
-                response = conn.describe_replication_groups()
-
-        except boto.exception.BotoServerError as e:
-            error = e.reason
-
-            if e.error_code == 'AuthFailure':
-                error = self.get_auth_error_message()
-            if not e.reason == "Forbidden":
-                error = "Looks like AWS ElastiCache [Replication Groups] is down:\n%s" % e.message
-            self.fail_with_error(error, 'getting ElastiCache clusters')
-
-        try:
-            # Boto also doesn't provide wrapper classes to ReplicationGroups
-            # Because of that wo can't make use of the get_list method in the
-            # AWSQueryConnection. Let's do the work manually
-            replication_groups = response['DescribeReplicationGroupsResponse']['DescribeReplicationGroupsResult']['ReplicationGroups']
-
-        except KeyError as e:
-            error = "ElastiCache [Replication Groups] query to AWS failed (unexpected format)."
-            self.fail_with_error(error, 'getting ElastiCache clusters')
-
-        for replication_group in replication_groups:
-            self.add_elasticache_replication_group(replication_group, region)
-
-    def get_auth_error_message(self):
-        ''' create an informative error message if there is an issue authenticating'''
-        errors = ["Authentication error retrieving ec2 inventory."]
-        if None in [os.environ.get('AWS_ACCESS_KEY_ID'), os.environ.get('AWS_SECRET_ACCESS_KEY')]:
-            errors.append(' - No AWS_ACCESS_KEY_ID or AWS_SECRET_ACCESS_KEY environment vars found')
-        else:
-            errors.append(' - AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY environment vars found but may not be correct')
-
-        boto_paths = ['/etc/boto.cfg', '~/.boto', '~/.aws/credentials']
-        boto_config_found = list(p for p in boto_paths if os.path.isfile(os.path.expanduser(p)))
-        if len(boto_config_found) > 0:
-            errors.append(" - Boto configs found at '%s', but the credentials contained may not be correct" % ', '.join(boto_config_found))
-        else:
-            errors.append(" - No Boto config found at any expected location '%s'" % ', '.join(boto_paths))
-
-        return '\n'.join(errors)
-
-    def fail_with_error(self, err_msg, err_operation=None):
-        '''log an error to std err for ansible-playbook to consume and exit'''
-        if err_operation:
-            err_msg = 'ERROR: "{err_msg}", while: {err_operation}'.format(
-                    err_msg=err_msg, err_operation=err_operation)
-        sys.stderr.write(err_msg)
-        sys.exit(1)
-
-    def get_instance(self, region, instance_id):
-        conn = self.connect(region)
-
-        reservations = conn.get_all_instances([instance_id])
-        for reservation in reservations:
-            for instance in reservation.instances:
-                return instance
-
-    def add_instance(self, instance, region):
-        ''' Adds an instance to the inventory and index, as long as it is
-        addressable '''
-
-        # Only return instances with desired instance states
-        if instance.state not in self.ec2_instance_states:
-            return
-
-        # Select the best destination address
-        if self.destination_format and self.destination_format_tags:
-            dest = self.destination_format.format(*[ getattr(instance, 'tags').get(tag, '') for tag in self.destination_format_tags ])
-        elif instance.subnet_id:
-            dest = getattr(instance, self.vpc_destination_variable, None)
-            if dest is None:
-                dest = getattr(instance, 'tags').get(self.vpc_destination_variable, None)
-        else:
-            dest = getattr(instance, self.destination_variable, None)
-            if dest is None:
-                dest = getattr(instance, 'tags').get(self.destination_variable, None)
-
-        if not dest:
-            # Skip instances we cannot address (e.g. private VPC subnet)
-            return
-
-        # Set the inventory name
-        hostname = None
-        if self.hostname_variable:
-            if self.hostname_variable.startswith('tag_'):
-                hostname = instance.tags.get(self.hostname_variable[4:], None)
-            else:
-                hostname = getattr(instance, self.hostname_variable)
-
-        # If we can't get a nice hostname, use the destination address
-        if not hostname:
-            hostname = dest
-        else:
-            hostname = self.to_safe(hostname).lower()
-
-        # if we only want to include hosts that match a pattern, skip those that don't
-        if self.pattern_include and not self.pattern_include.match(hostname):
-            return
-
-        # if we need to exclude hosts that match a pattern, skip those
-        if self.pattern_exclude and self.pattern_exclude.match(hostname):
-            return
-
-        # Add to index
-        self.index[hostname] = [region, instance.id]
-
-        # Inventory: Group by instance ID (always a group of 1)
-        if self.group_by_instance_id:
-            self.inventory[instance.id] = [hostname]
-            if self.nested_groups:
-                self.push_group(self.inventory, 'instances', instance.id)
-
-        # Inventory: Group by region
-        if self.group_by_region:
-            self.push(self.inventory, region, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'regions', region)
-
-        # Inventory: Group by availability zone
-        if self.group_by_availability_zone:
-            self.push(self.inventory, instance.placement, hostname)
-            if self.nested_groups:
-                if self.group_by_region:
-                    self.push_group(self.inventory, region, instance.placement)
-                self.push_group(self.inventory, 'zones', instance.placement)
-
-        # Inventory: Group by Amazon Machine Image (AMI) ID
-        if self.group_by_ami_id:
-            ami_id = self.to_safe(instance.image_id)
-            self.push(self.inventory, ami_id, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'images', ami_id)
-
-        # Inventory: Group by instance type
-        if self.group_by_instance_type:
-            type_name = self.to_safe('type_' + instance.instance_type)
-            self.push(self.inventory, type_name, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'types', type_name)
-
-        # Inventory: Group by key pair
-        if self.group_by_key_pair and instance.key_name:
-            key_name = self.to_safe('key_' + instance.key_name)
-            self.push(self.inventory, key_name, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'keys', key_name)
-
-        # Inventory: Group by VPC
-        if self.group_by_vpc_id and instance.vpc_id:
-            vpc_id_name = self.to_safe('vpc_id_' + instance.vpc_id)
-            self.push(self.inventory, vpc_id_name, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'vpcs', vpc_id_name)
-
-        # Inventory: Group by security group
-        if self.group_by_security_group:
-            try:
-                for group in instance.groups:
-                    key = self.to_safe("security_group_" + group.name)
-                    self.push(self.inventory, key, hostname)
-                    if self.nested_groups:
-                        self.push_group(self.inventory, 'security_groups', key)
-            except AttributeError:
-                self.fail_with_error('\n'.join(['Package boto seems a bit older.',
-                                                'Please upgrade boto >= 2.3.0.']))
-
-        # Inventory: Group by tag keys
-        if self.group_by_tag_keys:
-            for k, v in instance.tags.items():
-                if self.expand_csv_tags and v and ',' in v:
-                    values = map(lambda x: x.strip(), v.split(','))
-                else:
-                    values = [v]
-
-                for v in values:
-                    if v:
-                        key = self.to_safe("tag_" + k + "=" + v)
-                    else:
-                        key = self.to_safe("tag_" + k)
-                    self.push(self.inventory, key, hostname)
-                    if self.nested_groups:
-                        self.push_group(self.inventory, 'tags', self.to_safe("tag_" + k))
-                        if v:
-                            self.push_group(self.inventory, self.to_safe("tag_" + k), key)
-
-        # Inventory: Group by Route53 domain names if enabled
-        if self.route53_enabled and self.group_by_route53_names:
-            route53_names = self.get_instance_route53_names(instance)
-            for name in route53_names:
-                self.push(self.inventory, name, hostname)
-                if self.nested_groups:
-                    self.push_group(self.inventory, 'route53', name)
-
-        # Global Tag: instances without tags
-        if self.group_by_tag_none and len(instance.tags) == 0:
-            self.push(self.inventory, 'tag_none', hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'tags', 'tag_none')
-
-        # Global Tag: tag all EC2 instances
-        self.push(self.inventory, 'ec2', hostname)
-
-        self.inventory["_meta"]["hostvars"][hostname] = self.get_host_info_dict_from_instance(instance)
-        self.inventory["_meta"]["hostvars"][hostname]['ansible_ssh_host'] = dest
-
-
-    def add_rds_instance(self, instance, region):
-        ''' Adds an RDS instance to the inventory and index, as long as it is
-        addressable '''
-
-        # Only want available instances unless all_rds_instances is True
-        if not self.all_rds_instances and instance.status != 'available':
-            return
-
-        # Select the best destination address
-        dest = instance.endpoint[0]
-
-        if not dest:
-            # Skip instances we cannot address (e.g. private VPC subnet)
-            return
-
-        # Set the inventory name
-        hostname = None
-        if self.hostname_variable:
-            if self.hostname_variable.startswith('tag_'):
-                hostname = instance.tags.get(self.hostname_variable[4:], None)
-            else:
-                hostname = getattr(instance, self.hostname_variable)
-
-        # If we can't get a nice hostname, use the destination address
-        if not hostname:
-            hostname = dest
-
-        hostname = self.to_safe(hostname).lower()
-
-        # Add to index
-        self.index[hostname] = [region, instance.id]
-
-        # Inventory: Group by instance ID (always a group of 1)
-        if self.group_by_instance_id:
-            self.inventory[instance.id] = [hostname]
-            if self.nested_groups:
-                self.push_group(self.inventory, 'instances', instance.id)
-
-        # Inventory: Group by region
-        if self.group_by_region:
-            self.push(self.inventory, region, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'regions', region)
-
-        # Inventory: Group by availability zone
-        if self.group_by_availability_zone:
-            self.push(self.inventory, instance.availability_zone, hostname)
-            if self.nested_groups:
-                if self.group_by_region:
-                    self.push_group(self.inventory, region, instance.availability_zone)
-                self.push_group(self.inventory, 'zones', instance.availability_zone)
-
-        # Inventory: Group by instance type
-        if self.group_by_instance_type:
-            type_name = self.to_safe('type_' + instance.instance_class)
-            self.push(self.inventory, type_name, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'types', type_name)
-
-        # Inventory: Group by VPC
-        if self.group_by_vpc_id and instance.subnet_group and instance.subnet_group.vpc_id:
-            vpc_id_name = self.to_safe('vpc_id_' + instance.subnet_group.vpc_id)
-            self.push(self.inventory, vpc_id_name, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'vpcs', vpc_id_name)
-
-        # Inventory: Group by security group
-        if self.group_by_security_group:
-            try:
-                if instance.security_group:
-                    key = self.to_safe("security_group_" + instance.security_group.name)
-                    self.push(self.inventory, key, hostname)
-                    if self.nested_groups:
-                        self.push_group(self.inventory, 'security_groups', key)
-
-            except AttributeError:
-                self.fail_with_error('\n'.join(['Package boto seems a bit older.',
-                                                'Please upgrade boto >= 2.3.0.']))
-
-
-        # Inventory: Group by engine
-        if self.group_by_rds_engine:
-            self.push(self.inventory, self.to_safe("rds_" + instance.engine), hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'rds_engines', self.to_safe("rds_" + instance.engine))
-
-        # Inventory: Group by parameter group
-        if self.group_by_rds_parameter_group:
-            self.push(self.inventory, self.to_safe("rds_parameter_group_" + instance.parameter_group.name), hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'rds_parameter_groups', self.to_safe("rds_parameter_group_" + instance.parameter_group.name))
-
-        # Global Tag: all RDS instances
-        self.push(self.inventory, 'rds', hostname)
-
-        self.inventory["_meta"]["hostvars"][hostname] = self.get_host_info_dict_from_instance(instance)
-        self.inventory["_meta"]["hostvars"][hostname]['ansible_ssh_host'] = dest
-
-    def add_elasticache_cluster(self, cluster, region):
-        ''' Adds an ElastiCache cluster to the inventory and index, as long as
-        it's nodes are addressable '''
-
-        # Only want available clusters unless all_elasticache_clusters is True
-        if not self.all_elasticache_clusters and cluster['CacheClusterStatus'] != 'available':
-            return
-
-        # Select the best destination address
-        if 'ConfigurationEndpoint' in cluster and cluster['ConfigurationEndpoint']:
-            # Memcached cluster
-            dest = cluster['ConfigurationEndpoint']['Address']
-            is_redis = False
-        else:
-            # Redis sigle node cluster
-            # Because all Redis clusters are single nodes, we'll merge the
-            # info from the cluster with info about the node
-            dest = cluster['CacheNodes'][0]['Endpoint']['Address']
-            is_redis = True
-
-        if not dest:
-            # Skip clusters we cannot address (e.g. private VPC subnet)
-            return
-
-        # Add to index
-        self.index[dest] = [region, cluster['CacheClusterId']]
-
-        # Inventory: Group by instance ID (always a group of 1)
-        if self.group_by_instance_id:
-            self.inventory[cluster['CacheClusterId']] = [dest]
-            if self.nested_groups:
-                self.push_group(self.inventory, 'instances', cluster['CacheClusterId'])
-
-        # Inventory: Group by region
-        if self.group_by_region and not is_redis:
-            self.push(self.inventory, region, dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'regions', region)
-
-        # Inventory: Group by availability zone
-        if self.group_by_availability_zone and not is_redis:
-            self.push(self.inventory, cluster['PreferredAvailabilityZone'], dest)
-            if self.nested_groups:
-                if self.group_by_region:
-                    self.push_group(self.inventory, region, cluster['PreferredAvailabilityZone'])
-                self.push_group(self.inventory, 'zones', cluster['PreferredAvailabilityZone'])
-
-        # Inventory: Group by node type
-        if self.group_by_instance_type and not is_redis:
-            type_name = self.to_safe('type_' + cluster['CacheNodeType'])
-            self.push(self.inventory, type_name, dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'types', type_name)
-
-        # Inventory: Group by VPC (information not available in the current
-        # AWS API version for ElastiCache)
-
-        # Inventory: Group by security group
-        if self.group_by_security_group and not is_redis:
-
-            # Check for the existence of the 'SecurityGroups' key and also if
-            # this key has some value. When the cluster is not placed in a SG
-            # the query can return None here and cause an error.
-            if 'SecurityGroups' in cluster and cluster['SecurityGroups'] is not None:
-                for security_group in cluster['SecurityGroups']:
-                    key = self.to_safe("security_group_" + security_group['SecurityGroupId'])
-                    self.push(self.inventory, key, dest)
-                    if self.nested_groups:
-                        self.push_group(self.inventory, 'security_groups', key)
-
-        # Inventory: Group by engine
-        if self.group_by_elasticache_engine and not is_redis:
-            self.push(self.inventory, self.to_safe("elasticache_" + cluster['Engine']), dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'elasticache_engines', self.to_safe(cluster['Engine']))
-
-        # Inventory: Group by parameter group
-        if self.group_by_elasticache_parameter_group:
-            self.push(self.inventory, self.to_safe("elasticache_parameter_group_" + cluster['CacheParameterGroup']['CacheParameterGroupName']), dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'elasticache_parameter_groups', self.to_safe(cluster['CacheParameterGroup']['CacheParameterGroupName']))
-
-        # Inventory: Group by replication group
-        if self.group_by_elasticache_replication_group and 'ReplicationGroupId' in cluster and cluster['ReplicationGroupId']:
-            self.push(self.inventory, self.to_safe("elasticache_replication_group_" + cluster['ReplicationGroupId']), dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'elasticache_replication_groups', self.to_safe(cluster['ReplicationGroupId']))
-
-        # Global Tag: all ElastiCache clusters
-        self.push(self.inventory, 'elasticache_clusters', cluster['CacheClusterId'])
-
-        host_info = self.get_host_info_dict_from_describe_dict(cluster)
-
-        self.inventory["_meta"]["hostvars"][dest] = host_info
-
-        # Add the nodes
-        for node in cluster['CacheNodes']:
-            self.add_elasticache_node(node, cluster, region)
-
-    def add_elasticache_node(self, node, cluster, region):
-        ''' Adds an ElastiCache node to the inventory and index, as long as
-        it is addressable '''
-
-        # Only want available nodes unless all_elasticache_nodes is True
-        if not self.all_elasticache_nodes and node['CacheNodeStatus'] != 'available':
-            return
-
-        # Select the best destination address
-        dest = node['Endpoint']['Address']
-
-        if not dest:
-            # Skip nodes we cannot address (e.g. private VPC subnet)
-            return
-
-        node_id = self.to_safe(cluster['CacheClusterId'] + '_' + node['CacheNodeId'])
-
-        # Add to index
-        self.index[dest] = [region, node_id]
-
-        # Inventory: Group by node ID (always a group of 1)
-        if self.group_by_instance_id:
-            self.inventory[node_id] = [dest]
-            if self.nested_groups:
-                self.push_group(self.inventory, 'instances', node_id)
-
-        # Inventory: Group by region
-        if self.group_by_region:
-            self.push(self.inventory, region, dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'regions', region)
-
-        # Inventory: Group by availability zone
-        if self.group_by_availability_zone:
-            self.push(self.inventory, cluster['PreferredAvailabilityZone'], dest)
-            if self.nested_groups:
-                if self.group_by_region:
-                    self.push_group(self.inventory, region, cluster['PreferredAvailabilityZone'])
-                self.push_group(self.inventory, 'zones', cluster['PreferredAvailabilityZone'])
-
-        # Inventory: Group by node type
-        if self.group_by_instance_type:
-            type_name = self.to_safe('type_' + cluster['CacheNodeType'])
-            self.push(self.inventory, type_name, dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'types', type_name)
-
-        # Inventory: Group by VPC (information not available in the current
-        # AWS API version for ElastiCache)
-
-        # Inventory: Group by security group
-        if self.group_by_security_group:
-
-            # Check for the existence of the 'SecurityGroups' key and also if
-            # this key has some value. When the cluster is not placed in a SG
-            # the query can return None here and cause an error.
-            if 'SecurityGroups' in cluster and cluster['SecurityGroups'] is not None:
-                for security_group in cluster['SecurityGroups']:
-                    key = self.to_safe("security_group_" + security_group['SecurityGroupId'])
-                    self.push(self.inventory, key, dest)
-                    if self.nested_groups:
-                        self.push_group(self.inventory, 'security_groups', key)
-
-        # Inventory: Group by engine
-        if self.group_by_elasticache_engine:
-            self.push(self.inventory, self.to_safe("elasticache_" + cluster['Engine']), dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'elasticache_engines', self.to_safe("elasticache_" + cluster['Engine']))
-
-        # Inventory: Group by parameter group (done at cluster level)
-
-        # Inventory: Group by replication group (done at cluster level)
-
-        # Inventory: Group by ElastiCache Cluster
-        if self.group_by_elasticache_cluster:
-            self.push(self.inventory, self.to_safe("elasticache_cluster_" + cluster['CacheClusterId']), dest)
-
-        # Global Tag: all ElastiCache nodes
-        self.push(self.inventory, 'elasticache_nodes', dest)
-
-        host_info = self.get_host_info_dict_from_describe_dict(node)
-
-        if dest in self.inventory["_meta"]["hostvars"]:
-            self.inventory["_meta"]["hostvars"][dest].update(host_info)
-        else:
-            self.inventory["_meta"]["hostvars"][dest] = host_info
-
-    def add_elasticache_replication_group(self, replication_group, region):
-        ''' Adds an ElastiCache replication group to the inventory and index '''
-
-        # Only want available clusters unless all_elasticache_replication_groups is True
-        if not self.all_elasticache_replication_groups and replication_group['Status'] != 'available':
-            return
-
-        # Select the best destination address (PrimaryEndpoint)
-        dest = replication_group['NodeGroups'][0]['PrimaryEndpoint']['Address']
-
-        if not dest:
-            # Skip clusters we cannot address (e.g. private VPC subnet)
-            return
-
-        # Add to index
-        self.index[dest] = [region, replication_group['ReplicationGroupId']]
-
-        # Inventory: Group by ID (always a group of 1)
-        if self.group_by_instance_id:
-            self.inventory[replication_group['ReplicationGroupId']] = [dest]
-            if self.nested_groups:
-                self.push_group(self.inventory, 'instances', replication_group['ReplicationGroupId'])
-
-        # Inventory: Group by region
-        if self.group_by_region:
-            self.push(self.inventory, region, dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'regions', region)
-
-        # Inventory: Group by availability zone (doesn't apply to replication groups)
-
-        # Inventory: Group by node type (doesn't apply to replication groups)
-
-        # Inventory: Group by VPC (information not available in the current
-        # AWS API version for replication groups
-
-        # Inventory: Group by security group (doesn't apply to replication groups)
-        # Check this value in cluster level
-
-        # Inventory: Group by engine (replication groups are always Redis)
-        if self.group_by_elasticache_engine:
-            self.push(self.inventory, 'elasticache_redis', dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'elasticache_engines', 'redis')
-
-        # Global Tag: all ElastiCache clusters
-        self.push(self.inventory, 'elasticache_replication_groups', replication_group['ReplicationGroupId'])
-
-        host_info = self.get_host_info_dict_from_describe_dict(replication_group)
-
-        self.inventory["_meta"]["hostvars"][dest] = host_info
-
-    def get_route53_records(self):
-        ''' Get and store the map of resource records to domain names that
-        point to them. '''
-
-        r53_conn = route53.Route53Connection()
-        all_zones = r53_conn.get_zones()
-
-        route53_zones = [ zone for zone in all_zones if zone.name[:-1]
-                          not in self.route53_excluded_zones ]
-
-        self.route53_records = {}
-
-        for zone in route53_zones:
-            rrsets = r53_conn.get_all_rrsets(zone.id)
-
-            for record_set in rrsets:
-                record_name = record_set.name
-
-                if record_name.endswith('.'):
-                    record_name = record_name[:-1]
-
-                for resource in record_set.resource_records:
-                    self.route53_records.setdefault(resource, set())
-                    self.route53_records[resource].add(record_name)
-
-
-    def get_instance_route53_names(self, instance):
-        ''' Check if an instance is referenced in the records we have from
-        Route53. If it is, return the list of domain names pointing to said
-        instance. If nothing points to it, return an empty list. '''
-
-        instance_attributes = [ 'public_dns_name', 'private_dns_name',
-                                'ip_address', 'private_ip_address' ]
-
-        name_list = set()
-
-        for attrib in instance_attributes:
-            try:
-                value = getattr(instance, attrib)
-            except AttributeError:
-                continue
-
-            if value in self.route53_records:
-                name_list.update(self.route53_records[value])
-
-        return list(name_list)
-
-    def get_host_info_dict_from_instance(self, instance):
-        instance_vars = {}
-        for key in vars(instance):
-            value = getattr(instance, key)
-            key = self.to_safe('ec2_' + key)
-
-            # Handle complex types
-            # state/previous_state changed to properties in boto in https://github.com/boto/boto/commit/a23c379837f698212252720d2af8dec0325c9518
-            if key == 'ec2__state':
-                instance_vars['ec2_state'] = instance.state or ''
-                instance_vars['ec2_state_code'] = instance.state_code
-            elif key == 'ec2__previous_state':
-                instance_vars['ec2_previous_state'] = instance.previous_state or ''
-                instance_vars['ec2_previous_state_code'] = instance.previous_state_code
-            elif type(value) in [int, bool]:
-                instance_vars[key] = value
-            elif isinstance(value, six.string_types):
-                instance_vars[key] = value.strip()
-            elif type(value) == type(None):
-                instance_vars[key] = ''
-            elif key == 'ec2_region':
-                instance_vars[key] = value.name
-            elif key == 'ec2__placement':
-                instance_vars['ec2_placement'] = value.zone
-            elif key == 'ec2_tags':
-                for k, v in value.items():
-                    if self.expand_csv_tags and ',' in v:
-                        v = map(lambda x: x.strip(), v.split(','))
-                    key = self.to_safe('ec2_tag_' + k)
-                    instance_vars[key] = v
-            elif key == 'ec2_groups':
-                group_ids = []
-                group_names = []
-                for group in value:
-                    group_ids.append(group.id)
-                    group_names.append(group.name)
-                instance_vars["ec2_security_group_ids"] = ','.join([str(i) for i in group_ids])
-                instance_vars["ec2_security_group_names"] = ','.join([str(i) for i in group_names])
-            else:
-                pass
-                # TODO Product codes if someone finds them useful
-                #print key
-                #print type(value)
-                #print value
-
-        return instance_vars
-
-    def get_host_info_dict_from_describe_dict(self, describe_dict):
-        ''' Parses the dictionary returned by the API call into a flat list
-            of parameters. This method should be used only when 'describe' is
-            used directly because Boto doesn't provide specific classes. '''
-
-        # I really don't agree with prefixing everything with 'ec2'
-        # because EC2, RDS and ElastiCache are different services.
-        # I'm just following the pattern used until now to not break any
-        # compatibility.
-
-        host_info = {}
-        for key in describe_dict:
-            value = describe_dict[key]
-            key = self.to_safe('ec2_' + self.uncammelize(key))
-
-            # Handle complex types
-
-            # Target: Memcached Cache Clusters
-            if key == 'ec2_configuration_endpoint' and value:
-                host_info['ec2_configuration_endpoint_address'] = value['Address']
-                host_info['ec2_configuration_endpoint_port'] = value['Port']
-
-            # Target: Cache Nodes and Redis Cache Clusters (single node)
-            if key == 'ec2_endpoint' and value:
-                host_info['ec2_endpoint_address'] = value['Address']
-                host_info['ec2_endpoint_port'] = value['Port']
-
-            # Target: Redis Replication Groups
-            if key == 'ec2_node_groups' and value:
-                host_info['ec2_endpoint_address'] = value[0]['PrimaryEndpoint']['Address']
-                host_info['ec2_endpoint_port'] = value[0]['PrimaryEndpoint']['Port']
-                replica_count = 0
-                for node in value[0]['NodeGroupMembers']:
-                    if node['CurrentRole'] == 'primary':
-                        host_info['ec2_primary_cluster_address'] = node['ReadEndpoint']['Address']
-                        host_info['ec2_primary_cluster_port'] = node['ReadEndpoint']['Port']
-                        host_info['ec2_primary_cluster_id'] = node['CacheClusterId']
-                    elif node['CurrentRole'] == 'replica':
-                        host_info['ec2_replica_cluster_address_'+ str(replica_count)] = node['ReadEndpoint']['Address']
-                        host_info['ec2_replica_cluster_port_'+ str(replica_count)] = node['ReadEndpoint']['Port']
-                        host_info['ec2_replica_cluster_id_'+ str(replica_count)] = node['CacheClusterId']
-                        replica_count += 1
-
-            # Target: Redis Replication Groups
-            if key == 'ec2_member_clusters' and value:
-                host_info['ec2_member_clusters'] = ','.join([str(i) for i in value])
-
-            # Target: All Cache Clusters
-            elif key == 'ec2_cache_parameter_group':
-                host_info["ec2_cache_node_ids_to_reboot"] = ','.join([str(i) for i in value['CacheNodeIdsToReboot']])
-                host_info['ec2_cache_parameter_group_name'] = value['CacheParameterGroupName']
-                host_info['ec2_cache_parameter_apply_status'] = value['ParameterApplyStatus']
-
-            # Target: Almost everything
-            elif key == 'ec2_security_groups':
-
-                # Skip if SecurityGroups is None
-                # (it is possible to have the key defined but no value in it).
-                if value is not None:
-                    sg_ids = []
-                    for sg in value:
-                        sg_ids.append(sg['SecurityGroupId'])
-                    host_info["ec2_security_group_ids"] = ','.join([str(i) for i in sg_ids])
-
-            # Target: Everything
-            # Preserve booleans and integers
-            elif type(value) in [int, bool]:
-                host_info[key] = value
-
-            # Target: Everything
-            # Sanitize string values
-            elif isinstance(value, six.string_types):
-                host_info[key] = value.strip()
-
-            # Target: Everything
-            # Replace None by an empty string
-            elif type(value) == type(None):
-                host_info[key] = ''
-
-            else:
-                # Remove non-processed complex types
-                pass
-
-        return host_info
-
-    def get_host_info(self):
-        ''' Get variables about a specific host '''
-
-        if len(self.index) == 0:
-            # Need to load index from cache
-            self.load_index_from_cache()
-
-        if not self.args.host in self.index:
-            # try updating the cache
-            self.do_api_calls_update_cache()
-            if not self.args.host in self.index:
-                # host might not exist anymore
-                return self.json_format_dict({}, True)
-
-        (region, instance_id) = self.index[self.args.host]
-
-        instance = self.get_instance(region, instance_id)
-        return self.json_format_dict(self.get_host_info_dict_from_instance(instance), True)
-
-    def push(self, my_dict, key, element):
-        ''' Push an element onto an array that may not have been defined in
-        the dict '''
-        group_info = my_dict.setdefault(key, [])
-        if isinstance(group_info, dict):
-            host_list = group_info.setdefault('hosts', [])
-            host_list.append(element)
-        else:
-            group_info.append(element)
-
-    def push_group(self, my_dict, key, element):
-        ''' Push a group as a child of another group. '''
-        parent_group = my_dict.setdefault(key, {})
-        if not isinstance(parent_group, dict):
-            parent_group = my_dict[key] = {'hosts': parent_group}
-        child_groups = parent_group.setdefault('children', [])
-        if element not in child_groups:
-            child_groups.append(element)
-
-    def get_inventory_from_cache(self):
-        ''' Reads the inventory from the cache file and returns it as a JSON
-        object '''
-
-        cache = open(self.cache_path_cache, 'r')
-        json_inventory = cache.read()
-        return json_inventory
-
-
-    def load_index_from_cache(self):
-        ''' Reads the index from the cache file sets self.index '''
-
-        cache = open(self.cache_path_index, 'r')
-        json_index = cache.read()
-        self.index = json.loads(json_index)
-
-
-    def write_to_cache(self, data, filename):
-        ''' Writes data in JSON format to a file '''
-
-        json_data = self.json_format_dict(data, True)
-        cache = open(filename, 'w')
-        cache.write(json_data)
-        cache.close()
-
-    def uncammelize(self, key):
-        temp = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', key)
-        return re.sub('([a-z0-9])([A-Z])', r'\1_\2', temp).lower()
-
-    def to_safe(self, word):
-        ''' Converts 'bad' characters in a string to underscores so they can be used as Ansible groups '''
-        regex = "[^A-Za-z0-9\_"
-        if not self.replace_dash_in_groups:
-            regex += "\-"
-        return re.sub(regex + "]", "_", word)
-
-    def json_format_dict(self, data, pretty=False):
-        ''' Converts a dict to a JSON object and dumps it as a formatted
-        string '''
-
-        if pretty:
-            return json.dumps(data, sort_keys=True, indent=2)
-        else:
-            return json.dumps(data)
-
-
-# Run the script
-Ec2Inventory()
diff --git a/edge-1609-dc3/inventory b/edge-1609-dc3/inventory
deleted file mode 100644
index 27e2114..0000000
--- a/edge-1609-dc3/inventory
+++ /dev/null
@@ -1,87 +0,0 @@
-[tag_Name_dc3_n1]
-[tag_Name_dc3_n2]
-[tag_Name_dc3_n3]
-[tag_Name_dc3_n4]
-[tag_Name_dc3_n5]
-[tag_Name_dc3_n6]
-[tag_Name_dc3_n7]
-[tag_Name_dc3_n8]
-[tag_Name_dc3_n9]
-[tag_Name_dc3_n10]
-[tag_Name_dc3_n11]
-
-[planet:children]
-dc-1
-
-[dc-1:children]
-tag_Name_dc3_n1
-tag_Name_dc3_n2
-tag_Name_dc3_n3
-tag_Name_dc3_n4
-tag_Name_dc3_n5
-tag_Name_dc3_n6
-tag_Name_dc3_n7
-tag_Name_dc3_n8
-tag_Name_dc3_n9
-tag_Name_dc3_n10
-tag_Name_dc3_n11
-
-[ds:children]
-dc-1-ds
-
-[dc-1-ds:children]
-tag_Name_dc3_n2
-tag_Name_dc3_n3
-tag_Name_dc3_n4
-
-[ms:children]
-dc-1-ms
-
-[dc-1-ms:children]
-tag_Name_dc3_n1
-
-[ui:children]
-dc-1-ui
-
-[dc-1-ui:children]
-tag_Name_dc3_n1
-
-[ldap:children]
-dc-1-ldap
-
-[dc-1-ldap:children]
-tag_Name_dc3_n1
-
-[rmp:children]
-dc-1-rmp
-
-[dc-1-rmp:children]
-tag_Name_dc3_n5
-tag_Name_dc3_n6
-
-[qpid:children]
-dc-1-qpid
-
-[dc-1-qpid:children]
-tag_Name_dc3_n7
-tag_Name_dc3_n8
-
-[pg:children]
-dc-1-pg
-
-[dc-1-pg:children]
-dc-1-pgmaster
-dc-1-pgstandby
-
-[pgmaster:children]
-dc-1-pgmaster
-
-[dc-1-pgmaster:children]
-tag_Name_dc3_n9
-
-[pgstandby:children]
-dc-1-pgstandby
-
-[dc-1-pgstandby:children]
-tag_Name_dc3_n10
-
diff --git a/edge-1609-dc4/ec2.ini b/edge-1609-dc4/ec2.ini
deleted file mode 100644
index 36b3921..0000000
--- a/edge-1609-dc4/ec2.ini
+++ /dev/null
@@ -1,200 +0,0 @@
-# Ansible EC2 external inventory script settings
-#
-
-[ec2]
-
-# to talk to a private eucalyptus instance uncomment these lines
-# and edit edit eucalyptus_host to be the host name of your cloud controller
-#eucalyptus = True
-#eucalyptus_host = clc.cloud.domain.org
-
-# AWS regions to make calls to. Set this to 'all' to make request to all regions
-# in AWS and merge the results together. Alternatively, set this to a comma
-# separated list of regions. E.g. 'us-east-1,us-west-1,us-west-2'
-regions = all
-regions_exclude = us-gov-west-1,cn-north-1
-
-# When generating inventory, Ansible needs to know how to address a server.
-# Each EC2 instance has a lot of variables associated with it. Here is the list:
-#   http://docs.pythonboto.org/en/latest/ref/ec2.html#module-boto.ec2.instance
-# Below are 2 variables that are used as the address of a server:
-#   - destination_variable
-#   - vpc_destination_variable
-
-# This is the normal destination variable to use. If you are running Ansible
-# from outside EC2, then 'public_dns_name' makes the most sense. If you are
-# running Ansible from within EC2, then perhaps you want to use the internal
-# address, and should set this to 'private_dns_name'. The key of an EC2 tag
-# may optionally be used; however the boto instance variables hold precedence
-# in the event of a collision.
-destination_variable = public_dns_name
-
-# This allows you to override the inventory_name with an ec2 variable, instead
-# of using the destination_variable above. Addressing (aka ansible_ssh_host)
-# will still use destination_variable. Tags should be written as 'tag_TAGNAME'.
-#hostname_variable = tag_Name
-
-# For server inside a VPC, using DNS names may not make sense. When an instance
-# has 'subnet_id' set, this variable is used. If the subnet is public, setting
-# this to 'ip_address' will return the public IP address. For instances in a
-# private subnet, this should be set to 'private_ip_address', and Ansible must
-# be run from within EC2. The key of an EC2 tag may optionally be used; however
-# the boto instance variables hold precedence in the event of a collision.
-# WARNING: - instances that are in the private vpc, _without_ public ip address
-# will not be listed in the inventory until You set:
-# vpc_destination_variable = private_ip_address
-vpc_destination_variable = ip_address
-
-# The following two settings allow flexible ansible host naming based on a
-# python format string and a comma-separated list of ec2 tags.  Note that:
-#
-# 1) If the tags referenced are not present for some instances, empty strings
-#    will be substituted in the format string.
-# 2) This overrides both destination_variable and vpc_destination_variable.
-#
-#destination_format = {0}.{1}.example.com
-#destination_format_tags = Name,environment
-
-# To tag instances on EC2 with the resource records that point to them from
-# Route53, uncomment and set 'route53' to True.
-route53 = False
-
-# To exclude RDS instances from the inventory, uncomment and set to False.
-rds = False
-
-# To exclude ElastiCache instances from the inventory, uncomment and set to False.
-elasticache = False
-
-# Additionally, you can specify the list of zones to exclude looking up in
-# 'route53_excluded_zones' as a comma-separated list.
-# route53_excluded_zones = samplezone1.com, samplezone2.com
-
-# By default, only EC2 instances in the 'running' state are returned. Set
-# 'all_instances' to True to return all instances regardless of state.
-all_instances = True
-
-# By default, only EC2 instances in the 'running' state are returned. Specify
-# EC2 instance states to return as a comma-separated list. This
-# option is overriden when 'all_instances' is True.
-# instance_states = pending, running, shutting-down, terminated, stopping, stopped
-
-# By default, only RDS instances in the 'available' state are returned.  Set
-# 'all_rds_instances' to True return all RDS instances regardless of state.
-all_rds_instances = False
-
-# By default, only ElastiCache clusters and nodes in the 'available' state
-# are returned. Set 'all_elasticache_clusters' and/or 'all_elastic_nodes'
-# to True return all ElastiCache clusters and nodes, regardless of state.
-#
-# Note that all_elasticache_nodes only applies to listed clusters. That means
-# if you set all_elastic_clusters to false, no node will be return from
-# unavailable clusters, regardless of the state and to what you set for
-# all_elasticache_nodes.
-all_elasticache_replication_groups = False
-all_elasticache_clusters = False
-all_elasticache_nodes = False
-
-# API calls to EC2 are slow. For this reason, we cache the results of an API
-# call. Set this to the path you want cache files to be written to. Two files
-# will be written to this directory:
-#   - ansible-ec2.cache
-#   - ansible-ec2.index
-cache_path = ~/.ansible/tmp
-
-# The number of seconds a cache file is considered valid. After this many
-# seconds, a new API call will be made, and the cache file will be updated.
-# To disable the cache, set this value to 0
-cache_max_age = 300
-
-# Organize groups into a nested/hierarchy instead of a flat namespace.
-nested_groups = False
-
-# Replace - tags when creating groups to avoid issues with ansible
-replace_dash_in_groups = True
-
-# If set to true, any tag of the form "a,b,c" is expanded into a list
-# and the results are used to create additional tag_* inventory groups.
-expand_csv_tags = False
-
-# The EC2 inventory output can become very large. To manage its size,
-# configure which groups should be created.
-group_by_instance_id = True
-group_by_region = True
-group_by_availability_zone = True
-group_by_ami_id = True
-group_by_instance_type = True
-group_by_key_pair = True
-group_by_vpc_id = True
-group_by_security_group = True
-group_by_tag_keys = True
-group_by_tag_none = True
-group_by_route53_names = True
-group_by_rds_engine = False
-group_by_rds_parameter_group = False
-group_by_elasticache_engine = True
-group_by_elasticache_cluster = True
-group_by_elasticache_parameter_group = True
-group_by_elasticache_replication_group = True
-
-# If you only want to include hosts that match a certain regular expression
-# pattern_include = staging-*
-
-# If you want to exclude any hosts that match a certain regular expression
-# pattern_exclude = staging-*
-# Ansible EC2 external inventory script settings
-#
-
-##[ec2]
-##
-### to talk to a private eucalyptus instance uncomment these lines
-### and edit edit eucalyptus_host to be the host name of your cloud controller
-###eucalyptus = True
-###eucalyptus_host = clc.cloud.domain.org
-##
-### AWS regions to make calls to. Set this to 'all' to make request to all regions
-##
-### in AWS and merge the results together. Alternatively, set this to a comma
-### separated list of regions. E.g. 'us-east-1,us-west-1,us-west-2'
-##regions = all
-##regions_exclude = us-gov-west-1,cn-north-1
-##
-### When generating inventory, Ansible needs to know how to address a server.
-### Each EC2 instance has a lot of variables associated with it. Here is the list:
-###   http://docs.pythonboto.org/en/latest/ref/ec2.html#module-boto.ec2.instance
-### Below are 2 variables that are used as the address of a server:
-###   - destination_variable
-###   - vpc_destination_variable
-##
-### This is the normal destination variable to use. If you are running Ansible
-### from outside EC2, then 'public_dns_name' makes the most sense. If you are
-### running Ansible from within EC2, then perhaps you want to use the internal
-### address, and should set this to 'private_dns_name'. The key of an EC2 tag
-##...skipping...
-### pattern_include = staging-*
-##
-### If you want to exclude any hosts that match a certain regular expression
-### pattern_exclude = staging-*
-
-# Instance filters can be used to control which instances are retrieved for
-# inventory. For the full list of possible filters, please read the EC2 API
-# docs: http://docs.aws.amazon.com/AWSEC2/latest/APIReference/ApiReference-query-DescribeInstances.html#query-DescribeInstances-filters
-# Filters are key/value pairs separated by '=', to list multiple filters use
-# a list separated by commas. See examples below.
-
-# Retrieve only instances with (key=value) env=staging tag
-# instance_filters = tag:env=staging
-
-# Retrieve only instances with role=webservers OR role=dbservers tag
-# instance_filters = tag:role=webservers,tag:role=dbservers
-
-# Retrieve only t1.micro instances OR instances with tag env=staging
-# instance_filters = instance-type=t1.micro,tag:env=staging
-
-# You can use wildcards in filter values also. Below will list instances which
-# tag Name value matches webservers1*
-# (ex. webservers15, webservers1a, webservers123 etc)
-# instance_filters = tag:Name=webservers1*
-
-# A boto configuration profile may be used to separate out credentials
-# see http://boto.readthedocs.org/en/latest/boto_config_tut.html
-# boto_profile = some-boto-profile-name
diff --git a/edge-1609-dc4/ec2.py b/edge-1609-dc4/ec2.py
deleted file mode 100755
index f30958a..0000000
--- a/edge-1609-dc4/ec2.py
+++ /dev/null
@@ -1,1385 +0,0 @@
-#!/usr/bin/env python
-
-'''
-EC2 external inventory script
-=================================
-
-Generates inventory that Ansible can understand by making API request to
-AWS EC2 using the Boto library.
-
-NOTE: This script assumes Ansible is being executed where the environment
-variables needed for Boto have already been set:
-    export AWS_ACCESS_KEY_ID='AK123'
-    export AWS_SECRET_ACCESS_KEY='abc123'
-
-This script also assumes there is an ec2.ini file alongside it.  To specify a
-different path to ec2.ini, define the EC2_INI_PATH environment variable:
-
-    export EC2_INI_PATH=/path/to/my_ec2.ini
-
-If you're using eucalyptus you need to set the above variables and
-you need to define:
-
-    export EC2_URL=http://hostname_of_your_cc:port/services/Eucalyptus
-
-If you're using boto profiles (requires boto>=2.24.0) you can choose a profile
-using the --boto-profile command line argument (e.g. ec2.py --boto-profile prod) or using
-the AWS_PROFILE variable:
-
-    AWS_PROFILE=prod ansible-playbook -i ec2.py myplaybook.yml
-
-For more details, see: http://docs.pythonboto.org/en/latest/boto_config_tut.html
-
-When run against a specific host, this script returns the following variables:
- - ec2_ami_launch_index
- - ec2_architecture
- - ec2_association
- - ec2_attachTime
- - ec2_attachment
- - ec2_attachmentId
- - ec2_client_token
- - ec2_deleteOnTermination
- - ec2_description
- - ec2_deviceIndex
- - ec2_dns_name
- - ec2_eventsSet
- - ec2_group_name
- - ec2_hypervisor
- - ec2_id
- - ec2_image_id
- - ec2_instanceState
- - ec2_instance_type
- - ec2_ipOwnerId
- - ec2_ip_address
- - ec2_item
- - ec2_kernel
- - ec2_key_name
- - ec2_launch_time
- - ec2_monitored
- - ec2_monitoring
- - ec2_networkInterfaceId
- - ec2_ownerId
- - ec2_persistent
- - ec2_placement
- - ec2_platform
- - ec2_previous_state
- - ec2_private_dns_name
- - ec2_private_ip_address
- - ec2_publicIp
- - ec2_public_dns_name
- - ec2_ramdisk
- - ec2_reason
- - ec2_region
- - ec2_requester_id
- - ec2_root_device_name
- - ec2_root_device_type
- - ec2_security_group_ids
- - ec2_security_group_names
- - ec2_shutdown_state
- - ec2_sourceDestCheck
- - ec2_spot_instance_request_id
- - ec2_state
- - ec2_state_code
- - ec2_state_reason
- - ec2_status
- - ec2_subnet_id
- - ec2_tenancy
- - ec2_virtualization_type
- - ec2_vpc_id
-
-These variables are pulled out of a boto.ec2.instance object. There is a lack of
-consistency with variable spellings (camelCase and underscores) since this
-just loops through all variables the object exposes. It is preferred to use the
-ones with underscores when multiple exist.
-
-In addition, if an instance has AWS Tags associated with it, each tag is a new
-variable named:
- - ec2_tag_[Key] = [Value]
-
-Security groups are comma-separated in 'ec2_security_group_ids' and
-'ec2_security_group_names'.
-'''
-
-# (c) 2012, Peter Sankauskas
-#
-# This file is part of Ansible,
-#
-# Ansible is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# Ansible is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with Ansible.  If not, see <http://www.gnu.org/licenses/>.
-
-######################################################################
-
-import sys
-import os
-import argparse
-import re
-from time import time
-import boto
-from boto import ec2
-from boto import rds
-from boto import elasticache
-from boto import route53
-import six
-
-from six.moves import configparser
-from collections import defaultdict
-
-try:
-    import json
-except ImportError:
-    import simplejson as json
-
-
-class Ec2Inventory(object):
-
-    def _empty_inventory(self):
-        return {"_meta" : {"hostvars" : {}}}
-
-    def __init__(self):
-        ''' Main execution path '''
-
-        # Inventory grouped by instance IDs, tags, security groups, regions,
-        # and availability zones
-        self.inventory = self._empty_inventory()
-
-        # Index of hostname (address) to instance ID
-        self.index = {}
-
-        # Boto profile to use (if any)
-        self.boto_profile = None
-
-        # Read settings and parse CLI arguments
-        self.parse_cli_args()
-        self.read_settings()
-
-        # Make sure that profile_name is not passed at all if not set
-        # as pre 2.24 boto will fall over otherwise
-        if self.boto_profile:
-            if not hasattr(boto.ec2.EC2Connection, 'profile_name'):
-                self.fail_with_error("boto version must be >= 2.24 to use profile")
-
-        # Cache
-        if self.args.refresh_cache:
-            self.do_api_calls_update_cache()
-        elif not self.is_cache_valid():
-            self.do_api_calls_update_cache()
-
-        # Data to print
-        if self.args.host:
-            data_to_print = self.get_host_info()
-
-        elif self.args.list:
-            # Display list of instances for inventory
-            if self.inventory == self._empty_inventory():
-                data_to_print = self.get_inventory_from_cache()
-            else:
-                data_to_print = self.json_format_dict(self.inventory, True)
-
-        print(data_to_print)
-
-
-    def is_cache_valid(self):
-        ''' Determines if the cache files have expired, or if it is still valid '''
-
-        if os.path.isfile(self.cache_path_cache):
-            mod_time = os.path.getmtime(self.cache_path_cache)
-            current_time = time()
-            if (mod_time + self.cache_max_age) > current_time:
-                if os.path.isfile(self.cache_path_index):
-                    return True
-
-        return False
-
-
-    def read_settings(self):
-        ''' Reads the settings from the ec2.ini file '''
-        if six.PY3:
-            config = configparser.ConfigParser()
-        else:
-            config = configparser.SafeConfigParser()
-        ec2_default_ini_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'ec2.ini')
-        ec2_ini_path = os.path.expanduser(os.path.expandvars(os.environ.get('EC2_INI_PATH', ec2_default_ini_path)))
-        config.read(ec2_ini_path)
-
-        # is eucalyptus?
-        self.eucalyptus_host = None
-        self.eucalyptus = False
-        if config.has_option('ec2', 'eucalyptus'):
-            self.eucalyptus = config.getboolean('ec2', 'eucalyptus')
-        if self.eucalyptus and config.has_option('ec2', 'eucalyptus_host'):
-            self.eucalyptus_host = config.get('ec2', 'eucalyptus_host')
-
-        # Regions
-        self.regions = []
-        configRegions = config.get('ec2', 'regions')
-        configRegions_exclude = config.get('ec2', 'regions_exclude')
-        if (configRegions == 'all'):
-            if self.eucalyptus_host:
-                self.regions.append(boto.connect_euca(host=self.eucalyptus_host).region.name)
-            else:
-                for regionInfo in ec2.regions():
-                    if regionInfo.name not in configRegions_exclude:
-                        self.regions.append(regionInfo.name)
-        else:
-            self.regions = configRegions.split(",")
-
-        # Destination addresses
-        self.destination_variable = config.get('ec2', 'destination_variable')
-        self.vpc_destination_variable = config.get('ec2', 'vpc_destination_variable')
-
-        if config.has_option('ec2', 'hostname_variable'):
-            self.hostname_variable = config.get('ec2', 'hostname_variable')
-        else:
-            self.hostname_variable = None
-
-        if config.has_option('ec2', 'destination_format') and \
-                config.has_option('ec2', 'destination_format_tags'):
-            self.destination_format = config.get('ec2', 'destination_format')
-            self.destination_format_tags = config.get('ec2', 'destination_format_tags').split(',')
-        else:
-            self.destination_format = None
-            self.destination_format_tags = None
-
-        # Route53
-        self.route53_enabled = config.getboolean('ec2', 'route53')
-        self.route53_excluded_zones = []
-        if config.has_option('ec2', 'route53_excluded_zones'):
-            self.route53_excluded_zones.extend(
-                    config.get('ec2', 'route53_excluded_zones', '').split(','))
-
-        # Include RDS instances?
-        self.rds_enabled = True
-        if config.has_option('ec2', 'rds'):
-            self.rds_enabled = config.getboolean('ec2', 'rds')
-
-        # Include ElastiCache instances?
-        self.elasticache_enabled = True
-        if config.has_option('ec2', 'elasticache'):
-            self.elasticache_enabled = config.getboolean('ec2', 'elasticache')
-
-        # Return all EC2 instances?
-        if config.has_option('ec2', 'all_instances'):
-            self.all_instances = config.getboolean('ec2', 'all_instances')
-        else:
-            self.all_instances = False
-
-        # Instance states to be gathered in inventory. Default is 'running'.
-        # Setting 'all_instances' to 'yes' overrides this option.
-        ec2_valid_instance_states = [
-            'pending',
-            'running',
-            'shutting-down',
-            'terminated',
-            'stopping',
-            'stopped'
-        ]
-        self.ec2_instance_states = []
-        if self.all_instances:
-            self.ec2_instance_states = ec2_valid_instance_states
-        elif config.has_option('ec2', 'instance_states'):
-            for instance_state in config.get('ec2', 'instance_states').split(','):
-                instance_state = instance_state.strip()
-                if instance_state not in ec2_valid_instance_states:
-                    continue
-                self.ec2_instance_states.append(instance_state)
-        else:
-            self.ec2_instance_states = ['running']
-
-        # Return all RDS instances? (if RDS is enabled)
-        if config.has_option('ec2', 'all_rds_instances') and self.rds_enabled:
-            self.all_rds_instances = config.getboolean('ec2', 'all_rds_instances')
-        else:
-            self.all_rds_instances = False
-
-        # Return all ElastiCache replication groups? (if ElastiCache is enabled)
-        if config.has_option('ec2', 'all_elasticache_replication_groups') and self.elasticache_enabled:
-            self.all_elasticache_replication_groups = config.getboolean('ec2', 'all_elasticache_replication_groups')
-        else:
-            self.all_elasticache_replication_groups = False
-
-        # Return all ElastiCache clusters? (if ElastiCache is enabled)
-        if config.has_option('ec2', 'all_elasticache_clusters') and self.elasticache_enabled:
-            self.all_elasticache_clusters = config.getboolean('ec2', 'all_elasticache_clusters')
-        else:
-            self.all_elasticache_clusters = False
-
-        # Return all ElastiCache nodes? (if ElastiCache is enabled)
-        if config.has_option('ec2', 'all_elasticache_nodes') and self.elasticache_enabled:
-            self.all_elasticache_nodes = config.getboolean('ec2', 'all_elasticache_nodes')
-        else:
-            self.all_elasticache_nodes = False
-
-        # boto configuration profile (prefer CLI argument)
-        self.boto_profile = self.args.boto_profile
-        if config.has_option('ec2', 'boto_profile') and not self.boto_profile:
-            self.boto_profile = config.get('ec2', 'boto_profile')
-
-        # Cache related
-        cache_dir = os.path.expanduser(config.get('ec2', 'cache_path'))
-        if self.boto_profile:
-            cache_dir = os.path.join(cache_dir, 'profile_' + self.boto_profile)
-        if not os.path.exists(cache_dir):
-            os.makedirs(cache_dir)
-
-        cache_name = 'ansible-ec2'
-        aws_profile = lambda: (self.boto_profile or
-                               os.environ.get('AWS_PROFILE') or
-                               os.environ.get('AWS_ACCESS_KEY_ID'))
-        if aws_profile():
-            cache_name = '%s-%s' % (cache_name, aws_profile())
-        self.cache_path_cache = cache_dir + "/%s.cache" % cache_name
-        self.cache_path_index = cache_dir + "/%s.index" % cache_name
-        self.cache_max_age = config.getint('ec2', 'cache_max_age')
-
-        if config.has_option('ec2', 'expand_csv_tags'):
-            self.expand_csv_tags = config.getboolean('ec2', 'expand_csv_tags')
-        else:
-            self.expand_csv_tags = False
-
-        # Configure nested groups instead of flat namespace.
-        if config.has_option('ec2', 'nested_groups'):
-            self.nested_groups = config.getboolean('ec2', 'nested_groups')
-        else:
-            self.nested_groups = False
-
-        # Replace dash or not in group names
-        if config.has_option('ec2', 'replace_dash_in_groups'):
-            self.replace_dash_in_groups = config.getboolean('ec2', 'replace_dash_in_groups')
-        else:
-            self.replace_dash_in_groups = True
-
-        # Configure which groups should be created.
-        group_by_options = [
-            'group_by_instance_id',
-            'group_by_region',
-            'group_by_availability_zone',
-            'group_by_ami_id',
-            'group_by_instance_type',
-            'group_by_key_pair',
-            'group_by_vpc_id',
-            'group_by_security_group',
-            'group_by_tag_keys',
-            'group_by_tag_none',
-            'group_by_route53_names',
-            'group_by_rds_engine',
-            'group_by_rds_parameter_group',
-            'group_by_elasticache_engine',
-            'group_by_elasticache_cluster',
-            'group_by_elasticache_parameter_group',
-            'group_by_elasticache_replication_group',
-        ]
-        for option in group_by_options:
-            if config.has_option('ec2', option):
-                setattr(self, option, config.getboolean('ec2', option))
-            else:
-                setattr(self, option, True)
-
-        # Do we need to just include hosts that match a pattern?
-        try:
-            pattern_include = config.get('ec2', 'pattern_include')
-            if pattern_include and len(pattern_include) > 0:
-                self.pattern_include = re.compile(pattern_include)
-            else:
-                self.pattern_include = None
-        except configparser.NoOptionError:
-            self.pattern_include = None
-
-        # Do we need to exclude hosts that match a pattern?
-        try:
-            pattern_exclude = config.get('ec2', 'pattern_exclude');
-            if pattern_exclude and len(pattern_exclude) > 0:
-                self.pattern_exclude = re.compile(pattern_exclude)
-            else:
-                self.pattern_exclude = None
-        except configparser.NoOptionError:
-            self.pattern_exclude = None
-
-        # Instance filters (see boto and EC2 API docs). Ignore invalid filters.
-        self.ec2_instance_filters = defaultdict(list)
-        if config.has_option('ec2', 'instance_filters'):
-
-            filters = [f for f in config.get('ec2', 'instance_filters').split(',') if f]
-
-            for instance_filter in filters:
-                instance_filter = instance_filter.strip()
-                if not instance_filter or '=' not in instance_filter:
-                    continue
-                filter_key, filter_value = [x.strip() for x in instance_filter.split('=', 1)]
-                if not filter_key:
-                    continue
-                self.ec2_instance_filters[filter_key].append(filter_value)
-
-    def parse_cli_args(self):
-        ''' Command line argument processing '''
-
-        parser = argparse.ArgumentParser(description='Produce an Ansible Inventory file based on EC2')
-        parser.add_argument('--list', action='store_true', default=True,
-                            help='List instances (default: True)')
-        parser.add_argument('--host', action='store',
-                            help='Get all the variables about a specific instance')
-        parser.add_argument('--refresh-cache', action='store_true', default=False,
-                            help='Force refresh of cache by making API requests to EC2 (default: False - use cache files)')
-        parser.add_argument('--profile', '--boto-profile', action='store', dest='boto_profile',
-                            help='Use boto profile for connections to EC2')
-        self.args = parser.parse_args()
-
-
-    def do_api_calls_update_cache(self):
-        ''' Do API calls to each region, and save data in cache files '''
-
-        if self.route53_enabled:
-            self.get_route53_records()
-
-        for region in self.regions:
-            self.get_instances_by_region(region)
-            if self.rds_enabled:
-                self.get_rds_instances_by_region(region)
-            if self.elasticache_enabled:
-                self.get_elasticache_clusters_by_region(region)
-                self.get_elasticache_replication_groups_by_region(region)
-
-        self.write_to_cache(self.inventory, self.cache_path_cache)
-        self.write_to_cache(self.index, self.cache_path_index)
-
-    def connect(self, region):
-        ''' create connection to api server'''
-        if self.eucalyptus:
-            conn = boto.connect_euca(host=self.eucalyptus_host)
-            conn.APIVersion = '2010-08-31'
-        else:
-            conn = self.connect_to_aws(ec2, region)
-        return conn
-
-    def boto_fix_security_token_in_profile(self, connect_args):
-        ''' monkey patch for boto issue boto/boto#2100 '''
-        profile = 'profile ' + self.boto_profile
-        if boto.config.has_option(profile, 'aws_security_token'):
-            connect_args['security_token'] = boto.config.get(profile, 'aws_security_token')
-        return connect_args
-
-    def connect_to_aws(self, module, region):
-        connect_args = {}
-
-        # only pass the profile name if it's set (as it is not supported by older boto versions)
-        if self.boto_profile:
-            connect_args['profile_name'] = self.boto_profile
-            self.boto_fix_security_token_in_profile(connect_args)
-
-        conn = module.connect_to_region(region, **connect_args)
-        # connect_to_region will fail "silently" by returning None if the region name is wrong or not supported
-        if conn is None:
-            self.fail_with_error("region name: %s likely not supported, or AWS is down.  connection to region failed." % region)
-        return conn
-
-    def get_instances_by_region(self, region):
-        ''' Makes an AWS EC2 API call to the list of instances in a particular
-        region '''
-
-        try:
-            conn = self.connect(region)
-            reservations = []
-            if self.ec2_instance_filters:
-                for filter_key, filter_values in self.ec2_instance_filters.items():
-                    reservations.extend(conn.get_all_instances(filters = { filter_key : filter_values }))
-            else:
-                reservations = conn.get_all_instances()
-
-            for reservation in reservations:
-                for instance in reservation.instances:
-                    self.add_instance(instance, region)
-
-        except boto.exception.BotoServerError as e:
-            if e.error_code == 'AuthFailure':
-                error = self.get_auth_error_message()
-            else:
-                backend = 'Eucalyptus' if self.eucalyptus else 'AWS'
-                error = "Error connecting to %s backend.\n%s" % (backend, e.message)
-            self.fail_with_error(error, 'getting EC2 instances')
-
-    def get_rds_instances_by_region(self, region):
-        ''' Makes an AWS API call to the list of RDS instances in a particular
-        region '''
-
-        try:
-            conn = self.connect_to_aws(rds, region)
-            if conn:
-                marker = None
-                while True:
-                    instances = conn.get_all_dbinstances(marker=marker)
-                    marker = instances.marker
-                    for instance in instances:
-                        self.add_rds_instance(instance, region)
-                    if not marker:
-                        break
-        except boto.exception.BotoServerError as e:
-            error = e.reason
-
-            if e.error_code == 'AuthFailure':
-                error = self.get_auth_error_message()
-            if not e.reason == "Forbidden":
-                error = "Looks like AWS RDS is down:\n%s" % e.message
-            self.fail_with_error(error, 'getting RDS instances')
-
-    def get_elasticache_clusters_by_region(self, region):
-        ''' Makes an AWS API call to the list of ElastiCache clusters (with
-        nodes' info) in a particular region.'''
-
-        # ElastiCache boto module doesn't provide a get_all_intances method,
-        # that's why we need to call describe directly (it would be called by
-        # the shorthand method anyway...)
-        try:
-            conn = self.connect_to_aws(elasticache, region)
-            if conn:
-                # show_cache_node_info = True
-                # because we also want nodes' information
-                response = conn.describe_cache_clusters(None, None, None, True)
-
-        except boto.exception.BotoServerError as e:
-            error = e.reason
-
-            if e.error_code == 'AuthFailure':
-                error = self.get_auth_error_message()
-            if not e.reason == "Forbidden":
-                error = "Looks like AWS ElastiCache is down:\n%s" % e.message
-            self.fail_with_error(error, 'getting ElastiCache clusters')
-
-        try:
-            # Boto also doesn't provide wrapper classes to CacheClusters or
-            # CacheNodes. Because of that wo can't make use of the get_list
-            # method in the AWSQueryConnection. Let's do the work manually
-            clusters = response['DescribeCacheClustersResponse']['DescribeCacheClustersResult']['CacheClusters']
-
-        except KeyError as e:
-            error = "ElastiCache query to AWS failed (unexpected format)."
-            self.fail_with_error(error, 'getting ElastiCache clusters')
-
-        for cluster in clusters:
-            self.add_elasticache_cluster(cluster, region)
-
-    def get_elasticache_replication_groups_by_region(self, region):
-        ''' Makes an AWS API call to the list of ElastiCache replication groups
-        in a particular region.'''
-
-        # ElastiCache boto module doesn't provide a get_all_intances method,
-        # that's why we need to call describe directly (it would be called by
-        # the shorthand method anyway...)
-        try:
-            conn = self.connect_to_aws(elasticache, region)
-            if conn:
-                response = conn.describe_replication_groups()
-
-        except boto.exception.BotoServerError as e:
-            error = e.reason
-
-            if e.error_code == 'AuthFailure':
-                error = self.get_auth_error_message()
-            if not e.reason == "Forbidden":
-                error = "Looks like AWS ElastiCache [Replication Groups] is down:\n%s" % e.message
-            self.fail_with_error(error, 'getting ElastiCache clusters')
-
-        try:
-            # Boto also doesn't provide wrapper classes to ReplicationGroups
-            # Because of that wo can't make use of the get_list method in the
-            # AWSQueryConnection. Let's do the work manually
-            replication_groups = response['DescribeReplicationGroupsResponse']['DescribeReplicationGroupsResult']['ReplicationGroups']
-
-        except KeyError as e:
-            error = "ElastiCache [Replication Groups] query to AWS failed (unexpected format)."
-            self.fail_with_error(error, 'getting ElastiCache clusters')
-
-        for replication_group in replication_groups:
-            self.add_elasticache_replication_group(replication_group, region)
-
-    def get_auth_error_message(self):
-        ''' create an informative error message if there is an issue authenticating'''
-        errors = ["Authentication error retrieving ec2 inventory."]
-        if None in [os.environ.get('AWS_ACCESS_KEY_ID'), os.environ.get('AWS_SECRET_ACCESS_KEY')]:
-            errors.append(' - No AWS_ACCESS_KEY_ID or AWS_SECRET_ACCESS_KEY environment vars found')
-        else:
-            errors.append(' - AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY environment vars found but may not be correct')
-
-        boto_paths = ['/etc/boto.cfg', '~/.boto', '~/.aws/credentials']
-        boto_config_found = list(p for p in boto_paths if os.path.isfile(os.path.expanduser(p)))
-        if len(boto_config_found) > 0:
-            errors.append(" - Boto configs found at '%s', but the credentials contained may not be correct" % ', '.join(boto_config_found))
-        else:
-            errors.append(" - No Boto config found at any expected location '%s'" % ', '.join(boto_paths))
-
-        return '\n'.join(errors)
-
-    def fail_with_error(self, err_msg, err_operation=None):
-        '''log an error to std err for ansible-playbook to consume and exit'''
-        if err_operation:
-            err_msg = 'ERROR: "{err_msg}", while: {err_operation}'.format(
-                    err_msg=err_msg, err_operation=err_operation)
-        sys.stderr.write(err_msg)
-        sys.exit(1)
-
-    def get_instance(self, region, instance_id):
-        conn = self.connect(region)
-
-        reservations = conn.get_all_instances([instance_id])
-        for reservation in reservations:
-            for instance in reservation.instances:
-                return instance
-
-    def add_instance(self, instance, region):
-        ''' Adds an instance to the inventory and index, as long as it is
-        addressable '''
-
-        # Only return instances with desired instance states
-        if instance.state not in self.ec2_instance_states:
-            return
-
-        # Select the best destination address
-        if self.destination_format and self.destination_format_tags:
-            dest = self.destination_format.format(*[ getattr(instance, 'tags').get(tag, '') for tag in self.destination_format_tags ])
-        elif instance.subnet_id:
-            dest = getattr(instance, self.vpc_destination_variable, None)
-            if dest is None:
-                dest = getattr(instance, 'tags').get(self.vpc_destination_variable, None)
-        else:
-            dest = getattr(instance, self.destination_variable, None)
-            if dest is None:
-                dest = getattr(instance, 'tags').get(self.destination_variable, None)
-
-        if not dest:
-            # Skip instances we cannot address (e.g. private VPC subnet)
-            return
-
-        # Set the inventory name
-        hostname = None
-        if self.hostname_variable:
-            if self.hostname_variable.startswith('tag_'):
-                hostname = instance.tags.get(self.hostname_variable[4:], None)
-            else:
-                hostname = getattr(instance, self.hostname_variable)
-
-        # If we can't get a nice hostname, use the destination address
-        if not hostname:
-            hostname = dest
-        else:
-            hostname = self.to_safe(hostname).lower()
-
-        # if we only want to include hosts that match a pattern, skip those that don't
-        if self.pattern_include and not self.pattern_include.match(hostname):
-            return
-
-        # if we need to exclude hosts that match a pattern, skip those
-        if self.pattern_exclude and self.pattern_exclude.match(hostname):
-            return
-
-        # Add to index
-        self.index[hostname] = [region, instance.id]
-
-        # Inventory: Group by instance ID (always a group of 1)
-        if self.group_by_instance_id:
-            self.inventory[instance.id] = [hostname]
-            if self.nested_groups:
-                self.push_group(self.inventory, 'instances', instance.id)
-
-        # Inventory: Group by region
-        if self.group_by_region:
-            self.push(self.inventory, region, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'regions', region)
-
-        # Inventory: Group by availability zone
-        if self.group_by_availability_zone:
-            self.push(self.inventory, instance.placement, hostname)
-            if self.nested_groups:
-                if self.group_by_region:
-                    self.push_group(self.inventory, region, instance.placement)
-                self.push_group(self.inventory, 'zones', instance.placement)
-
-        # Inventory: Group by Amazon Machine Image (AMI) ID
-        if self.group_by_ami_id:
-            ami_id = self.to_safe(instance.image_id)
-            self.push(self.inventory, ami_id, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'images', ami_id)
-
-        # Inventory: Group by instance type
-        if self.group_by_instance_type:
-            type_name = self.to_safe('type_' + instance.instance_type)
-            self.push(self.inventory, type_name, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'types', type_name)
-
-        # Inventory: Group by key pair
-        if self.group_by_key_pair and instance.key_name:
-            key_name = self.to_safe('key_' + instance.key_name)
-            self.push(self.inventory, key_name, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'keys', key_name)
-
-        # Inventory: Group by VPC
-        if self.group_by_vpc_id and instance.vpc_id:
-            vpc_id_name = self.to_safe('vpc_id_' + instance.vpc_id)
-            self.push(self.inventory, vpc_id_name, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'vpcs', vpc_id_name)
-
-        # Inventory: Group by security group
-        if self.group_by_security_group:
-            try:
-                for group in instance.groups:
-                    key = self.to_safe("security_group_" + group.name)
-                    self.push(self.inventory, key, hostname)
-                    if self.nested_groups:
-                        self.push_group(self.inventory, 'security_groups', key)
-            except AttributeError:
-                self.fail_with_error('\n'.join(['Package boto seems a bit older.',
-                                                'Please upgrade boto >= 2.3.0.']))
-
-        # Inventory: Group by tag keys
-        if self.group_by_tag_keys:
-            for k, v in instance.tags.items():
-                if self.expand_csv_tags and v and ',' in v:
-                    values = map(lambda x: x.strip(), v.split(','))
-                else:
-                    values = [v]
-
-                for v in values:
-                    if v:
-                        key = self.to_safe("tag_" + k + "=" + v)
-                    else:
-                        key = self.to_safe("tag_" + k)
-                    self.push(self.inventory, key, hostname)
-                    if self.nested_groups:
-                        self.push_group(self.inventory, 'tags', self.to_safe("tag_" + k))
-                        if v:
-                            self.push_group(self.inventory, self.to_safe("tag_" + k), key)
-
-        # Inventory: Group by Route53 domain names if enabled
-        if self.route53_enabled and self.group_by_route53_names:
-            route53_names = self.get_instance_route53_names(instance)
-            for name in route53_names:
-                self.push(self.inventory, name, hostname)
-                if self.nested_groups:
-                    self.push_group(self.inventory, 'route53', name)
-
-        # Global Tag: instances without tags
-        if self.group_by_tag_none and len(instance.tags) == 0:
-            self.push(self.inventory, 'tag_none', hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'tags', 'tag_none')
-
-        # Global Tag: tag all EC2 instances
-        self.push(self.inventory, 'ec2', hostname)
-
-        self.inventory["_meta"]["hostvars"][hostname] = self.get_host_info_dict_from_instance(instance)
-        self.inventory["_meta"]["hostvars"][hostname]['ansible_ssh_host'] = dest
-
-
-    def add_rds_instance(self, instance, region):
-        ''' Adds an RDS instance to the inventory and index, as long as it is
-        addressable '''
-
-        # Only want available instances unless all_rds_instances is True
-        if not self.all_rds_instances and instance.status != 'available':
-            return
-
-        # Select the best destination address
-        dest = instance.endpoint[0]
-
-        if not dest:
-            # Skip instances we cannot address (e.g. private VPC subnet)
-            return
-
-        # Set the inventory name
-        hostname = None
-        if self.hostname_variable:
-            if self.hostname_variable.startswith('tag_'):
-                hostname = instance.tags.get(self.hostname_variable[4:], None)
-            else:
-                hostname = getattr(instance, self.hostname_variable)
-
-        # If we can't get a nice hostname, use the destination address
-        if not hostname:
-            hostname = dest
-
-        hostname = self.to_safe(hostname).lower()
-
-        # Add to index
-        self.index[hostname] = [region, instance.id]
-
-        # Inventory: Group by instance ID (always a group of 1)
-        if self.group_by_instance_id:
-            self.inventory[instance.id] = [hostname]
-            if self.nested_groups:
-                self.push_group(self.inventory, 'instances', instance.id)
-
-        # Inventory: Group by region
-        if self.group_by_region:
-            self.push(self.inventory, region, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'regions', region)
-
-        # Inventory: Group by availability zone
-        if self.group_by_availability_zone:
-            self.push(self.inventory, instance.availability_zone, hostname)
-            if self.nested_groups:
-                if self.group_by_region:
-                    self.push_group(self.inventory, region, instance.availability_zone)
-                self.push_group(self.inventory, 'zones', instance.availability_zone)
-
-        # Inventory: Group by instance type
-        if self.group_by_instance_type:
-            type_name = self.to_safe('type_' + instance.instance_class)
-            self.push(self.inventory, type_name, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'types', type_name)
-
-        # Inventory: Group by VPC
-        if self.group_by_vpc_id and instance.subnet_group and instance.subnet_group.vpc_id:
-            vpc_id_name = self.to_safe('vpc_id_' + instance.subnet_group.vpc_id)
-            self.push(self.inventory, vpc_id_name, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'vpcs', vpc_id_name)
-
-        # Inventory: Group by security group
-        if self.group_by_security_group:
-            try:
-                if instance.security_group:
-                    key = self.to_safe("security_group_" + instance.security_group.name)
-                    self.push(self.inventory, key, hostname)
-                    if self.nested_groups:
-                        self.push_group(self.inventory, 'security_groups', key)
-
-            except AttributeError:
-                self.fail_with_error('\n'.join(['Package boto seems a bit older.',
-                                                'Please upgrade boto >= 2.3.0.']))
-
-
-        # Inventory: Group by engine
-        if self.group_by_rds_engine:
-            self.push(self.inventory, self.to_safe("rds_" + instance.engine), hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'rds_engines', self.to_safe("rds_" + instance.engine))
-
-        # Inventory: Group by parameter group
-        if self.group_by_rds_parameter_group:
-            self.push(self.inventory, self.to_safe("rds_parameter_group_" + instance.parameter_group.name), hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'rds_parameter_groups', self.to_safe("rds_parameter_group_" + instance.parameter_group.name))
-
-        # Global Tag: all RDS instances
-        self.push(self.inventory, 'rds', hostname)
-
-        self.inventory["_meta"]["hostvars"][hostname] = self.get_host_info_dict_from_instance(instance)
-        self.inventory["_meta"]["hostvars"][hostname]['ansible_ssh_host'] = dest
-
-    def add_elasticache_cluster(self, cluster, region):
-        ''' Adds an ElastiCache cluster to the inventory and index, as long as
-        it's nodes are addressable '''
-
-        # Only want available clusters unless all_elasticache_clusters is True
-        if not self.all_elasticache_clusters and cluster['CacheClusterStatus'] != 'available':
-            return
-
-        # Select the best destination address
-        if 'ConfigurationEndpoint' in cluster and cluster['ConfigurationEndpoint']:
-            # Memcached cluster
-            dest = cluster['ConfigurationEndpoint']['Address']
-            is_redis = False
-        else:
-            # Redis sigle node cluster
-            # Because all Redis clusters are single nodes, we'll merge the
-            # info from the cluster with info about the node
-            dest = cluster['CacheNodes'][0]['Endpoint']['Address']
-            is_redis = True
-
-        if not dest:
-            # Skip clusters we cannot address (e.g. private VPC subnet)
-            return
-
-        # Add to index
-        self.index[dest] = [region, cluster['CacheClusterId']]
-
-        # Inventory: Group by instance ID (always a group of 1)
-        if self.group_by_instance_id:
-            self.inventory[cluster['CacheClusterId']] = [dest]
-            if self.nested_groups:
-                self.push_group(self.inventory, 'instances', cluster['CacheClusterId'])
-
-        # Inventory: Group by region
-        if self.group_by_region and not is_redis:
-            self.push(self.inventory, region, dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'regions', region)
-
-        # Inventory: Group by availability zone
-        if self.group_by_availability_zone and not is_redis:
-            self.push(self.inventory, cluster['PreferredAvailabilityZone'], dest)
-            if self.nested_groups:
-                if self.group_by_region:
-                    self.push_group(self.inventory, region, cluster['PreferredAvailabilityZone'])
-                self.push_group(self.inventory, 'zones', cluster['PreferredAvailabilityZone'])
-
-        # Inventory: Group by node type
-        if self.group_by_instance_type and not is_redis:
-            type_name = self.to_safe('type_' + cluster['CacheNodeType'])
-            self.push(self.inventory, type_name, dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'types', type_name)
-
-        # Inventory: Group by VPC (information not available in the current
-        # AWS API version for ElastiCache)
-
-        # Inventory: Group by security group
-        if self.group_by_security_group and not is_redis:
-
-            # Check for the existence of the 'SecurityGroups' key and also if
-            # this key has some value. When the cluster is not placed in a SG
-            # the query can return None here and cause an error.
-            if 'SecurityGroups' in cluster and cluster['SecurityGroups'] is not None:
-                for security_group in cluster['SecurityGroups']:
-                    key = self.to_safe("security_group_" + security_group['SecurityGroupId'])
-                    self.push(self.inventory, key, dest)
-                    if self.nested_groups:
-                        self.push_group(self.inventory, 'security_groups', key)
-
-        # Inventory: Group by engine
-        if self.group_by_elasticache_engine and not is_redis:
-            self.push(self.inventory, self.to_safe("elasticache_" + cluster['Engine']), dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'elasticache_engines', self.to_safe(cluster['Engine']))
-
-        # Inventory: Group by parameter group
-        if self.group_by_elasticache_parameter_group:
-            self.push(self.inventory, self.to_safe("elasticache_parameter_group_" + cluster['CacheParameterGroup']['CacheParameterGroupName']), dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'elasticache_parameter_groups', self.to_safe(cluster['CacheParameterGroup']['CacheParameterGroupName']))
-
-        # Inventory: Group by replication group
-        if self.group_by_elasticache_replication_group and 'ReplicationGroupId' in cluster and cluster['ReplicationGroupId']:
-            self.push(self.inventory, self.to_safe("elasticache_replication_group_" + cluster['ReplicationGroupId']), dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'elasticache_replication_groups', self.to_safe(cluster['ReplicationGroupId']))
-
-        # Global Tag: all ElastiCache clusters
-        self.push(self.inventory, 'elasticache_clusters', cluster['CacheClusterId'])
-
-        host_info = self.get_host_info_dict_from_describe_dict(cluster)
-
-        self.inventory["_meta"]["hostvars"][dest] = host_info
-
-        # Add the nodes
-        for node in cluster['CacheNodes']:
-            self.add_elasticache_node(node, cluster, region)
-
-    def add_elasticache_node(self, node, cluster, region):
-        ''' Adds an ElastiCache node to the inventory and index, as long as
-        it is addressable '''
-
-        # Only want available nodes unless all_elasticache_nodes is True
-        if not self.all_elasticache_nodes and node['CacheNodeStatus'] != 'available':
-            return
-
-        # Select the best destination address
-        dest = node['Endpoint']['Address']
-
-        if not dest:
-            # Skip nodes we cannot address (e.g. private VPC subnet)
-            return
-
-        node_id = self.to_safe(cluster['CacheClusterId'] + '_' + node['CacheNodeId'])
-
-        # Add to index
-        self.index[dest] = [region, node_id]
-
-        # Inventory: Group by node ID (always a group of 1)
-        if self.group_by_instance_id:
-            self.inventory[node_id] = [dest]
-            if self.nested_groups:
-                self.push_group(self.inventory, 'instances', node_id)
-
-        # Inventory: Group by region
-        if self.group_by_region:
-            self.push(self.inventory, region, dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'regions', region)
-
-        # Inventory: Group by availability zone
-        if self.group_by_availability_zone:
-            self.push(self.inventory, cluster['PreferredAvailabilityZone'], dest)
-            if self.nested_groups:
-                if self.group_by_region:
-                    self.push_group(self.inventory, region, cluster['PreferredAvailabilityZone'])
-                self.push_group(self.inventory, 'zones', cluster['PreferredAvailabilityZone'])
-
-        # Inventory: Group by node type
-        if self.group_by_instance_type:
-            type_name = self.to_safe('type_' + cluster['CacheNodeType'])
-            self.push(self.inventory, type_name, dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'types', type_name)
-
-        # Inventory: Group by VPC (information not available in the current
-        # AWS API version for ElastiCache)
-
-        # Inventory: Group by security group
-        if self.group_by_security_group:
-
-            # Check for the existence of the 'SecurityGroups' key and also if
-            # this key has some value. When the cluster is not placed in a SG
-            # the query can return None here and cause an error.
-            if 'SecurityGroups' in cluster and cluster['SecurityGroups'] is not None:
-                for security_group in cluster['SecurityGroups']:
-                    key = self.to_safe("security_group_" + security_group['SecurityGroupId'])
-                    self.push(self.inventory, key, dest)
-                    if self.nested_groups:
-                        self.push_group(self.inventory, 'security_groups', key)
-
-        # Inventory: Group by engine
-        if self.group_by_elasticache_engine:
-            self.push(self.inventory, self.to_safe("elasticache_" + cluster['Engine']), dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'elasticache_engines', self.to_safe("elasticache_" + cluster['Engine']))
-
-        # Inventory: Group by parameter group (done at cluster level)
-
-        # Inventory: Group by replication group (done at cluster level)
-
-        # Inventory: Group by ElastiCache Cluster
-        if self.group_by_elasticache_cluster:
-            self.push(self.inventory, self.to_safe("elasticache_cluster_" + cluster['CacheClusterId']), dest)
-
-        # Global Tag: all ElastiCache nodes
-        self.push(self.inventory, 'elasticache_nodes', dest)
-
-        host_info = self.get_host_info_dict_from_describe_dict(node)
-
-        if dest in self.inventory["_meta"]["hostvars"]:
-            self.inventory["_meta"]["hostvars"][dest].update(host_info)
-        else:
-            self.inventory["_meta"]["hostvars"][dest] = host_info
-
-    def add_elasticache_replication_group(self, replication_group, region):
-        ''' Adds an ElastiCache replication group to the inventory and index '''
-
-        # Only want available clusters unless all_elasticache_replication_groups is True
-        if not self.all_elasticache_replication_groups and replication_group['Status'] != 'available':
-            return
-
-        # Select the best destination address (PrimaryEndpoint)
-        dest = replication_group['NodeGroups'][0]['PrimaryEndpoint']['Address']
-
-        if not dest:
-            # Skip clusters we cannot address (e.g. private VPC subnet)
-            return
-
-        # Add to index
-        self.index[dest] = [region, replication_group['ReplicationGroupId']]
-
-        # Inventory: Group by ID (always a group of 1)
-        if self.group_by_instance_id:
-            self.inventory[replication_group['ReplicationGroupId']] = [dest]
-            if self.nested_groups:
-                self.push_group(self.inventory, 'instances', replication_group['ReplicationGroupId'])
-
-        # Inventory: Group by region
-        if self.group_by_region:
-            self.push(self.inventory, region, dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'regions', region)
-
-        # Inventory: Group by availability zone (doesn't apply to replication groups)
-
-        # Inventory: Group by node type (doesn't apply to replication groups)
-
-        # Inventory: Group by VPC (information not available in the current
-        # AWS API version for replication groups
-
-        # Inventory: Group by security group (doesn't apply to replication groups)
-        # Check this value in cluster level
-
-        # Inventory: Group by engine (replication groups are always Redis)
-        if self.group_by_elasticache_engine:
-            self.push(self.inventory, 'elasticache_redis', dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'elasticache_engines', 'redis')
-
-        # Global Tag: all ElastiCache clusters
-        self.push(self.inventory, 'elasticache_replication_groups', replication_group['ReplicationGroupId'])
-
-        host_info = self.get_host_info_dict_from_describe_dict(replication_group)
-
-        self.inventory["_meta"]["hostvars"][dest] = host_info
-
-    def get_route53_records(self):
-        ''' Get and store the map of resource records to domain names that
-        point to them. '''
-
-        r53_conn = route53.Route53Connection()
-        all_zones = r53_conn.get_zones()
-
-        route53_zones = [ zone for zone in all_zones if zone.name[:-1]
-                          not in self.route53_excluded_zones ]
-
-        self.route53_records = {}
-
-        for zone in route53_zones:
-            rrsets = r53_conn.get_all_rrsets(zone.id)
-
-            for record_set in rrsets:
-                record_name = record_set.name
-
-                if record_name.endswith('.'):
-                    record_name = record_name[:-1]
-
-                for resource in record_set.resource_records:
-                    self.route53_records.setdefault(resource, set())
-                    self.route53_records[resource].add(record_name)
-
-
-    def get_instance_route53_names(self, instance):
-        ''' Check if an instance is referenced in the records we have from
-        Route53. If it is, return the list of domain names pointing to said
-        instance. If nothing points to it, return an empty list. '''
-
-        instance_attributes = [ 'public_dns_name', 'private_dns_name',
-                                'ip_address', 'private_ip_address' ]
-
-        name_list = set()
-
-        for attrib in instance_attributes:
-            try:
-                value = getattr(instance, attrib)
-            except AttributeError:
-                continue
-
-            if value in self.route53_records:
-                name_list.update(self.route53_records[value])
-
-        return list(name_list)
-
-    def get_host_info_dict_from_instance(self, instance):
-        instance_vars = {}
-        for key in vars(instance):
-            value = getattr(instance, key)
-            key = self.to_safe('ec2_' + key)
-
-            # Handle complex types
-            # state/previous_state changed to properties in boto in https://github.com/boto/boto/commit/a23c379837f698212252720d2af8dec0325c9518
-            if key == 'ec2__state':
-                instance_vars['ec2_state'] = instance.state or ''
-                instance_vars['ec2_state_code'] = instance.state_code
-            elif key == 'ec2__previous_state':
-                instance_vars['ec2_previous_state'] = instance.previous_state or ''
-                instance_vars['ec2_previous_state_code'] = instance.previous_state_code
-            elif type(value) in [int, bool]:
-                instance_vars[key] = value
-            elif isinstance(value, six.string_types):
-                instance_vars[key] = value.strip()
-            elif type(value) == type(None):
-                instance_vars[key] = ''
-            elif key == 'ec2_region':
-                instance_vars[key] = value.name
-            elif key == 'ec2__placement':
-                instance_vars['ec2_placement'] = value.zone
-            elif key == 'ec2_tags':
-                for k, v in value.items():
-                    if self.expand_csv_tags and ',' in v:
-                        v = map(lambda x: x.strip(), v.split(','))
-                    key = self.to_safe('ec2_tag_' + k)
-                    instance_vars[key] = v
-            elif key == 'ec2_groups':
-                group_ids = []
-                group_names = []
-                for group in value:
-                    group_ids.append(group.id)
-                    group_names.append(group.name)
-                instance_vars["ec2_security_group_ids"] = ','.join([str(i) for i in group_ids])
-                instance_vars["ec2_security_group_names"] = ','.join([str(i) for i in group_names])
-            else:
-                pass
-                # TODO Product codes if someone finds them useful
-                #print key
-                #print type(value)
-                #print value
-
-        return instance_vars
-
-    def get_host_info_dict_from_describe_dict(self, describe_dict):
-        ''' Parses the dictionary returned by the API call into a flat list
-            of parameters. This method should be used only when 'describe' is
-            used directly because Boto doesn't provide specific classes. '''
-
-        # I really don't agree with prefixing everything with 'ec2'
-        # because EC2, RDS and ElastiCache are different services.
-        # I'm just following the pattern used until now to not break any
-        # compatibility.
-
-        host_info = {}
-        for key in describe_dict:
-            value = describe_dict[key]
-            key = self.to_safe('ec2_' + self.uncammelize(key))
-
-            # Handle complex types
-
-            # Target: Memcached Cache Clusters
-            if key == 'ec2_configuration_endpoint' and value:
-                host_info['ec2_configuration_endpoint_address'] = value['Address']
-                host_info['ec2_configuration_endpoint_port'] = value['Port']
-
-            # Target: Cache Nodes and Redis Cache Clusters (single node)
-            if key == 'ec2_endpoint' and value:
-                host_info['ec2_endpoint_address'] = value['Address']
-                host_info['ec2_endpoint_port'] = value['Port']
-
-            # Target: Redis Replication Groups
-            if key == 'ec2_node_groups' and value:
-                host_info['ec2_endpoint_address'] = value[0]['PrimaryEndpoint']['Address']
-                host_info['ec2_endpoint_port'] = value[0]['PrimaryEndpoint']['Port']
-                replica_count = 0
-                for node in value[0]['NodeGroupMembers']:
-                    if node['CurrentRole'] == 'primary':
-                        host_info['ec2_primary_cluster_address'] = node['ReadEndpoint']['Address']
-                        host_info['ec2_primary_cluster_port'] = node['ReadEndpoint']['Port']
-                        host_info['ec2_primary_cluster_id'] = node['CacheClusterId']
-                    elif node['CurrentRole'] == 'replica':
-                        host_info['ec2_replica_cluster_address_'+ str(replica_count)] = node['ReadEndpoint']['Address']
-                        host_info['ec2_replica_cluster_port_'+ str(replica_count)] = node['ReadEndpoint']['Port']
-                        host_info['ec2_replica_cluster_id_'+ str(replica_count)] = node['CacheClusterId']
-                        replica_count += 1
-
-            # Target: Redis Replication Groups
-            if key == 'ec2_member_clusters' and value:
-                host_info['ec2_member_clusters'] = ','.join([str(i) for i in value])
-
-            # Target: All Cache Clusters
-            elif key == 'ec2_cache_parameter_group':
-                host_info["ec2_cache_node_ids_to_reboot"] = ','.join([str(i) for i in value['CacheNodeIdsToReboot']])
-                host_info['ec2_cache_parameter_group_name'] = value['CacheParameterGroupName']
-                host_info['ec2_cache_parameter_apply_status'] = value['ParameterApplyStatus']
-
-            # Target: Almost everything
-            elif key == 'ec2_security_groups':
-
-                # Skip if SecurityGroups is None
-                # (it is possible to have the key defined but no value in it).
-                if value is not None:
-                    sg_ids = []
-                    for sg in value:
-                        sg_ids.append(sg['SecurityGroupId'])
-                    host_info["ec2_security_group_ids"] = ','.join([str(i) for i in sg_ids])
-
-            # Target: Everything
-            # Preserve booleans and integers
-            elif type(value) in [int, bool]:
-                host_info[key] = value
-
-            # Target: Everything
-            # Sanitize string values
-            elif isinstance(value, six.string_types):
-                host_info[key] = value.strip()
-
-            # Target: Everything
-            # Replace None by an empty string
-            elif type(value) == type(None):
-                host_info[key] = ''
-
-            else:
-                # Remove non-processed complex types
-                pass
-
-        return host_info
-
-    def get_host_info(self):
-        ''' Get variables about a specific host '''
-
-        if len(self.index) == 0:
-            # Need to load index from cache
-            self.load_index_from_cache()
-
-        if not self.args.host in self.index:
-            # try updating the cache
-            self.do_api_calls_update_cache()
-            if not self.args.host in self.index:
-                # host might not exist anymore
-                return self.json_format_dict({}, True)
-
-        (region, instance_id) = self.index[self.args.host]
-
-        instance = self.get_instance(region, instance_id)
-        return self.json_format_dict(self.get_host_info_dict_from_instance(instance), True)
-
-    def push(self, my_dict, key, element):
-        ''' Push an element onto an array that may not have been defined in
-        the dict '''
-        group_info = my_dict.setdefault(key, [])
-        if isinstance(group_info, dict):
-            host_list = group_info.setdefault('hosts', [])
-            host_list.append(element)
-        else:
-            group_info.append(element)
-
-    def push_group(self, my_dict, key, element):
-        ''' Push a group as a child of another group. '''
-        parent_group = my_dict.setdefault(key, {})
-        if not isinstance(parent_group, dict):
-            parent_group = my_dict[key] = {'hosts': parent_group}
-        child_groups = parent_group.setdefault('children', [])
-        if element not in child_groups:
-            child_groups.append(element)
-
-    def get_inventory_from_cache(self):
-        ''' Reads the inventory from the cache file and returns it as a JSON
-        object '''
-
-        cache = open(self.cache_path_cache, 'r')
-        json_inventory = cache.read()
-        return json_inventory
-
-
-    def load_index_from_cache(self):
-        ''' Reads the index from the cache file sets self.index '''
-
-        cache = open(self.cache_path_index, 'r')
-        json_index = cache.read()
-        self.index = json.loads(json_index)
-
-
-    def write_to_cache(self, data, filename):
-        ''' Writes data in JSON format to a file '''
-
-        json_data = self.json_format_dict(data, True)
-        cache = open(filename, 'w')
-        cache.write(json_data)
-        cache.close()
-
-    def uncammelize(self, key):
-        temp = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', key)
-        return re.sub('([a-z0-9])([A-Z])', r'\1_\2', temp).lower()
-
-    def to_safe(self, word):
-        ''' Converts 'bad' characters in a string to underscores so they can be used as Ansible groups '''
-        regex = "[^A-Za-z0-9\_"
-        if not self.replace_dash_in_groups:
-            regex += "\-"
-        return re.sub(regex + "]", "_", word)
-
-    def json_format_dict(self, data, pretty=False):
-        ''' Converts a dict to a JSON object and dumps it as a formatted
-        string '''
-
-        if pretty:
-            return json.dumps(data, sort_keys=True, indent=2)
-        else:
-            return json.dumps(data)
-
-
-# Run the script
-Ec2Inventory()
diff --git a/edge-1609-dc4/inventory b/edge-1609-dc4/inventory
deleted file mode 100644
index 47150f9..0000000
--- a/edge-1609-dc4/inventory
+++ /dev/null
@@ -1,87 +0,0 @@
-[tag_Name_dc4_n1]
-[tag_Name_dc4_n2]
-[tag_Name_dc4_n3]
-[tag_Name_dc4_n4]
-[tag_Name_dc4_n5]
-[tag_Name_dc4_n6]
-[tag_Name_dc4_n7]
-[tag_Name_dc4_n8]
-[tag_Name_dc4_n9]
-[tag_Name_dc4_n10]
-[tag_Name_dc4_n11]
-
-[planet:children]
-dc-1
-
-[dc-1:children]
-tag_Name_dc4_n1
-tag_Name_dc4_n2
-tag_Name_dc4_n3
-tag_Name_dc4_n4
-tag_Name_dc4_n5
-tag_Name_dc4_n6
-tag_Name_dc4_n7
-tag_Name_dc4_n8
-tag_Name_dc4_n9
-tag_Name_dc4_n10
-tag_Name_dc4_n11
-
-[ds:children]
-dc-1-ds
-
-[dc-1-ds:children]
-tag_Name_dc4_n2
-tag_Name_dc4_n3
-tag_Name_dc4_n4
-
-[ms:children]
-dc-1-ms
-
-[dc-1-ms:children]
-tag_Name_dc4_n1
-
-[ui:children]
-dc-1-ui
-
-[dc-1-ui:children]
-tag_Name_dc4_n1
-
-[ldap:children]
-dc-1-ldap
-
-[dc-1-ldap:children]
-tag_Name_dc4_n1
-
-[rmp:children]
-dc-1-rmp
-
-[dc-1-rmp:children]
-tag_Name_dc4_n5
-tag_Name_dc4_n6
-
-[qpid:children]
-dc-1-qpid
-
-[dc-1-qpid:children]
-tag_Name_dc4_n7
-tag_Name_dc4_n8
-
-[pg:children]
-dc-1-pg
-
-[dc-1-pg:children]
-dc-1-pgmaster
-dc-1-pgstandby
-
-[pgmaster:children]
-dc-1-pgmaster
-
-[dc-1-pgmaster:children]
-tag_Name_dc4_n9
-
-[pgstandby:children]
-dc-1-pgstandby
-
-[dc-1-pgstandby:children]
-tag_Name_dc4_n10
-
diff --git a/edge-1701-dc1/ec2.ini b/edge-1701-dc1/ec2.ini
deleted file mode 100644
index 36b3921..0000000
--- a/edge-1701-dc1/ec2.ini
+++ /dev/null
@@ -1,200 +0,0 @@
-# Ansible EC2 external inventory script settings
-#
-
-[ec2]
-
-# to talk to a private eucalyptus instance uncomment these lines
-# and edit edit eucalyptus_host to be the host name of your cloud controller
-#eucalyptus = True
-#eucalyptus_host = clc.cloud.domain.org
-
-# AWS regions to make calls to. Set this to 'all' to make request to all regions
-# in AWS and merge the results together. Alternatively, set this to a comma
-# separated list of regions. E.g. 'us-east-1,us-west-1,us-west-2'
-regions = all
-regions_exclude = us-gov-west-1,cn-north-1
-
-# When generating inventory, Ansible needs to know how to address a server.
-# Each EC2 instance has a lot of variables associated with it. Here is the list:
-#   http://docs.pythonboto.org/en/latest/ref/ec2.html#module-boto.ec2.instance
-# Below are 2 variables that are used as the address of a server:
-#   - destination_variable
-#   - vpc_destination_variable
-
-# This is the normal destination variable to use. If you are running Ansible
-# from outside EC2, then 'public_dns_name' makes the most sense. If you are
-# running Ansible from within EC2, then perhaps you want to use the internal
-# address, and should set this to 'private_dns_name'. The key of an EC2 tag
-# may optionally be used; however the boto instance variables hold precedence
-# in the event of a collision.
-destination_variable = public_dns_name
-
-# This allows you to override the inventory_name with an ec2 variable, instead
-# of using the destination_variable above. Addressing (aka ansible_ssh_host)
-# will still use destination_variable. Tags should be written as 'tag_TAGNAME'.
-#hostname_variable = tag_Name
-
-# For server inside a VPC, using DNS names may not make sense. When an instance
-# has 'subnet_id' set, this variable is used. If the subnet is public, setting
-# this to 'ip_address' will return the public IP address. For instances in a
-# private subnet, this should be set to 'private_ip_address', and Ansible must
-# be run from within EC2. The key of an EC2 tag may optionally be used; however
-# the boto instance variables hold precedence in the event of a collision.
-# WARNING: - instances that are in the private vpc, _without_ public ip address
-# will not be listed in the inventory until You set:
-# vpc_destination_variable = private_ip_address
-vpc_destination_variable = ip_address
-
-# The following two settings allow flexible ansible host naming based on a
-# python format string and a comma-separated list of ec2 tags.  Note that:
-#
-# 1) If the tags referenced are not present for some instances, empty strings
-#    will be substituted in the format string.
-# 2) This overrides both destination_variable and vpc_destination_variable.
-#
-#destination_format = {0}.{1}.example.com
-#destination_format_tags = Name,environment
-
-# To tag instances on EC2 with the resource records that point to them from
-# Route53, uncomment and set 'route53' to True.
-route53 = False
-
-# To exclude RDS instances from the inventory, uncomment and set to False.
-rds = False
-
-# To exclude ElastiCache instances from the inventory, uncomment and set to False.
-elasticache = False
-
-# Additionally, you can specify the list of zones to exclude looking up in
-# 'route53_excluded_zones' as a comma-separated list.
-# route53_excluded_zones = samplezone1.com, samplezone2.com
-
-# By default, only EC2 instances in the 'running' state are returned. Set
-# 'all_instances' to True to return all instances regardless of state.
-all_instances = True
-
-# By default, only EC2 instances in the 'running' state are returned. Specify
-# EC2 instance states to return as a comma-separated list. This
-# option is overriden when 'all_instances' is True.
-# instance_states = pending, running, shutting-down, terminated, stopping, stopped
-
-# By default, only RDS instances in the 'available' state are returned.  Set
-# 'all_rds_instances' to True return all RDS instances regardless of state.
-all_rds_instances = False
-
-# By default, only ElastiCache clusters and nodes in the 'available' state
-# are returned. Set 'all_elasticache_clusters' and/or 'all_elastic_nodes'
-# to True return all ElastiCache clusters and nodes, regardless of state.
-#
-# Note that all_elasticache_nodes only applies to listed clusters. That means
-# if you set all_elastic_clusters to false, no node will be return from
-# unavailable clusters, regardless of the state and to what you set for
-# all_elasticache_nodes.
-all_elasticache_replication_groups = False
-all_elasticache_clusters = False
-all_elasticache_nodes = False
-
-# API calls to EC2 are slow. For this reason, we cache the results of an API
-# call. Set this to the path you want cache files to be written to. Two files
-# will be written to this directory:
-#   - ansible-ec2.cache
-#   - ansible-ec2.index
-cache_path = ~/.ansible/tmp
-
-# The number of seconds a cache file is considered valid. After this many
-# seconds, a new API call will be made, and the cache file will be updated.
-# To disable the cache, set this value to 0
-cache_max_age = 300
-
-# Organize groups into a nested/hierarchy instead of a flat namespace.
-nested_groups = False
-
-# Replace - tags when creating groups to avoid issues with ansible
-replace_dash_in_groups = True
-
-# If set to true, any tag of the form "a,b,c" is expanded into a list
-# and the results are used to create additional tag_* inventory groups.
-expand_csv_tags = False
-
-# The EC2 inventory output can become very large. To manage its size,
-# configure which groups should be created.
-group_by_instance_id = True
-group_by_region = True
-group_by_availability_zone = True
-group_by_ami_id = True
-group_by_instance_type = True
-group_by_key_pair = True
-group_by_vpc_id = True
-group_by_security_group = True
-group_by_tag_keys = True
-group_by_tag_none = True
-group_by_route53_names = True
-group_by_rds_engine = False
-group_by_rds_parameter_group = False
-group_by_elasticache_engine = True
-group_by_elasticache_cluster = True
-group_by_elasticache_parameter_group = True
-group_by_elasticache_replication_group = True
-
-# If you only want to include hosts that match a certain regular expression
-# pattern_include = staging-*
-
-# If you want to exclude any hosts that match a certain regular expression
-# pattern_exclude = staging-*
-# Ansible EC2 external inventory script settings
-#
-
-##[ec2]
-##
-### to talk to a private eucalyptus instance uncomment these lines
-### and edit edit eucalyptus_host to be the host name of your cloud controller
-###eucalyptus = True
-###eucalyptus_host = clc.cloud.domain.org
-##
-### AWS regions to make calls to. Set this to 'all' to make request to all regions
-##
-### in AWS and merge the results together. Alternatively, set this to a comma
-### separated list of regions. E.g. 'us-east-1,us-west-1,us-west-2'
-##regions = all
-##regions_exclude = us-gov-west-1,cn-north-1
-##
-### When generating inventory, Ansible needs to know how to address a server.
-### Each EC2 instance has a lot of variables associated with it. Here is the list:
-###   http://docs.pythonboto.org/en/latest/ref/ec2.html#module-boto.ec2.instance
-### Below are 2 variables that are used as the address of a server:
-###   - destination_variable
-###   - vpc_destination_variable
-##
-### This is the normal destination variable to use. If you are running Ansible
-### from outside EC2, then 'public_dns_name' makes the most sense. If you are
-### running Ansible from within EC2, then perhaps you want to use the internal
-### address, and should set this to 'private_dns_name'. The key of an EC2 tag
-##...skipping...
-### pattern_include = staging-*
-##
-### If you want to exclude any hosts that match a certain regular expression
-### pattern_exclude = staging-*
-
-# Instance filters can be used to control which instances are retrieved for
-# inventory. For the full list of possible filters, please read the EC2 API
-# docs: http://docs.aws.amazon.com/AWSEC2/latest/APIReference/ApiReference-query-DescribeInstances.html#query-DescribeInstances-filters
-# Filters are key/value pairs separated by '=', to list multiple filters use
-# a list separated by commas. See examples below.
-
-# Retrieve only instances with (key=value) env=staging tag
-# instance_filters = tag:env=staging
-
-# Retrieve only instances with role=webservers OR role=dbservers tag
-# instance_filters = tag:role=webservers,tag:role=dbservers
-
-# Retrieve only t1.micro instances OR instances with tag env=staging
-# instance_filters = instance-type=t1.micro,tag:env=staging
-
-# You can use wildcards in filter values also. Below will list instances which
-# tag Name value matches webservers1*
-# (ex. webservers15, webservers1a, webservers123 etc)
-# instance_filters = tag:Name=webservers1*
-
-# A boto configuration profile may be used to separate out credentials
-# see http://boto.readthedocs.org/en/latest/boto_config_tut.html
-# boto_profile = some-boto-profile-name
diff --git a/edge-1701-dc1/ec2.py b/edge-1701-dc1/ec2.py
deleted file mode 100755
index f30958a..0000000
--- a/edge-1701-dc1/ec2.py
+++ /dev/null
@@ -1,1385 +0,0 @@
-#!/usr/bin/env python
-
-'''
-EC2 external inventory script
-=================================
-
-Generates inventory that Ansible can understand by making API request to
-AWS EC2 using the Boto library.
-
-NOTE: This script assumes Ansible is being executed where the environment
-variables needed for Boto have already been set:
-    export AWS_ACCESS_KEY_ID='AK123'
-    export AWS_SECRET_ACCESS_KEY='abc123'
-
-This script also assumes there is an ec2.ini file alongside it.  To specify a
-different path to ec2.ini, define the EC2_INI_PATH environment variable:
-
-    export EC2_INI_PATH=/path/to/my_ec2.ini
-
-If you're using eucalyptus you need to set the above variables and
-you need to define:
-
-    export EC2_URL=http://hostname_of_your_cc:port/services/Eucalyptus
-
-If you're using boto profiles (requires boto>=2.24.0) you can choose a profile
-using the --boto-profile command line argument (e.g. ec2.py --boto-profile prod) or using
-the AWS_PROFILE variable:
-
-    AWS_PROFILE=prod ansible-playbook -i ec2.py myplaybook.yml
-
-For more details, see: http://docs.pythonboto.org/en/latest/boto_config_tut.html
-
-When run against a specific host, this script returns the following variables:
- - ec2_ami_launch_index
- - ec2_architecture
- - ec2_association
- - ec2_attachTime
- - ec2_attachment
- - ec2_attachmentId
- - ec2_client_token
- - ec2_deleteOnTermination
- - ec2_description
- - ec2_deviceIndex
- - ec2_dns_name
- - ec2_eventsSet
- - ec2_group_name
- - ec2_hypervisor
- - ec2_id
- - ec2_image_id
- - ec2_instanceState
- - ec2_instance_type
- - ec2_ipOwnerId
- - ec2_ip_address
- - ec2_item
- - ec2_kernel
- - ec2_key_name
- - ec2_launch_time
- - ec2_monitored
- - ec2_monitoring
- - ec2_networkInterfaceId
- - ec2_ownerId
- - ec2_persistent
- - ec2_placement
- - ec2_platform
- - ec2_previous_state
- - ec2_private_dns_name
- - ec2_private_ip_address
- - ec2_publicIp
- - ec2_public_dns_name
- - ec2_ramdisk
- - ec2_reason
- - ec2_region
- - ec2_requester_id
- - ec2_root_device_name
- - ec2_root_device_type
- - ec2_security_group_ids
- - ec2_security_group_names
- - ec2_shutdown_state
- - ec2_sourceDestCheck
- - ec2_spot_instance_request_id
- - ec2_state
- - ec2_state_code
- - ec2_state_reason
- - ec2_status
- - ec2_subnet_id
- - ec2_tenancy
- - ec2_virtualization_type
- - ec2_vpc_id
-
-These variables are pulled out of a boto.ec2.instance object. There is a lack of
-consistency with variable spellings (camelCase and underscores) since this
-just loops through all variables the object exposes. It is preferred to use the
-ones with underscores when multiple exist.
-
-In addition, if an instance has AWS Tags associated with it, each tag is a new
-variable named:
- - ec2_tag_[Key] = [Value]
-
-Security groups are comma-separated in 'ec2_security_group_ids' and
-'ec2_security_group_names'.
-'''
-
-# (c) 2012, Peter Sankauskas
-#
-# This file is part of Ansible,
-#
-# Ansible is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# Ansible is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with Ansible.  If not, see <http://www.gnu.org/licenses/>.
-
-######################################################################
-
-import sys
-import os
-import argparse
-import re
-from time import time
-import boto
-from boto import ec2
-from boto import rds
-from boto import elasticache
-from boto import route53
-import six
-
-from six.moves import configparser
-from collections import defaultdict
-
-try:
-    import json
-except ImportError:
-    import simplejson as json
-
-
-class Ec2Inventory(object):
-
-    def _empty_inventory(self):
-        return {"_meta" : {"hostvars" : {}}}
-
-    def __init__(self):
-        ''' Main execution path '''
-
-        # Inventory grouped by instance IDs, tags, security groups, regions,
-        # and availability zones
-        self.inventory = self._empty_inventory()
-
-        # Index of hostname (address) to instance ID
-        self.index = {}
-
-        # Boto profile to use (if any)
-        self.boto_profile = None
-
-        # Read settings and parse CLI arguments
-        self.parse_cli_args()
-        self.read_settings()
-
-        # Make sure that profile_name is not passed at all if not set
-        # as pre 2.24 boto will fall over otherwise
-        if self.boto_profile:
-            if not hasattr(boto.ec2.EC2Connection, 'profile_name'):
-                self.fail_with_error("boto version must be >= 2.24 to use profile")
-
-        # Cache
-        if self.args.refresh_cache:
-            self.do_api_calls_update_cache()
-        elif not self.is_cache_valid():
-            self.do_api_calls_update_cache()
-
-        # Data to print
-        if self.args.host:
-            data_to_print = self.get_host_info()
-
-        elif self.args.list:
-            # Display list of instances for inventory
-            if self.inventory == self._empty_inventory():
-                data_to_print = self.get_inventory_from_cache()
-            else:
-                data_to_print = self.json_format_dict(self.inventory, True)
-
-        print(data_to_print)
-
-
-    def is_cache_valid(self):
-        ''' Determines if the cache files have expired, or if it is still valid '''
-
-        if os.path.isfile(self.cache_path_cache):
-            mod_time = os.path.getmtime(self.cache_path_cache)
-            current_time = time()
-            if (mod_time + self.cache_max_age) > current_time:
-                if os.path.isfile(self.cache_path_index):
-                    return True
-
-        return False
-
-
-    def read_settings(self):
-        ''' Reads the settings from the ec2.ini file '''
-        if six.PY3:
-            config = configparser.ConfigParser()
-        else:
-            config = configparser.SafeConfigParser()
-        ec2_default_ini_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'ec2.ini')
-        ec2_ini_path = os.path.expanduser(os.path.expandvars(os.environ.get('EC2_INI_PATH', ec2_default_ini_path)))
-        config.read(ec2_ini_path)
-
-        # is eucalyptus?
-        self.eucalyptus_host = None
-        self.eucalyptus = False
-        if config.has_option('ec2', 'eucalyptus'):
-            self.eucalyptus = config.getboolean('ec2', 'eucalyptus')
-        if self.eucalyptus and config.has_option('ec2', 'eucalyptus_host'):
-            self.eucalyptus_host = config.get('ec2', 'eucalyptus_host')
-
-        # Regions
-        self.regions = []
-        configRegions = config.get('ec2', 'regions')
-        configRegions_exclude = config.get('ec2', 'regions_exclude')
-        if (configRegions == 'all'):
-            if self.eucalyptus_host:
-                self.regions.append(boto.connect_euca(host=self.eucalyptus_host).region.name)
-            else:
-                for regionInfo in ec2.regions():
-                    if regionInfo.name not in configRegions_exclude:
-                        self.regions.append(regionInfo.name)
-        else:
-            self.regions = configRegions.split(",")
-
-        # Destination addresses
-        self.destination_variable = config.get('ec2', 'destination_variable')
-        self.vpc_destination_variable = config.get('ec2', 'vpc_destination_variable')
-
-        if config.has_option('ec2', 'hostname_variable'):
-            self.hostname_variable = config.get('ec2', 'hostname_variable')
-        else:
-            self.hostname_variable = None
-
-        if config.has_option('ec2', 'destination_format') and \
-                config.has_option('ec2', 'destination_format_tags'):
-            self.destination_format = config.get('ec2', 'destination_format')
-            self.destination_format_tags = config.get('ec2', 'destination_format_tags').split(',')
-        else:
-            self.destination_format = None
-            self.destination_format_tags = None
-
-        # Route53
-        self.route53_enabled = config.getboolean('ec2', 'route53')
-        self.route53_excluded_zones = []
-        if config.has_option('ec2', 'route53_excluded_zones'):
-            self.route53_excluded_zones.extend(
-                    config.get('ec2', 'route53_excluded_zones', '').split(','))
-
-        # Include RDS instances?
-        self.rds_enabled = True
-        if config.has_option('ec2', 'rds'):
-            self.rds_enabled = config.getboolean('ec2', 'rds')
-
-        # Include ElastiCache instances?
-        self.elasticache_enabled = True
-        if config.has_option('ec2', 'elasticache'):
-            self.elasticache_enabled = config.getboolean('ec2', 'elasticache')
-
-        # Return all EC2 instances?
-        if config.has_option('ec2', 'all_instances'):
-            self.all_instances = config.getboolean('ec2', 'all_instances')
-        else:
-            self.all_instances = False
-
-        # Instance states to be gathered in inventory. Default is 'running'.
-        # Setting 'all_instances' to 'yes' overrides this option.
-        ec2_valid_instance_states = [
-            'pending',
-            'running',
-            'shutting-down',
-            'terminated',
-            'stopping',
-            'stopped'
-        ]
-        self.ec2_instance_states = []
-        if self.all_instances:
-            self.ec2_instance_states = ec2_valid_instance_states
-        elif config.has_option('ec2', 'instance_states'):
-            for instance_state in config.get('ec2', 'instance_states').split(','):
-                instance_state = instance_state.strip()
-                if instance_state not in ec2_valid_instance_states:
-                    continue
-                self.ec2_instance_states.append(instance_state)
-        else:
-            self.ec2_instance_states = ['running']
-
-        # Return all RDS instances? (if RDS is enabled)
-        if config.has_option('ec2', 'all_rds_instances') and self.rds_enabled:
-            self.all_rds_instances = config.getboolean('ec2', 'all_rds_instances')
-        else:
-            self.all_rds_instances = False
-
-        # Return all ElastiCache replication groups? (if ElastiCache is enabled)
-        if config.has_option('ec2', 'all_elasticache_replication_groups') and self.elasticache_enabled:
-            self.all_elasticache_replication_groups = config.getboolean('ec2', 'all_elasticache_replication_groups')
-        else:
-            self.all_elasticache_replication_groups = False
-
-        # Return all ElastiCache clusters? (if ElastiCache is enabled)
-        if config.has_option('ec2', 'all_elasticache_clusters') and self.elasticache_enabled:
-            self.all_elasticache_clusters = config.getboolean('ec2', 'all_elasticache_clusters')
-        else:
-            self.all_elasticache_clusters = False
-
-        # Return all ElastiCache nodes? (if ElastiCache is enabled)
-        if config.has_option('ec2', 'all_elasticache_nodes') and self.elasticache_enabled:
-            self.all_elasticache_nodes = config.getboolean('ec2', 'all_elasticache_nodes')
-        else:
-            self.all_elasticache_nodes = False
-
-        # boto configuration profile (prefer CLI argument)
-        self.boto_profile = self.args.boto_profile
-        if config.has_option('ec2', 'boto_profile') and not self.boto_profile:
-            self.boto_profile = config.get('ec2', 'boto_profile')
-
-        # Cache related
-        cache_dir = os.path.expanduser(config.get('ec2', 'cache_path'))
-        if self.boto_profile:
-            cache_dir = os.path.join(cache_dir, 'profile_' + self.boto_profile)
-        if not os.path.exists(cache_dir):
-            os.makedirs(cache_dir)
-
-        cache_name = 'ansible-ec2'
-        aws_profile = lambda: (self.boto_profile or
-                               os.environ.get('AWS_PROFILE') or
-                               os.environ.get('AWS_ACCESS_KEY_ID'))
-        if aws_profile():
-            cache_name = '%s-%s' % (cache_name, aws_profile())
-        self.cache_path_cache = cache_dir + "/%s.cache" % cache_name
-        self.cache_path_index = cache_dir + "/%s.index" % cache_name
-        self.cache_max_age = config.getint('ec2', 'cache_max_age')
-
-        if config.has_option('ec2', 'expand_csv_tags'):
-            self.expand_csv_tags = config.getboolean('ec2', 'expand_csv_tags')
-        else:
-            self.expand_csv_tags = False
-
-        # Configure nested groups instead of flat namespace.
-        if config.has_option('ec2', 'nested_groups'):
-            self.nested_groups = config.getboolean('ec2', 'nested_groups')
-        else:
-            self.nested_groups = False
-
-        # Replace dash or not in group names
-        if config.has_option('ec2', 'replace_dash_in_groups'):
-            self.replace_dash_in_groups = config.getboolean('ec2', 'replace_dash_in_groups')
-        else:
-            self.replace_dash_in_groups = True
-
-        # Configure which groups should be created.
-        group_by_options = [
-            'group_by_instance_id',
-            'group_by_region',
-            'group_by_availability_zone',
-            'group_by_ami_id',
-            'group_by_instance_type',
-            'group_by_key_pair',
-            'group_by_vpc_id',
-            'group_by_security_group',
-            'group_by_tag_keys',
-            'group_by_tag_none',
-            'group_by_route53_names',
-            'group_by_rds_engine',
-            'group_by_rds_parameter_group',
-            'group_by_elasticache_engine',
-            'group_by_elasticache_cluster',
-            'group_by_elasticache_parameter_group',
-            'group_by_elasticache_replication_group',
-        ]
-        for option in group_by_options:
-            if config.has_option('ec2', option):
-                setattr(self, option, config.getboolean('ec2', option))
-            else:
-                setattr(self, option, True)
-
-        # Do we need to just include hosts that match a pattern?
-        try:
-            pattern_include = config.get('ec2', 'pattern_include')
-            if pattern_include and len(pattern_include) > 0:
-                self.pattern_include = re.compile(pattern_include)
-            else:
-                self.pattern_include = None
-        except configparser.NoOptionError:
-            self.pattern_include = None
-
-        # Do we need to exclude hosts that match a pattern?
-        try:
-            pattern_exclude = config.get('ec2', 'pattern_exclude');
-            if pattern_exclude and len(pattern_exclude) > 0:
-                self.pattern_exclude = re.compile(pattern_exclude)
-            else:
-                self.pattern_exclude = None
-        except configparser.NoOptionError:
-            self.pattern_exclude = None
-
-        # Instance filters (see boto and EC2 API docs). Ignore invalid filters.
-        self.ec2_instance_filters = defaultdict(list)
-        if config.has_option('ec2', 'instance_filters'):
-
-            filters = [f for f in config.get('ec2', 'instance_filters').split(',') if f]
-
-            for instance_filter in filters:
-                instance_filter = instance_filter.strip()
-                if not instance_filter or '=' not in instance_filter:
-                    continue
-                filter_key, filter_value = [x.strip() for x in instance_filter.split('=', 1)]
-                if not filter_key:
-                    continue
-                self.ec2_instance_filters[filter_key].append(filter_value)
-
-    def parse_cli_args(self):
-        ''' Command line argument processing '''
-
-        parser = argparse.ArgumentParser(description='Produce an Ansible Inventory file based on EC2')
-        parser.add_argument('--list', action='store_true', default=True,
-                            help='List instances (default: True)')
-        parser.add_argument('--host', action='store',
-                            help='Get all the variables about a specific instance')
-        parser.add_argument('--refresh-cache', action='store_true', default=False,
-                            help='Force refresh of cache by making API requests to EC2 (default: False - use cache files)')
-        parser.add_argument('--profile', '--boto-profile', action='store', dest='boto_profile',
-                            help='Use boto profile for connections to EC2')
-        self.args = parser.parse_args()
-
-
-    def do_api_calls_update_cache(self):
-        ''' Do API calls to each region, and save data in cache files '''
-
-        if self.route53_enabled:
-            self.get_route53_records()
-
-        for region in self.regions:
-            self.get_instances_by_region(region)
-            if self.rds_enabled:
-                self.get_rds_instances_by_region(region)
-            if self.elasticache_enabled:
-                self.get_elasticache_clusters_by_region(region)
-                self.get_elasticache_replication_groups_by_region(region)
-
-        self.write_to_cache(self.inventory, self.cache_path_cache)
-        self.write_to_cache(self.index, self.cache_path_index)
-
-    def connect(self, region):
-        ''' create connection to api server'''
-        if self.eucalyptus:
-            conn = boto.connect_euca(host=self.eucalyptus_host)
-            conn.APIVersion = '2010-08-31'
-        else:
-            conn = self.connect_to_aws(ec2, region)
-        return conn
-
-    def boto_fix_security_token_in_profile(self, connect_args):
-        ''' monkey patch for boto issue boto/boto#2100 '''
-        profile = 'profile ' + self.boto_profile
-        if boto.config.has_option(profile, 'aws_security_token'):
-            connect_args['security_token'] = boto.config.get(profile, 'aws_security_token')
-        return connect_args
-
-    def connect_to_aws(self, module, region):
-        connect_args = {}
-
-        # only pass the profile name if it's set (as it is not supported by older boto versions)
-        if self.boto_profile:
-            connect_args['profile_name'] = self.boto_profile
-            self.boto_fix_security_token_in_profile(connect_args)
-
-        conn = module.connect_to_region(region, **connect_args)
-        # connect_to_region will fail "silently" by returning None if the region name is wrong or not supported
-        if conn is None:
-            self.fail_with_error("region name: %s likely not supported, or AWS is down.  connection to region failed." % region)
-        return conn
-
-    def get_instances_by_region(self, region):
-        ''' Makes an AWS EC2 API call to the list of instances in a particular
-        region '''
-
-        try:
-            conn = self.connect(region)
-            reservations = []
-            if self.ec2_instance_filters:
-                for filter_key, filter_values in self.ec2_instance_filters.items():
-                    reservations.extend(conn.get_all_instances(filters = { filter_key : filter_values }))
-            else:
-                reservations = conn.get_all_instances()
-
-            for reservation in reservations:
-                for instance in reservation.instances:
-                    self.add_instance(instance, region)
-
-        except boto.exception.BotoServerError as e:
-            if e.error_code == 'AuthFailure':
-                error = self.get_auth_error_message()
-            else:
-                backend = 'Eucalyptus' if self.eucalyptus else 'AWS'
-                error = "Error connecting to %s backend.\n%s" % (backend, e.message)
-            self.fail_with_error(error, 'getting EC2 instances')
-
-    def get_rds_instances_by_region(self, region):
-        ''' Makes an AWS API call to the list of RDS instances in a particular
-        region '''
-
-        try:
-            conn = self.connect_to_aws(rds, region)
-            if conn:
-                marker = None
-                while True:
-                    instances = conn.get_all_dbinstances(marker=marker)
-                    marker = instances.marker
-                    for instance in instances:
-                        self.add_rds_instance(instance, region)
-                    if not marker:
-                        break
-        except boto.exception.BotoServerError as e:
-            error = e.reason
-
-            if e.error_code == 'AuthFailure':
-                error = self.get_auth_error_message()
-            if not e.reason == "Forbidden":
-                error = "Looks like AWS RDS is down:\n%s" % e.message
-            self.fail_with_error(error, 'getting RDS instances')
-
-    def get_elasticache_clusters_by_region(self, region):
-        ''' Makes an AWS API call to the list of ElastiCache clusters (with
-        nodes' info) in a particular region.'''
-
-        # ElastiCache boto module doesn't provide a get_all_intances method,
-        # that's why we need to call describe directly (it would be called by
-        # the shorthand method anyway...)
-        try:
-            conn = self.connect_to_aws(elasticache, region)
-            if conn:
-                # show_cache_node_info = True
-                # because we also want nodes' information
-                response = conn.describe_cache_clusters(None, None, None, True)
-
-        except boto.exception.BotoServerError as e:
-            error = e.reason
-
-            if e.error_code == 'AuthFailure':
-                error = self.get_auth_error_message()
-            if not e.reason == "Forbidden":
-                error = "Looks like AWS ElastiCache is down:\n%s" % e.message
-            self.fail_with_error(error, 'getting ElastiCache clusters')
-
-        try:
-            # Boto also doesn't provide wrapper classes to CacheClusters or
-            # CacheNodes. Because of that wo can't make use of the get_list
-            # method in the AWSQueryConnection. Let's do the work manually
-            clusters = response['DescribeCacheClustersResponse']['DescribeCacheClustersResult']['CacheClusters']
-
-        except KeyError as e:
-            error = "ElastiCache query to AWS failed (unexpected format)."
-            self.fail_with_error(error, 'getting ElastiCache clusters')
-
-        for cluster in clusters:
-            self.add_elasticache_cluster(cluster, region)
-
-    def get_elasticache_replication_groups_by_region(self, region):
-        ''' Makes an AWS API call to the list of ElastiCache replication groups
-        in a particular region.'''
-
-        # ElastiCache boto module doesn't provide a get_all_intances method,
-        # that's why we need to call describe directly (it would be called by
-        # the shorthand method anyway...)
-        try:
-            conn = self.connect_to_aws(elasticache, region)
-            if conn:
-                response = conn.describe_replication_groups()
-
-        except boto.exception.BotoServerError as e:
-            error = e.reason
-
-            if e.error_code == 'AuthFailure':
-                error = self.get_auth_error_message()
-            if not e.reason == "Forbidden":
-                error = "Looks like AWS ElastiCache [Replication Groups] is down:\n%s" % e.message
-            self.fail_with_error(error, 'getting ElastiCache clusters')
-
-        try:
-            # Boto also doesn't provide wrapper classes to ReplicationGroups
-            # Because of that wo can't make use of the get_list method in the
-            # AWSQueryConnection. Let's do the work manually
-            replication_groups = response['DescribeReplicationGroupsResponse']['DescribeReplicationGroupsResult']['ReplicationGroups']
-
-        except KeyError as e:
-            error = "ElastiCache [Replication Groups] query to AWS failed (unexpected format)."
-            self.fail_with_error(error, 'getting ElastiCache clusters')
-
-        for replication_group in replication_groups:
-            self.add_elasticache_replication_group(replication_group, region)
-
-    def get_auth_error_message(self):
-        ''' create an informative error message if there is an issue authenticating'''
-        errors = ["Authentication error retrieving ec2 inventory."]
-        if None in [os.environ.get('AWS_ACCESS_KEY_ID'), os.environ.get('AWS_SECRET_ACCESS_KEY')]:
-            errors.append(' - No AWS_ACCESS_KEY_ID or AWS_SECRET_ACCESS_KEY environment vars found')
-        else:
-            errors.append(' - AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY environment vars found but may not be correct')
-
-        boto_paths = ['/etc/boto.cfg', '~/.boto', '~/.aws/credentials']
-        boto_config_found = list(p for p in boto_paths if os.path.isfile(os.path.expanduser(p)))
-        if len(boto_config_found) > 0:
-            errors.append(" - Boto configs found at '%s', but the credentials contained may not be correct" % ', '.join(boto_config_found))
-        else:
-            errors.append(" - No Boto config found at any expected location '%s'" % ', '.join(boto_paths))
-
-        return '\n'.join(errors)
-
-    def fail_with_error(self, err_msg, err_operation=None):
-        '''log an error to std err for ansible-playbook to consume and exit'''
-        if err_operation:
-            err_msg = 'ERROR: "{err_msg}", while: {err_operation}'.format(
-                    err_msg=err_msg, err_operation=err_operation)
-        sys.stderr.write(err_msg)
-        sys.exit(1)
-
-    def get_instance(self, region, instance_id):
-        conn = self.connect(region)
-
-        reservations = conn.get_all_instances([instance_id])
-        for reservation in reservations:
-            for instance in reservation.instances:
-                return instance
-
-    def add_instance(self, instance, region):
-        ''' Adds an instance to the inventory and index, as long as it is
-        addressable '''
-
-        # Only return instances with desired instance states
-        if instance.state not in self.ec2_instance_states:
-            return
-
-        # Select the best destination address
-        if self.destination_format and self.destination_format_tags:
-            dest = self.destination_format.format(*[ getattr(instance, 'tags').get(tag, '') for tag in self.destination_format_tags ])
-        elif instance.subnet_id:
-            dest = getattr(instance, self.vpc_destination_variable, None)
-            if dest is None:
-                dest = getattr(instance, 'tags').get(self.vpc_destination_variable, None)
-        else:
-            dest = getattr(instance, self.destination_variable, None)
-            if dest is None:
-                dest = getattr(instance, 'tags').get(self.destination_variable, None)
-
-        if not dest:
-            # Skip instances we cannot address (e.g. private VPC subnet)
-            return
-
-        # Set the inventory name
-        hostname = None
-        if self.hostname_variable:
-            if self.hostname_variable.startswith('tag_'):
-                hostname = instance.tags.get(self.hostname_variable[4:], None)
-            else:
-                hostname = getattr(instance, self.hostname_variable)
-
-        # If we can't get a nice hostname, use the destination address
-        if not hostname:
-            hostname = dest
-        else:
-            hostname = self.to_safe(hostname).lower()
-
-        # if we only want to include hosts that match a pattern, skip those that don't
-        if self.pattern_include and not self.pattern_include.match(hostname):
-            return
-
-        # if we need to exclude hosts that match a pattern, skip those
-        if self.pattern_exclude and self.pattern_exclude.match(hostname):
-            return
-
-        # Add to index
-        self.index[hostname] = [region, instance.id]
-
-        # Inventory: Group by instance ID (always a group of 1)
-        if self.group_by_instance_id:
-            self.inventory[instance.id] = [hostname]
-            if self.nested_groups:
-                self.push_group(self.inventory, 'instances', instance.id)
-
-        # Inventory: Group by region
-        if self.group_by_region:
-            self.push(self.inventory, region, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'regions', region)
-
-        # Inventory: Group by availability zone
-        if self.group_by_availability_zone:
-            self.push(self.inventory, instance.placement, hostname)
-            if self.nested_groups:
-                if self.group_by_region:
-                    self.push_group(self.inventory, region, instance.placement)
-                self.push_group(self.inventory, 'zones', instance.placement)
-
-        # Inventory: Group by Amazon Machine Image (AMI) ID
-        if self.group_by_ami_id:
-            ami_id = self.to_safe(instance.image_id)
-            self.push(self.inventory, ami_id, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'images', ami_id)
-
-        # Inventory: Group by instance type
-        if self.group_by_instance_type:
-            type_name = self.to_safe('type_' + instance.instance_type)
-            self.push(self.inventory, type_name, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'types', type_name)
-
-        # Inventory: Group by key pair
-        if self.group_by_key_pair and instance.key_name:
-            key_name = self.to_safe('key_' + instance.key_name)
-            self.push(self.inventory, key_name, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'keys', key_name)
-
-        # Inventory: Group by VPC
-        if self.group_by_vpc_id and instance.vpc_id:
-            vpc_id_name = self.to_safe('vpc_id_' + instance.vpc_id)
-            self.push(self.inventory, vpc_id_name, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'vpcs', vpc_id_name)
-
-        # Inventory: Group by security group
-        if self.group_by_security_group:
-            try:
-                for group in instance.groups:
-                    key = self.to_safe("security_group_" + group.name)
-                    self.push(self.inventory, key, hostname)
-                    if self.nested_groups:
-                        self.push_group(self.inventory, 'security_groups', key)
-            except AttributeError:
-                self.fail_with_error('\n'.join(['Package boto seems a bit older.',
-                                                'Please upgrade boto >= 2.3.0.']))
-
-        # Inventory: Group by tag keys
-        if self.group_by_tag_keys:
-            for k, v in instance.tags.items():
-                if self.expand_csv_tags and v and ',' in v:
-                    values = map(lambda x: x.strip(), v.split(','))
-                else:
-                    values = [v]
-
-                for v in values:
-                    if v:
-                        key = self.to_safe("tag_" + k + "=" + v)
-                    else:
-                        key = self.to_safe("tag_" + k)
-                    self.push(self.inventory, key, hostname)
-                    if self.nested_groups:
-                        self.push_group(self.inventory, 'tags', self.to_safe("tag_" + k))
-                        if v:
-                            self.push_group(self.inventory, self.to_safe("tag_" + k), key)
-
-        # Inventory: Group by Route53 domain names if enabled
-        if self.route53_enabled and self.group_by_route53_names:
-            route53_names = self.get_instance_route53_names(instance)
-            for name in route53_names:
-                self.push(self.inventory, name, hostname)
-                if self.nested_groups:
-                    self.push_group(self.inventory, 'route53', name)
-
-        # Global Tag: instances without tags
-        if self.group_by_tag_none and len(instance.tags) == 0:
-            self.push(self.inventory, 'tag_none', hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'tags', 'tag_none')
-
-        # Global Tag: tag all EC2 instances
-        self.push(self.inventory, 'ec2', hostname)
-
-        self.inventory["_meta"]["hostvars"][hostname] = self.get_host_info_dict_from_instance(instance)
-        self.inventory["_meta"]["hostvars"][hostname]['ansible_ssh_host'] = dest
-
-
-    def add_rds_instance(self, instance, region):
-        ''' Adds an RDS instance to the inventory and index, as long as it is
-        addressable '''
-
-        # Only want available instances unless all_rds_instances is True
-        if not self.all_rds_instances and instance.status != 'available':
-            return
-
-        # Select the best destination address
-        dest = instance.endpoint[0]
-
-        if not dest:
-            # Skip instances we cannot address (e.g. private VPC subnet)
-            return
-
-        # Set the inventory name
-        hostname = None
-        if self.hostname_variable:
-            if self.hostname_variable.startswith('tag_'):
-                hostname = instance.tags.get(self.hostname_variable[4:], None)
-            else:
-                hostname = getattr(instance, self.hostname_variable)
-
-        # If we can't get a nice hostname, use the destination address
-        if not hostname:
-            hostname = dest
-
-        hostname = self.to_safe(hostname).lower()
-
-        # Add to index
-        self.index[hostname] = [region, instance.id]
-
-        # Inventory: Group by instance ID (always a group of 1)
-        if self.group_by_instance_id:
-            self.inventory[instance.id] = [hostname]
-            if self.nested_groups:
-                self.push_group(self.inventory, 'instances', instance.id)
-
-        # Inventory: Group by region
-        if self.group_by_region:
-            self.push(self.inventory, region, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'regions', region)
-
-        # Inventory: Group by availability zone
-        if self.group_by_availability_zone:
-            self.push(self.inventory, instance.availability_zone, hostname)
-            if self.nested_groups:
-                if self.group_by_region:
-                    self.push_group(self.inventory, region, instance.availability_zone)
-                self.push_group(self.inventory, 'zones', instance.availability_zone)
-
-        # Inventory: Group by instance type
-        if self.group_by_instance_type:
-            type_name = self.to_safe('type_' + instance.instance_class)
-            self.push(self.inventory, type_name, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'types', type_name)
-
-        # Inventory: Group by VPC
-        if self.group_by_vpc_id and instance.subnet_group and instance.subnet_group.vpc_id:
-            vpc_id_name = self.to_safe('vpc_id_' + instance.subnet_group.vpc_id)
-            self.push(self.inventory, vpc_id_name, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'vpcs', vpc_id_name)
-
-        # Inventory: Group by security group
-        if self.group_by_security_group:
-            try:
-                if instance.security_group:
-                    key = self.to_safe("security_group_" + instance.security_group.name)
-                    self.push(self.inventory, key, hostname)
-                    if self.nested_groups:
-                        self.push_group(self.inventory, 'security_groups', key)
-
-            except AttributeError:
-                self.fail_with_error('\n'.join(['Package boto seems a bit older.',
-                                                'Please upgrade boto >= 2.3.0.']))
-
-
-        # Inventory: Group by engine
-        if self.group_by_rds_engine:
-            self.push(self.inventory, self.to_safe("rds_" + instance.engine), hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'rds_engines', self.to_safe("rds_" + instance.engine))
-
-        # Inventory: Group by parameter group
-        if self.group_by_rds_parameter_group:
-            self.push(self.inventory, self.to_safe("rds_parameter_group_" + instance.parameter_group.name), hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'rds_parameter_groups', self.to_safe("rds_parameter_group_" + instance.parameter_group.name))
-
-        # Global Tag: all RDS instances
-        self.push(self.inventory, 'rds', hostname)
-
-        self.inventory["_meta"]["hostvars"][hostname] = self.get_host_info_dict_from_instance(instance)
-        self.inventory["_meta"]["hostvars"][hostname]['ansible_ssh_host'] = dest
-
-    def add_elasticache_cluster(self, cluster, region):
-        ''' Adds an ElastiCache cluster to the inventory and index, as long as
-        it's nodes are addressable '''
-
-        # Only want available clusters unless all_elasticache_clusters is True
-        if not self.all_elasticache_clusters and cluster['CacheClusterStatus'] != 'available':
-            return
-
-        # Select the best destination address
-        if 'ConfigurationEndpoint' in cluster and cluster['ConfigurationEndpoint']:
-            # Memcached cluster
-            dest = cluster['ConfigurationEndpoint']['Address']
-            is_redis = False
-        else:
-            # Redis sigle node cluster
-            # Because all Redis clusters are single nodes, we'll merge the
-            # info from the cluster with info about the node
-            dest = cluster['CacheNodes'][0]['Endpoint']['Address']
-            is_redis = True
-
-        if not dest:
-            # Skip clusters we cannot address (e.g. private VPC subnet)
-            return
-
-        # Add to index
-        self.index[dest] = [region, cluster['CacheClusterId']]
-
-        # Inventory: Group by instance ID (always a group of 1)
-        if self.group_by_instance_id:
-            self.inventory[cluster['CacheClusterId']] = [dest]
-            if self.nested_groups:
-                self.push_group(self.inventory, 'instances', cluster['CacheClusterId'])
-
-        # Inventory: Group by region
-        if self.group_by_region and not is_redis:
-            self.push(self.inventory, region, dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'regions', region)
-
-        # Inventory: Group by availability zone
-        if self.group_by_availability_zone and not is_redis:
-            self.push(self.inventory, cluster['PreferredAvailabilityZone'], dest)
-            if self.nested_groups:
-                if self.group_by_region:
-                    self.push_group(self.inventory, region, cluster['PreferredAvailabilityZone'])
-                self.push_group(self.inventory, 'zones', cluster['PreferredAvailabilityZone'])
-
-        # Inventory: Group by node type
-        if self.group_by_instance_type and not is_redis:
-            type_name = self.to_safe('type_' + cluster['CacheNodeType'])
-            self.push(self.inventory, type_name, dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'types', type_name)
-
-        # Inventory: Group by VPC (information not available in the current
-        # AWS API version for ElastiCache)
-
-        # Inventory: Group by security group
-        if self.group_by_security_group and not is_redis:
-
-            # Check for the existence of the 'SecurityGroups' key and also if
-            # this key has some value. When the cluster is not placed in a SG
-            # the query can return None here and cause an error.
-            if 'SecurityGroups' in cluster and cluster['SecurityGroups'] is not None:
-                for security_group in cluster['SecurityGroups']:
-                    key = self.to_safe("security_group_" + security_group['SecurityGroupId'])
-                    self.push(self.inventory, key, dest)
-                    if self.nested_groups:
-                        self.push_group(self.inventory, 'security_groups', key)
-
-        # Inventory: Group by engine
-        if self.group_by_elasticache_engine and not is_redis:
-            self.push(self.inventory, self.to_safe("elasticache_" + cluster['Engine']), dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'elasticache_engines', self.to_safe(cluster['Engine']))
-
-        # Inventory: Group by parameter group
-        if self.group_by_elasticache_parameter_group:
-            self.push(self.inventory, self.to_safe("elasticache_parameter_group_" + cluster['CacheParameterGroup']['CacheParameterGroupName']), dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'elasticache_parameter_groups', self.to_safe(cluster['CacheParameterGroup']['CacheParameterGroupName']))
-
-        # Inventory: Group by replication group
-        if self.group_by_elasticache_replication_group and 'ReplicationGroupId' in cluster and cluster['ReplicationGroupId']:
-            self.push(self.inventory, self.to_safe("elasticache_replication_group_" + cluster['ReplicationGroupId']), dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'elasticache_replication_groups', self.to_safe(cluster['ReplicationGroupId']))
-
-        # Global Tag: all ElastiCache clusters
-        self.push(self.inventory, 'elasticache_clusters', cluster['CacheClusterId'])
-
-        host_info = self.get_host_info_dict_from_describe_dict(cluster)
-
-        self.inventory["_meta"]["hostvars"][dest] = host_info
-
-        # Add the nodes
-        for node in cluster['CacheNodes']:
-            self.add_elasticache_node(node, cluster, region)
-
-    def add_elasticache_node(self, node, cluster, region):
-        ''' Adds an ElastiCache node to the inventory and index, as long as
-        it is addressable '''
-
-        # Only want available nodes unless all_elasticache_nodes is True
-        if not self.all_elasticache_nodes and node['CacheNodeStatus'] != 'available':
-            return
-
-        # Select the best destination address
-        dest = node['Endpoint']['Address']
-
-        if not dest:
-            # Skip nodes we cannot address (e.g. private VPC subnet)
-            return
-
-        node_id = self.to_safe(cluster['CacheClusterId'] + '_' + node['CacheNodeId'])
-
-        # Add to index
-        self.index[dest] = [region, node_id]
-
-        # Inventory: Group by node ID (always a group of 1)
-        if self.group_by_instance_id:
-            self.inventory[node_id] = [dest]
-            if self.nested_groups:
-                self.push_group(self.inventory, 'instances', node_id)
-
-        # Inventory: Group by region
-        if self.group_by_region:
-            self.push(self.inventory, region, dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'regions', region)
-
-        # Inventory: Group by availability zone
-        if self.group_by_availability_zone:
-            self.push(self.inventory, cluster['PreferredAvailabilityZone'], dest)
-            if self.nested_groups:
-                if self.group_by_region:
-                    self.push_group(self.inventory, region, cluster['PreferredAvailabilityZone'])
-                self.push_group(self.inventory, 'zones', cluster['PreferredAvailabilityZone'])
-
-        # Inventory: Group by node type
-        if self.group_by_instance_type:
-            type_name = self.to_safe('type_' + cluster['CacheNodeType'])
-            self.push(self.inventory, type_name, dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'types', type_name)
-
-        # Inventory: Group by VPC (information not available in the current
-        # AWS API version for ElastiCache)
-
-        # Inventory: Group by security group
-        if self.group_by_security_group:
-
-            # Check for the existence of the 'SecurityGroups' key and also if
-            # this key has some value. When the cluster is not placed in a SG
-            # the query can return None here and cause an error.
-            if 'SecurityGroups' in cluster and cluster['SecurityGroups'] is not None:
-                for security_group in cluster['SecurityGroups']:
-                    key = self.to_safe("security_group_" + security_group['SecurityGroupId'])
-                    self.push(self.inventory, key, dest)
-                    if self.nested_groups:
-                        self.push_group(self.inventory, 'security_groups', key)
-
-        # Inventory: Group by engine
-        if self.group_by_elasticache_engine:
-            self.push(self.inventory, self.to_safe("elasticache_" + cluster['Engine']), dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'elasticache_engines', self.to_safe("elasticache_" + cluster['Engine']))
-
-        # Inventory: Group by parameter group (done at cluster level)
-
-        # Inventory: Group by replication group (done at cluster level)
-
-        # Inventory: Group by ElastiCache Cluster
-        if self.group_by_elasticache_cluster:
-            self.push(self.inventory, self.to_safe("elasticache_cluster_" + cluster['CacheClusterId']), dest)
-
-        # Global Tag: all ElastiCache nodes
-        self.push(self.inventory, 'elasticache_nodes', dest)
-
-        host_info = self.get_host_info_dict_from_describe_dict(node)
-
-        if dest in self.inventory["_meta"]["hostvars"]:
-            self.inventory["_meta"]["hostvars"][dest].update(host_info)
-        else:
-            self.inventory["_meta"]["hostvars"][dest] = host_info
-
-    def add_elasticache_replication_group(self, replication_group, region):
-        ''' Adds an ElastiCache replication group to the inventory and index '''
-
-        # Only want available clusters unless all_elasticache_replication_groups is True
-        if not self.all_elasticache_replication_groups and replication_group['Status'] != 'available':
-            return
-
-        # Select the best destination address (PrimaryEndpoint)
-        dest = replication_group['NodeGroups'][0]['PrimaryEndpoint']['Address']
-
-        if not dest:
-            # Skip clusters we cannot address (e.g. private VPC subnet)
-            return
-
-        # Add to index
-        self.index[dest] = [region, replication_group['ReplicationGroupId']]
-
-        # Inventory: Group by ID (always a group of 1)
-        if self.group_by_instance_id:
-            self.inventory[replication_group['ReplicationGroupId']] = [dest]
-            if self.nested_groups:
-                self.push_group(self.inventory, 'instances', replication_group['ReplicationGroupId'])
-
-        # Inventory: Group by region
-        if self.group_by_region:
-            self.push(self.inventory, region, dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'regions', region)
-
-        # Inventory: Group by availability zone (doesn't apply to replication groups)
-
-        # Inventory: Group by node type (doesn't apply to replication groups)
-
-        # Inventory: Group by VPC (information not available in the current
-        # AWS API version for replication groups
-
-        # Inventory: Group by security group (doesn't apply to replication groups)
-        # Check this value in cluster level
-
-        # Inventory: Group by engine (replication groups are always Redis)
-        if self.group_by_elasticache_engine:
-            self.push(self.inventory, 'elasticache_redis', dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'elasticache_engines', 'redis')
-
-        # Global Tag: all ElastiCache clusters
-        self.push(self.inventory, 'elasticache_replication_groups', replication_group['ReplicationGroupId'])
-
-        host_info = self.get_host_info_dict_from_describe_dict(replication_group)
-
-        self.inventory["_meta"]["hostvars"][dest] = host_info
-
-    def get_route53_records(self):
-        ''' Get and store the map of resource records to domain names that
-        point to them. '''
-
-        r53_conn = route53.Route53Connection()
-        all_zones = r53_conn.get_zones()
-
-        route53_zones = [ zone for zone in all_zones if zone.name[:-1]
-                          not in self.route53_excluded_zones ]
-
-        self.route53_records = {}
-
-        for zone in route53_zones:
-            rrsets = r53_conn.get_all_rrsets(zone.id)
-
-            for record_set in rrsets:
-                record_name = record_set.name
-
-                if record_name.endswith('.'):
-                    record_name = record_name[:-1]
-
-                for resource in record_set.resource_records:
-                    self.route53_records.setdefault(resource, set())
-                    self.route53_records[resource].add(record_name)
-
-
-    def get_instance_route53_names(self, instance):
-        ''' Check if an instance is referenced in the records we have from
-        Route53. If it is, return the list of domain names pointing to said
-        instance. If nothing points to it, return an empty list. '''
-
-        instance_attributes = [ 'public_dns_name', 'private_dns_name',
-                                'ip_address', 'private_ip_address' ]
-
-        name_list = set()
-
-        for attrib in instance_attributes:
-            try:
-                value = getattr(instance, attrib)
-            except AttributeError:
-                continue
-
-            if value in self.route53_records:
-                name_list.update(self.route53_records[value])
-
-        return list(name_list)
-
-    def get_host_info_dict_from_instance(self, instance):
-        instance_vars = {}
-        for key in vars(instance):
-            value = getattr(instance, key)
-            key = self.to_safe('ec2_' + key)
-
-            # Handle complex types
-            # state/previous_state changed to properties in boto in https://github.com/boto/boto/commit/a23c379837f698212252720d2af8dec0325c9518
-            if key == 'ec2__state':
-                instance_vars['ec2_state'] = instance.state or ''
-                instance_vars['ec2_state_code'] = instance.state_code
-            elif key == 'ec2__previous_state':
-                instance_vars['ec2_previous_state'] = instance.previous_state or ''
-                instance_vars['ec2_previous_state_code'] = instance.previous_state_code
-            elif type(value) in [int, bool]:
-                instance_vars[key] = value
-            elif isinstance(value, six.string_types):
-                instance_vars[key] = value.strip()
-            elif type(value) == type(None):
-                instance_vars[key] = ''
-            elif key == 'ec2_region':
-                instance_vars[key] = value.name
-            elif key == 'ec2__placement':
-                instance_vars['ec2_placement'] = value.zone
-            elif key == 'ec2_tags':
-                for k, v in value.items():
-                    if self.expand_csv_tags and ',' in v:
-                        v = map(lambda x: x.strip(), v.split(','))
-                    key = self.to_safe('ec2_tag_' + k)
-                    instance_vars[key] = v
-            elif key == 'ec2_groups':
-                group_ids = []
-                group_names = []
-                for group in value:
-                    group_ids.append(group.id)
-                    group_names.append(group.name)
-                instance_vars["ec2_security_group_ids"] = ','.join([str(i) for i in group_ids])
-                instance_vars["ec2_security_group_names"] = ','.join([str(i) for i in group_names])
-            else:
-                pass
-                # TODO Product codes if someone finds them useful
-                #print key
-                #print type(value)
-                #print value
-
-        return instance_vars
-
-    def get_host_info_dict_from_describe_dict(self, describe_dict):
-        ''' Parses the dictionary returned by the API call into a flat list
-            of parameters. This method should be used only when 'describe' is
-            used directly because Boto doesn't provide specific classes. '''
-
-        # I really don't agree with prefixing everything with 'ec2'
-        # because EC2, RDS and ElastiCache are different services.
-        # I'm just following the pattern used until now to not break any
-        # compatibility.
-
-        host_info = {}
-        for key in describe_dict:
-            value = describe_dict[key]
-            key = self.to_safe('ec2_' + self.uncammelize(key))
-
-            # Handle complex types
-
-            # Target: Memcached Cache Clusters
-            if key == 'ec2_configuration_endpoint' and value:
-                host_info['ec2_configuration_endpoint_address'] = value['Address']
-                host_info['ec2_configuration_endpoint_port'] = value['Port']
-
-            # Target: Cache Nodes and Redis Cache Clusters (single node)
-            if key == 'ec2_endpoint' and value:
-                host_info['ec2_endpoint_address'] = value['Address']
-                host_info['ec2_endpoint_port'] = value['Port']
-
-            # Target: Redis Replication Groups
-            if key == 'ec2_node_groups' and value:
-                host_info['ec2_endpoint_address'] = value[0]['PrimaryEndpoint']['Address']
-                host_info['ec2_endpoint_port'] = value[0]['PrimaryEndpoint']['Port']
-                replica_count = 0
-                for node in value[0]['NodeGroupMembers']:
-                    if node['CurrentRole'] == 'primary':
-                        host_info['ec2_primary_cluster_address'] = node['ReadEndpoint']['Address']
-                        host_info['ec2_primary_cluster_port'] = node['ReadEndpoint']['Port']
-                        host_info['ec2_primary_cluster_id'] = node['CacheClusterId']
-                    elif node['CurrentRole'] == 'replica':
-                        host_info['ec2_replica_cluster_address_'+ str(replica_count)] = node['ReadEndpoint']['Address']
-                        host_info['ec2_replica_cluster_port_'+ str(replica_count)] = node['ReadEndpoint']['Port']
-                        host_info['ec2_replica_cluster_id_'+ str(replica_count)] = node['CacheClusterId']
-                        replica_count += 1
-
-            # Target: Redis Replication Groups
-            if key == 'ec2_member_clusters' and value:
-                host_info['ec2_member_clusters'] = ','.join([str(i) for i in value])
-
-            # Target: All Cache Clusters
-            elif key == 'ec2_cache_parameter_group':
-                host_info["ec2_cache_node_ids_to_reboot"] = ','.join([str(i) for i in value['CacheNodeIdsToReboot']])
-                host_info['ec2_cache_parameter_group_name'] = value['CacheParameterGroupName']
-                host_info['ec2_cache_parameter_apply_status'] = value['ParameterApplyStatus']
-
-            # Target: Almost everything
-            elif key == 'ec2_security_groups':
-
-                # Skip if SecurityGroups is None
-                # (it is possible to have the key defined but no value in it).
-                if value is not None:
-                    sg_ids = []
-                    for sg in value:
-                        sg_ids.append(sg['SecurityGroupId'])
-                    host_info["ec2_security_group_ids"] = ','.join([str(i) for i in sg_ids])
-
-            # Target: Everything
-            # Preserve booleans and integers
-            elif type(value) in [int, bool]:
-                host_info[key] = value
-
-            # Target: Everything
-            # Sanitize string values
-            elif isinstance(value, six.string_types):
-                host_info[key] = value.strip()
-
-            # Target: Everything
-            # Replace None by an empty string
-            elif type(value) == type(None):
-                host_info[key] = ''
-
-            else:
-                # Remove non-processed complex types
-                pass
-
-        return host_info
-
-    def get_host_info(self):
-        ''' Get variables about a specific host '''
-
-        if len(self.index) == 0:
-            # Need to load index from cache
-            self.load_index_from_cache()
-
-        if not self.args.host in self.index:
-            # try updating the cache
-            self.do_api_calls_update_cache()
-            if not self.args.host in self.index:
-                # host might not exist anymore
-                return self.json_format_dict({}, True)
-
-        (region, instance_id) = self.index[self.args.host]
-
-        instance = self.get_instance(region, instance_id)
-        return self.json_format_dict(self.get_host_info_dict_from_instance(instance), True)
-
-    def push(self, my_dict, key, element):
-        ''' Push an element onto an array that may not have been defined in
-        the dict '''
-        group_info = my_dict.setdefault(key, [])
-        if isinstance(group_info, dict):
-            host_list = group_info.setdefault('hosts', [])
-            host_list.append(element)
-        else:
-            group_info.append(element)
-
-    def push_group(self, my_dict, key, element):
-        ''' Push a group as a child of another group. '''
-        parent_group = my_dict.setdefault(key, {})
-        if not isinstance(parent_group, dict):
-            parent_group = my_dict[key] = {'hosts': parent_group}
-        child_groups = parent_group.setdefault('children', [])
-        if element not in child_groups:
-            child_groups.append(element)
-
-    def get_inventory_from_cache(self):
-        ''' Reads the inventory from the cache file and returns it as a JSON
-        object '''
-
-        cache = open(self.cache_path_cache, 'r')
-        json_inventory = cache.read()
-        return json_inventory
-
-
-    def load_index_from_cache(self):
-        ''' Reads the index from the cache file sets self.index '''
-
-        cache = open(self.cache_path_index, 'r')
-        json_index = cache.read()
-        self.index = json.loads(json_index)
-
-
-    def write_to_cache(self, data, filename):
-        ''' Writes data in JSON format to a file '''
-
-        json_data = self.json_format_dict(data, True)
-        cache = open(filename, 'w')
-        cache.write(json_data)
-        cache.close()
-
-    def uncammelize(self, key):
-        temp = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', key)
-        return re.sub('([a-z0-9])([A-Z])', r'\1_\2', temp).lower()
-
-    def to_safe(self, word):
-        ''' Converts 'bad' characters in a string to underscores so they can be used as Ansible groups '''
-        regex = "[^A-Za-z0-9\_"
-        if not self.replace_dash_in_groups:
-            regex += "\-"
-        return re.sub(regex + "]", "_", word)
-
-    def json_format_dict(self, data, pretty=False):
-        ''' Converts a dict to a JSON object and dumps it as a formatted
-        string '''
-
-        if pretty:
-            return json.dumps(data, sort_keys=True, indent=2)
-        else:
-            return json.dumps(data)
-
-
-# Run the script
-Ec2Inventory()
diff --git a/edge-1701-dc1/inventory b/edge-1701-dc1/inventory
deleted file mode 100644
index 4c90b9e..0000000
--- a/edge-1701-dc1/inventory
+++ /dev/null
@@ -1,75 +0,0 @@
-[tag_Name_dc1_n1]
-[tag_Name_dc1_n2]
-[tag_Name_dc1_n3]
-[tag_Name_dc1_n4]
-[tag_Name_dc1_n5]
-
-[planet:children]
-dc-1
-
-[dc-1:children]
-tag_Name_dc1_n1
-tag_Name_dc1_n2
-tag_Name_dc1_n3
-tag_Name_dc1_n4
-tag_Name_dc1_n5
-
-[ds:children]
-dc-1-ds
-
-[dc-1-ds:children]
-tag_Name_dc1_n1
-tag_Name_dc1_n2
-tag_Name_dc1_n3
-
-[ms:children]
-dc-1-ms
-
-[dc-1-ms:children]
-tag_Name_dc1_n1
-
-[ui:children]
-dc-1-ui
-
-[dc-1-ui:children]
-tag_Name_dc1_n1
-
-[ldap:children]
-dc-1-ldap
-
-[dc-1-ldap:children]
-tag_Name_dc1_n1
-
-[rmp:children]
-dc-1-rmp
-
-[dc-1-rmp:children]
-tag_Name_dc1_n2
-tag_Name_dc1_n3
-
-[qpid:children]
-dc-1-qpid
-
-[dc-1-qpid:children]
-tag_Name_dc1_n4
-tag_Name_dc1_n5
-
-[pg:children]
-dc-1-pg
-
-[dc-1-pg:children]
-dc-1-pgmaster
-dc-1-pgstandby
-
-[pgmaster:children]
-dc-1-pgmaster
-
-[dc-1-pgmaster:children]
-tag_Name_dc1_n4
-
-[pgstandby:children]
-dc-1-pgstandby
-
-[dc-1-pgstandby:children]
-tag_Name_dc1_n5
-
diff --git a/edge-1701-dc2/ec2.ini b/edge-1701-dc2/ec2.ini
deleted file mode 100644
index 36b3921..0000000
--- a/edge-1701-dc2/ec2.ini
+++ /dev/null
@@ -1,200 +0,0 @@
-# Ansible EC2 external inventory script settings
-#
-
-[ec2]
-
-# to talk to a private eucalyptus instance uncomment these lines
-# and edit edit eucalyptus_host to be the host name of your cloud controller
-#eucalyptus = True
-#eucalyptus_host = clc.cloud.domain.org
-
-# AWS regions to make calls to. Set this to 'all' to make request to all regions
-# in AWS and merge the results together. Alternatively, set this to a comma
-# separated list of regions. E.g. 'us-east-1,us-west-1,us-west-2'
-regions = all
-regions_exclude = us-gov-west-1,cn-north-1
-
-# When generating inventory, Ansible needs to know how to address a server.
-# Each EC2 instance has a lot of variables associated with it. Here is the list:
-#   http://docs.pythonboto.org/en/latest/ref/ec2.html#module-boto.ec2.instance
-# Below are 2 variables that are used as the address of a server:
-#   - destination_variable
-#   - vpc_destination_variable
-
-# This is the normal destination variable to use. If you are running Ansible
-# from outside EC2, then 'public_dns_name' makes the most sense. If you are
-# running Ansible from within EC2, then perhaps you want to use the internal
-# address, and should set this to 'private_dns_name'. The key of an EC2 tag
-# may optionally be used; however the boto instance variables hold precedence
-# in the event of a collision.
-destination_variable = public_dns_name
-
-# This allows you to override the inventory_name with an ec2 variable, instead
-# of using the destination_variable above. Addressing (aka ansible_ssh_host)
-# will still use destination_variable. Tags should be written as 'tag_TAGNAME'.
-#hostname_variable = tag_Name
-
-# For server inside a VPC, using DNS names may not make sense. When an instance
-# has 'subnet_id' set, this variable is used. If the subnet is public, setting
-# this to 'ip_address' will return the public IP address. For instances in a
-# private subnet, this should be set to 'private_ip_address', and Ansible must
-# be run from within EC2. The key of an EC2 tag may optionally be used; however
-# the boto instance variables hold precedence in the event of a collision.
-# WARNING: - instances that are in the private vpc, _without_ public ip address
-# will not be listed in the inventory until You set:
-# vpc_destination_variable = private_ip_address
-vpc_destination_variable = ip_address
-
-# The following two settings allow flexible ansible host naming based on a
-# python format string and a comma-separated list of ec2 tags.  Note that:
-#
-# 1) If the tags referenced are not present for some instances, empty strings
-#    will be substituted in the format string.
-# 2) This overrides both destination_variable and vpc_destination_variable.
-#
-#destination_format = {0}.{1}.example.com
-#destination_format_tags = Name,environment
-
-# To tag instances on EC2 with the resource records that point to them from
-# Route53, uncomment and set 'route53' to True.
-route53 = False
-
-# To exclude RDS instances from the inventory, uncomment and set to False.
-rds = False
-
-# To exclude ElastiCache instances from the inventory, uncomment and set to False.
-elasticache = False
-
-# Additionally, you can specify the list of zones to exclude looking up in
-# 'route53_excluded_zones' as a comma-separated list.
-# route53_excluded_zones = samplezone1.com, samplezone2.com
-
-# By default, only EC2 instances in the 'running' state are returned. Set
-# 'all_instances' to True to return all instances regardless of state.
-all_instances = True
-
-# By default, only EC2 instances in the 'running' state are returned. Specify
-# EC2 instance states to return as a comma-separated list. This
-# option is overriden when 'all_instances' is True.
-# instance_states = pending, running, shutting-down, terminated, stopping, stopped
-
-# By default, only RDS instances in the 'available' state are returned.  Set
-# 'all_rds_instances' to True return all RDS instances regardless of state.
-all_rds_instances = False
-
-# By default, only ElastiCache clusters and nodes in the 'available' state
-# are returned. Set 'all_elasticache_clusters' and/or 'all_elastic_nodes'
-# to True return all ElastiCache clusters and nodes, regardless of state.
-#
-# Note that all_elasticache_nodes only applies to listed clusters. That means
-# if you set all_elastic_clusters to false, no node will be return from
-# unavailable clusters, regardless of the state and to what you set for
-# all_elasticache_nodes.
-all_elasticache_replication_groups = False
-all_elasticache_clusters = False
-all_elasticache_nodes = False
-
-# API calls to EC2 are slow. For this reason, we cache the results of an API
-# call. Set this to the path you want cache files to be written to. Two files
-# will be written to this directory:
-#   - ansible-ec2.cache
-#   - ansible-ec2.index
-cache_path = ~/.ansible/tmp
-
-# The number of seconds a cache file is considered valid. After this many
-# seconds, a new API call will be made, and the cache file will be updated.
-# To disable the cache, set this value to 0
-cache_max_age = 300
-
-# Organize groups into a nested/hierarchy instead of a flat namespace.
-nested_groups = False
-
-# Replace - tags when creating groups to avoid issues with ansible
-replace_dash_in_groups = True
-
-# If set to true, any tag of the form "a,b,c" is expanded into a list
-# and the results are used to create additional tag_* inventory groups.
-expand_csv_tags = False
-
-# The EC2 inventory output can become very large. To manage its size,
-# configure which groups should be created.
-group_by_instance_id = True
-group_by_region = True
-group_by_availability_zone = True
-group_by_ami_id = True
-group_by_instance_type = True
-group_by_key_pair = True
-group_by_vpc_id = True
-group_by_security_group = True
-group_by_tag_keys = True
-group_by_tag_none = True
-group_by_route53_names = True
-group_by_rds_engine = False
-group_by_rds_parameter_group = False
-group_by_elasticache_engine = True
-group_by_elasticache_cluster = True
-group_by_elasticache_parameter_group = True
-group_by_elasticache_replication_group = True
-
-# If you only want to include hosts that match a certain regular expression
-# pattern_include = staging-*
-
-# If you want to exclude any hosts that match a certain regular expression
-# pattern_exclude = staging-*
-# Ansible EC2 external inventory script settings
-#
-
-##[ec2]
-##
-### to talk to a private eucalyptus instance uncomment these lines
-### and edit edit eucalyptus_host to be the host name of your cloud controller
-###eucalyptus = True
-###eucalyptus_host = clc.cloud.domain.org
-##
-### AWS regions to make calls to. Set this to 'all' to make request to all regions
-##
-### in AWS and merge the results together. Alternatively, set this to a comma
-### separated list of regions. E.g. 'us-east-1,us-west-1,us-west-2'
-##regions = all
-##regions_exclude = us-gov-west-1,cn-north-1
-##
-### When generating inventory, Ansible needs to know how to address a server.
-### Each EC2 instance has a lot of variables associated with it. Here is the list:
-###   http://docs.pythonboto.org/en/latest/ref/ec2.html#module-boto.ec2.instance
-### Below are 2 variables that are used as the address of a server:
-###   - destination_variable
-###   - vpc_destination_variable
-##
-### This is the normal destination variable to use. If you are running Ansible
-### from outside EC2, then 'public_dns_name' makes the most sense. If you are
-### running Ansible from within EC2, then perhaps you want to use the internal
-### address, and should set this to 'private_dns_name'. The key of an EC2 tag
-##...skipping...
-### pattern_include = staging-*
-##
-### If you want to exclude any hosts that match a certain regular expression
-### pattern_exclude = staging-*
-
-# Instance filters can be used to control which instances are retrieved for
-# inventory. For the full list of possible filters, please read the EC2 API
-# docs: http://docs.aws.amazon.com/AWSEC2/latest/APIReference/ApiReference-query-DescribeInstances.html#query-DescribeInstances-filters
-# Filters are key/value pairs separated by '=', to list multiple filters use
-# a list separated by commas. See examples below.
-
-# Retrieve only instances with (key=value) env=staging tag
-# instance_filters = tag:env=staging
-
-# Retrieve only instances with role=webservers OR role=dbservers tag
-# instance_filters = tag:role=webservers,tag:role=dbservers
-
-# Retrieve only t1.micro instances OR instances with tag env=staging
-# instance_filters = instance-type=t1.micro,tag:env=staging
-
-# You can use wildcards in filter values also. Below will list instances which
-# tag Name value matches webservers1*
-# (ex. webservers15, webservers1a, webservers123 etc)
-# instance_filters = tag:Name=webservers1*
-
-# A boto configuration profile may be used to separate out credentials
-# see http://boto.readthedocs.org/en/latest/boto_config_tut.html
-# boto_profile = some-boto-profile-name
diff --git a/edge-1701-dc2/ec2.py b/edge-1701-dc2/ec2.py
deleted file mode 100755
index f30958a..0000000
--- a/edge-1701-dc2/ec2.py
+++ /dev/null
@@ -1,1385 +0,0 @@
-#!/usr/bin/env python
-
-'''
-EC2 external inventory script
-=================================
-
-Generates inventory that Ansible can understand by making API request to
-AWS EC2 using the Boto library.
-
-NOTE: This script assumes Ansible is being executed where the environment
-variables needed for Boto have already been set:
-    export AWS_ACCESS_KEY_ID='AK123'
-    export AWS_SECRET_ACCESS_KEY='abc123'
-
-This script also assumes there is an ec2.ini file alongside it.  To specify a
-different path to ec2.ini, define the EC2_INI_PATH environment variable:
-
-    export EC2_INI_PATH=/path/to/my_ec2.ini
-
-If you're using eucalyptus you need to set the above variables and
-you need to define:
-
-    export EC2_URL=http://hostname_of_your_cc:port/services/Eucalyptus
-
-If you're using boto profiles (requires boto>=2.24.0) you can choose a profile
-using the --boto-profile command line argument (e.g. ec2.py --boto-profile prod) or using
-the AWS_PROFILE variable:
-
-    AWS_PROFILE=prod ansible-playbook -i ec2.py myplaybook.yml
-
-For more details, see: http://docs.pythonboto.org/en/latest/boto_config_tut.html
-
-When run against a specific host, this script returns the following variables:
- - ec2_ami_launch_index
- - ec2_architecture
- - ec2_association
- - ec2_attachTime
- - ec2_attachment
- - ec2_attachmentId
- - ec2_client_token
- - ec2_deleteOnTermination
- - ec2_description
- - ec2_deviceIndex
- - ec2_dns_name
- - ec2_eventsSet
- - ec2_group_name
- - ec2_hypervisor
- - ec2_id
- - ec2_image_id
- - ec2_instanceState
- - ec2_instance_type
- - ec2_ipOwnerId
- - ec2_ip_address
- - ec2_item
- - ec2_kernel
- - ec2_key_name
- - ec2_launch_time
- - ec2_monitored
- - ec2_monitoring
- - ec2_networkInterfaceId
- - ec2_ownerId
- - ec2_persistent
- - ec2_placement
- - ec2_platform
- - ec2_previous_state
- - ec2_private_dns_name
- - ec2_private_ip_address
- - ec2_publicIp
- - ec2_public_dns_name
- - ec2_ramdisk
- - ec2_reason
- - ec2_region
- - ec2_requester_id
- - ec2_root_device_name
- - ec2_root_device_type
- - ec2_security_group_ids
- - ec2_security_group_names
- - ec2_shutdown_state
- - ec2_sourceDestCheck
- - ec2_spot_instance_request_id
- - ec2_state
- - ec2_state_code
- - ec2_state_reason
- - ec2_status
- - ec2_subnet_id
- - ec2_tenancy
- - ec2_virtualization_type
- - ec2_vpc_id
-
-These variables are pulled out of a boto.ec2.instance object. There is a lack of
-consistency with variable spellings (camelCase and underscores) since this
-just loops through all variables the object exposes. It is preferred to use the
-ones with underscores when multiple exist.
-
-In addition, if an instance has AWS Tags associated with it, each tag is a new
-variable named:
- - ec2_tag_[Key] = [Value]
-
-Security groups are comma-separated in 'ec2_security_group_ids' and
-'ec2_security_group_names'.
-'''
-
-# (c) 2012, Peter Sankauskas
-#
-# This file is part of Ansible,
-#
-# Ansible is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# Ansible is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with Ansible.  If not, see <http://www.gnu.org/licenses/>.
-
-######################################################################
-
-import sys
-import os
-import argparse
-import re
-from time import time
-import boto
-from boto import ec2
-from boto import rds
-from boto import elasticache
-from boto import route53
-import six
-
-from six.moves import configparser
-from collections import defaultdict
-
-try:
-    import json
-except ImportError:
-    import simplejson as json
-
-
-class Ec2Inventory(object):
-
-    def _empty_inventory(self):
-        return {"_meta" : {"hostvars" : {}}}
-
-    def __init__(self):
-        ''' Main execution path '''
-
-        # Inventory grouped by instance IDs, tags, security groups, regions,
-        # and availability zones
-        self.inventory = self._empty_inventory()
-
-        # Index of hostname (address) to instance ID
-        self.index = {}
-
-        # Boto profile to use (if any)
-        self.boto_profile = None
-
-        # Read settings and parse CLI arguments
-        self.parse_cli_args()
-        self.read_settings()
-
-        # Make sure that profile_name is not passed at all if not set
-        # as pre 2.24 boto will fall over otherwise
-        if self.boto_profile:
-            if not hasattr(boto.ec2.EC2Connection, 'profile_name'):
-                self.fail_with_error("boto version must be >= 2.24 to use profile")
-
-        # Cache
-        if self.args.refresh_cache:
-            self.do_api_calls_update_cache()
-        elif not self.is_cache_valid():
-            self.do_api_calls_update_cache()
-
-        # Data to print
-        if self.args.host:
-            data_to_print = self.get_host_info()
-
-        elif self.args.list:
-            # Display list of instances for inventory
-            if self.inventory == self._empty_inventory():
-                data_to_print = self.get_inventory_from_cache()
-            else:
-                data_to_print = self.json_format_dict(self.inventory, True)
-
-        print(data_to_print)
-
-
-    def is_cache_valid(self):
-        ''' Determines if the cache files have expired, or if it is still valid '''
-
-        if os.path.isfile(self.cache_path_cache):
-            mod_time = os.path.getmtime(self.cache_path_cache)
-            current_time = time()
-            if (mod_time + self.cache_max_age) > current_time:
-                if os.path.isfile(self.cache_path_index):
-                    return True
-
-        return False
-
-
-    def read_settings(self):
-        ''' Reads the settings from the ec2.ini file '''
-        if six.PY3:
-            config = configparser.ConfigParser()
-        else:
-            config = configparser.SafeConfigParser()
-        ec2_default_ini_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'ec2.ini')
-        ec2_ini_path = os.path.expanduser(os.path.expandvars(os.environ.get('EC2_INI_PATH', ec2_default_ini_path)))
-        config.read(ec2_ini_path)
-
-        # is eucalyptus?
-        self.eucalyptus_host = None
-        self.eucalyptus = False
-        if config.has_option('ec2', 'eucalyptus'):
-            self.eucalyptus = config.getboolean('ec2', 'eucalyptus')
-        if self.eucalyptus and config.has_option('ec2', 'eucalyptus_host'):
-            self.eucalyptus_host = config.get('ec2', 'eucalyptus_host')
-
-        # Regions
-        self.regions = []
-        configRegions = config.get('ec2', 'regions')
-        configRegions_exclude = config.get('ec2', 'regions_exclude')
-        if (configRegions == 'all'):
-            if self.eucalyptus_host:
-                self.regions.append(boto.connect_euca(host=self.eucalyptus_host).region.name)
-            else:
-                for regionInfo in ec2.regions():
-                    if regionInfo.name not in configRegions_exclude:
-                        self.regions.append(regionInfo.name)
-        else:
-            self.regions = configRegions.split(",")
-
-        # Destination addresses
-        self.destination_variable = config.get('ec2', 'destination_variable')
-        self.vpc_destination_variable = config.get('ec2', 'vpc_destination_variable')
-
-        if config.has_option('ec2', 'hostname_variable'):
-            self.hostname_variable = config.get('ec2', 'hostname_variable')
-        else:
-            self.hostname_variable = None
-
-        if config.has_option('ec2', 'destination_format') and \
-                config.has_option('ec2', 'destination_format_tags'):
-            self.destination_format = config.get('ec2', 'destination_format')
-            self.destination_format_tags = config.get('ec2', 'destination_format_tags').split(',')
-        else:
-            self.destination_format = None
-            self.destination_format_tags = None
-
-        # Route53
-        self.route53_enabled = config.getboolean('ec2', 'route53')
-        self.route53_excluded_zones = []
-        if config.has_option('ec2', 'route53_excluded_zones'):
-            self.route53_excluded_zones.extend(
-                    config.get('ec2', 'route53_excluded_zones', '').split(','))
-
-        # Include RDS instances?
-        self.rds_enabled = True
-        if config.has_option('ec2', 'rds'):
-            self.rds_enabled = config.getboolean('ec2', 'rds')
-
-        # Include ElastiCache instances?
-        self.elasticache_enabled = True
-        if config.has_option('ec2', 'elasticache'):
-            self.elasticache_enabled = config.getboolean('ec2', 'elasticache')
-
-        # Return all EC2 instances?
-        if config.has_option('ec2', 'all_instances'):
-            self.all_instances = config.getboolean('ec2', 'all_instances')
-        else:
-            self.all_instances = False
-
-        # Instance states to be gathered in inventory. Default is 'running'.
-        # Setting 'all_instances' to 'yes' overrides this option.
-        ec2_valid_instance_states = [
-            'pending',
-            'running',
-            'shutting-down',
-            'terminated',
-            'stopping',
-            'stopped'
-        ]
-        self.ec2_instance_states = []
-        if self.all_instances:
-            self.ec2_instance_states = ec2_valid_instance_states
-        elif config.has_option('ec2', 'instance_states'):
-            for instance_state in config.get('ec2', 'instance_states').split(','):
-                instance_state = instance_state.strip()
-                if instance_state not in ec2_valid_instance_states:
-                    continue
-                self.ec2_instance_states.append(instance_state)
-        else:
-            self.ec2_instance_states = ['running']
-
-        # Return all RDS instances? (if RDS is enabled)
-        if config.has_option('ec2', 'all_rds_instances') and self.rds_enabled:
-            self.all_rds_instances = config.getboolean('ec2', 'all_rds_instances')
-        else:
-            self.all_rds_instances = False
-
-        # Return all ElastiCache replication groups? (if ElastiCache is enabled)
-        if config.has_option('ec2', 'all_elasticache_replication_groups') and self.elasticache_enabled:
-            self.all_elasticache_replication_groups = config.getboolean('ec2', 'all_elasticache_replication_groups')
-        else:
-            self.all_elasticache_replication_groups = False
-
-        # Return all ElastiCache clusters? (if ElastiCache is enabled)
-        if config.has_option('ec2', 'all_elasticache_clusters') and self.elasticache_enabled:
-            self.all_elasticache_clusters = config.getboolean('ec2', 'all_elasticache_clusters')
-        else:
-            self.all_elasticache_clusters = False
-
-        # Return all ElastiCache nodes? (if ElastiCache is enabled)
-        if config.has_option('ec2', 'all_elasticache_nodes') and self.elasticache_enabled:
-            self.all_elasticache_nodes = config.getboolean('ec2', 'all_elasticache_nodes')
-        else:
-            self.all_elasticache_nodes = False
-
-        # boto configuration profile (prefer CLI argument)
-        self.boto_profile = self.args.boto_profile
-        if config.has_option('ec2', 'boto_profile') and not self.boto_profile:
-            self.boto_profile = config.get('ec2', 'boto_profile')
-
-        # Cache related
-        cache_dir = os.path.expanduser(config.get('ec2', 'cache_path'))
-        if self.boto_profile:
-            cache_dir = os.path.join(cache_dir, 'profile_' + self.boto_profile)
-        if not os.path.exists(cache_dir):
-            os.makedirs(cache_dir)
-
-        cache_name = 'ansible-ec2'
-        aws_profile = lambda: (self.boto_profile or
-                               os.environ.get('AWS_PROFILE') or
-                               os.environ.get('AWS_ACCESS_KEY_ID'))
-        if aws_profile():
-            cache_name = '%s-%s' % (cache_name, aws_profile())
-        self.cache_path_cache = cache_dir + "/%s.cache" % cache_name
-        self.cache_path_index = cache_dir + "/%s.index" % cache_name
-        self.cache_max_age = config.getint('ec2', 'cache_max_age')
-
-        if config.has_option('ec2', 'expand_csv_tags'):
-            self.expand_csv_tags = config.getboolean('ec2', 'expand_csv_tags')
-        else:
-            self.expand_csv_tags = False
-
-        # Configure nested groups instead of flat namespace.
-        if config.has_option('ec2', 'nested_groups'):
-            self.nested_groups = config.getboolean('ec2', 'nested_groups')
-        else:
-            self.nested_groups = False
-
-        # Replace dash or not in group names
-        if config.has_option('ec2', 'replace_dash_in_groups'):
-            self.replace_dash_in_groups = config.getboolean('ec2', 'replace_dash_in_groups')
-        else:
-            self.replace_dash_in_groups = True
-
-        # Configure which groups should be created.
-        group_by_options = [
-            'group_by_instance_id',
-            'group_by_region',
-            'group_by_availability_zone',
-            'group_by_ami_id',
-            'group_by_instance_type',
-            'group_by_key_pair',
-            'group_by_vpc_id',
-            'group_by_security_group',
-            'group_by_tag_keys',
-            'group_by_tag_none',
-            'group_by_route53_names',
-            'group_by_rds_engine',
-            'group_by_rds_parameter_group',
-            'group_by_elasticache_engine',
-            'group_by_elasticache_cluster',
-            'group_by_elasticache_parameter_group',
-            'group_by_elasticache_replication_group',
-        ]
-        for option in group_by_options:
-            if config.has_option('ec2', option):
-                setattr(self, option, config.getboolean('ec2', option))
-            else:
-                setattr(self, option, True)
-
-        # Do we need to just include hosts that match a pattern?
-        try:
-            pattern_include = config.get('ec2', 'pattern_include')
-            if pattern_include and len(pattern_include) > 0:
-                self.pattern_include = re.compile(pattern_include)
-            else:
-                self.pattern_include = None
-        except configparser.NoOptionError:
-            self.pattern_include = None
-
-        # Do we need to exclude hosts that match a pattern?
-        try:
-            pattern_exclude = config.get('ec2', 'pattern_exclude');
-            if pattern_exclude and len(pattern_exclude) > 0:
-                self.pattern_exclude = re.compile(pattern_exclude)
-            else:
-                self.pattern_exclude = None
-        except configparser.NoOptionError:
-            self.pattern_exclude = None
-
-        # Instance filters (see boto and EC2 API docs). Ignore invalid filters.
-        self.ec2_instance_filters = defaultdict(list)
-        if config.has_option('ec2', 'instance_filters'):
-
-            filters = [f for f in config.get('ec2', 'instance_filters').split(',') if f]
-
-            for instance_filter in filters:
-                instance_filter = instance_filter.strip()
-                if not instance_filter or '=' not in instance_filter:
-                    continue
-                filter_key, filter_value = [x.strip() for x in instance_filter.split('=', 1)]
-                if not filter_key:
-                    continue
-                self.ec2_instance_filters[filter_key].append(filter_value)
-
-    def parse_cli_args(self):
-        ''' Command line argument processing '''
-
-        parser = argparse.ArgumentParser(description='Produce an Ansible Inventory file based on EC2')
-        parser.add_argument('--list', action='store_true', default=True,
-                            help='List instances (default: True)')
-        parser.add_argument('--host', action='store',
-                            help='Get all the variables about a specific instance')
-        parser.add_argument('--refresh-cache', action='store_true', default=False,
-                            help='Force refresh of cache by making API requests to EC2 (default: False - use cache files)')
-        parser.add_argument('--profile', '--boto-profile', action='store', dest='boto_profile',
-                            help='Use boto profile for connections to EC2')
-        self.args = parser.parse_args()
-
-
-    def do_api_calls_update_cache(self):
-        ''' Do API calls to each region, and save data in cache files '''
-
-        if self.route53_enabled:
-            self.get_route53_records()
-
-        for region in self.regions:
-            self.get_instances_by_region(region)
-            if self.rds_enabled:
-                self.get_rds_instances_by_region(region)
-            if self.elasticache_enabled:
-                self.get_elasticache_clusters_by_region(region)
-                self.get_elasticache_replication_groups_by_region(region)
-
-        self.write_to_cache(self.inventory, self.cache_path_cache)
-        self.write_to_cache(self.index, self.cache_path_index)
-
-    def connect(self, region):
-        ''' create connection to api server'''
-        if self.eucalyptus:
-            conn = boto.connect_euca(host=self.eucalyptus_host)
-            conn.APIVersion = '2010-08-31'
-        else:
-            conn = self.connect_to_aws(ec2, region)
-        return conn
-
-    def boto_fix_security_token_in_profile(self, connect_args):
-        ''' monkey patch for boto issue boto/boto#2100 '''
-        profile = 'profile ' + self.boto_profile
-        if boto.config.has_option(profile, 'aws_security_token'):
-            connect_args['security_token'] = boto.config.get(profile, 'aws_security_token')
-        return connect_args
-
-    def connect_to_aws(self, module, region):
-        connect_args = {}
-
-        # only pass the profile name if it's set (as it is not supported by older boto versions)
-        if self.boto_profile:
-            connect_args['profile_name'] = self.boto_profile
-            self.boto_fix_security_token_in_profile(connect_args)
-
-        conn = module.connect_to_region(region, **connect_args)
-        # connect_to_region will fail "silently" by returning None if the region name is wrong or not supported
-        if conn is None:
-            self.fail_with_error("region name: %s likely not supported, or AWS is down.  connection to region failed." % region)
-        return conn
-
-    def get_instances_by_region(self, region):
-        ''' Makes an AWS EC2 API call to the list of instances in a particular
-        region '''
-
-        try:
-            conn = self.connect(region)
-            reservations = []
-            if self.ec2_instance_filters:
-                for filter_key, filter_values in self.ec2_instance_filters.items():
-                    reservations.extend(conn.get_all_instances(filters = { filter_key : filter_values }))
-            else:
-                reservations = conn.get_all_instances()
-
-            for reservation in reservations:
-                for instance in reservation.instances:
-                    self.add_instance(instance, region)
-
-        except boto.exception.BotoServerError as e:
-            if e.error_code == 'AuthFailure':
-                error = self.get_auth_error_message()
-            else:
-                backend = 'Eucalyptus' if self.eucalyptus else 'AWS'
-                error = "Error connecting to %s backend.\n%s" % (backend, e.message)
-            self.fail_with_error(error, 'getting EC2 instances')
-
-    def get_rds_instances_by_region(self, region):
-        ''' Makes an AWS API call to the list of RDS instances in a particular
-        region '''
-
-        try:
-            conn = self.connect_to_aws(rds, region)
-            if conn:
-                marker = None
-                while True:
-                    instances = conn.get_all_dbinstances(marker=marker)
-                    marker = instances.marker
-                    for instance in instances:
-                        self.add_rds_instance(instance, region)
-                    if not marker:
-                        break
-        except boto.exception.BotoServerError as e:
-            error = e.reason
-
-            if e.error_code == 'AuthFailure':
-                error = self.get_auth_error_message()
-            if not e.reason == "Forbidden":
-                error = "Looks like AWS RDS is down:\n%s" % e.message
-            self.fail_with_error(error, 'getting RDS instances')
-
-    def get_elasticache_clusters_by_region(self, region):
-        ''' Makes an AWS API call to the list of ElastiCache clusters (with
-        nodes' info) in a particular region.'''
-
-        # ElastiCache boto module doesn't provide a get_all_intances method,
-        # that's why we need to call describe directly (it would be called by
-        # the shorthand method anyway...)
-        try:
-            conn = self.connect_to_aws(elasticache, region)
-            if conn:
-                # show_cache_node_info = True
-                # because we also want nodes' information
-                response = conn.describe_cache_clusters(None, None, None, True)
-
-        except boto.exception.BotoServerError as e:
-            error = e.reason
-
-            if e.error_code == 'AuthFailure':
-                error = self.get_auth_error_message()
-            if not e.reason == "Forbidden":
-                error = "Looks like AWS ElastiCache is down:\n%s" % e.message
-            self.fail_with_error(error, 'getting ElastiCache clusters')
-
-        try:
-            # Boto also doesn't provide wrapper classes to CacheClusters or
-            # CacheNodes. Because of that wo can't make use of the get_list
-            # method in the AWSQueryConnection. Let's do the work manually
-            clusters = response['DescribeCacheClustersResponse']['DescribeCacheClustersResult']['CacheClusters']
-
-        except KeyError as e:
-            error = "ElastiCache query to AWS failed (unexpected format)."
-            self.fail_with_error(error, 'getting ElastiCache clusters')
-
-        for cluster in clusters:
-            self.add_elasticache_cluster(cluster, region)
-
-    def get_elasticache_replication_groups_by_region(self, region):
-        ''' Makes an AWS API call to the list of ElastiCache replication groups
-        in a particular region.'''
-
-        # ElastiCache boto module doesn't provide a get_all_intances method,
-        # that's why we need to call describe directly (it would be called by
-        # the shorthand method anyway...)
-        try:
-            conn = self.connect_to_aws(elasticache, region)
-            if conn:
-                response = conn.describe_replication_groups()
-
-        except boto.exception.BotoServerError as e:
-            error = e.reason
-
-            if e.error_code == 'AuthFailure':
-                error = self.get_auth_error_message()
-            if not e.reason == "Forbidden":
-                error = "Looks like AWS ElastiCache [Replication Groups] is down:\n%s" % e.message
-            self.fail_with_error(error, 'getting ElastiCache clusters')
-
-        try:
-            # Boto also doesn't provide wrapper classes to ReplicationGroups
-            # Because of that wo can't make use of the get_list method in the
-            # AWSQueryConnection. Let's do the work manually
-            replication_groups = response['DescribeReplicationGroupsResponse']['DescribeReplicationGroupsResult']['ReplicationGroups']
-
-        except KeyError as e:
-            error = "ElastiCache [Replication Groups] query to AWS failed (unexpected format)."
-            self.fail_with_error(error, 'getting ElastiCache clusters')
-
-        for replication_group in replication_groups:
-            self.add_elasticache_replication_group(replication_group, region)
-
-    def get_auth_error_message(self):
-        ''' create an informative error message if there is an issue authenticating'''
-        errors = ["Authentication error retrieving ec2 inventory."]
-        if None in [os.environ.get('AWS_ACCESS_KEY_ID'), os.environ.get('AWS_SECRET_ACCESS_KEY')]:
-            errors.append(' - No AWS_ACCESS_KEY_ID or AWS_SECRET_ACCESS_KEY environment vars found')
-        else:
-            errors.append(' - AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY environment vars found but may not be correct')
-
-        boto_paths = ['/etc/boto.cfg', '~/.boto', '~/.aws/credentials']
-        boto_config_found = list(p for p in boto_paths if os.path.isfile(os.path.expanduser(p)))
-        if len(boto_config_found) > 0:
-            errors.append(" - Boto configs found at '%s', but the credentials contained may not be correct" % ', '.join(boto_config_found))
-        else:
-            errors.append(" - No Boto config found at any expected location '%s'" % ', '.join(boto_paths))
-
-        return '\n'.join(errors)
-
-    def fail_with_error(self, err_msg, err_operation=None):
-        '''log an error to std err for ansible-playbook to consume and exit'''
-        if err_operation:
-            err_msg = 'ERROR: "{err_msg}", while: {err_operation}'.format(
-                    err_msg=err_msg, err_operation=err_operation)
-        sys.stderr.write(err_msg)
-        sys.exit(1)
-
-    def get_instance(self, region, instance_id):
-        conn = self.connect(region)
-
-        reservations = conn.get_all_instances([instance_id])
-        for reservation in reservations:
-            for instance in reservation.instances:
-                return instance
-
-    def add_instance(self, instance, region):
-        ''' Adds an instance to the inventory and index, as long as it is
-        addressable '''
-
-        # Only return instances with desired instance states
-        if instance.state not in self.ec2_instance_states:
-            return
-
-        # Select the best destination address
-        if self.destination_format and self.destination_format_tags:
-            dest = self.destination_format.format(*[ getattr(instance, 'tags').get(tag, '') for tag in self.destination_format_tags ])
-        elif instance.subnet_id:
-            dest = getattr(instance, self.vpc_destination_variable, None)
-            if dest is None:
-                dest = getattr(instance, 'tags').get(self.vpc_destination_variable, None)
-        else:
-            dest = getattr(instance, self.destination_variable, None)
-            if dest is None:
-                dest = getattr(instance, 'tags').get(self.destination_variable, None)
-
-        if not dest:
-            # Skip instances we cannot address (e.g. private VPC subnet)
-            return
-
-        # Set the inventory name
-        hostname = None
-        if self.hostname_variable:
-            if self.hostname_variable.startswith('tag_'):
-                hostname = instance.tags.get(self.hostname_variable[4:], None)
-            else:
-                hostname = getattr(instance, self.hostname_variable)
-
-        # If we can't get a nice hostname, use the destination address
-        if not hostname:
-            hostname = dest
-        else:
-            hostname = self.to_safe(hostname).lower()
-
-        # if we only want to include hosts that match a pattern, skip those that don't
-        if self.pattern_include and not self.pattern_include.match(hostname):
-            return
-
-        # if we need to exclude hosts that match a pattern, skip those
-        if self.pattern_exclude and self.pattern_exclude.match(hostname):
-            return
-
-        # Add to index
-        self.index[hostname] = [region, instance.id]
-
-        # Inventory: Group by instance ID (always a group of 1)
-        if self.group_by_instance_id:
-            self.inventory[instance.id] = [hostname]
-            if self.nested_groups:
-                self.push_group(self.inventory, 'instances', instance.id)
-
-        # Inventory: Group by region
-        if self.group_by_region:
-            self.push(self.inventory, region, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'regions', region)
-
-        # Inventory: Group by availability zone
-        if self.group_by_availability_zone:
-            self.push(self.inventory, instance.placement, hostname)
-            if self.nested_groups:
-                if self.group_by_region:
-                    self.push_group(self.inventory, region, instance.placement)
-                self.push_group(self.inventory, 'zones', instance.placement)
-
-        # Inventory: Group by Amazon Machine Image (AMI) ID
-        if self.group_by_ami_id:
-            ami_id = self.to_safe(instance.image_id)
-            self.push(self.inventory, ami_id, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'images', ami_id)
-
-        # Inventory: Group by instance type
-        if self.group_by_instance_type:
-            type_name = self.to_safe('type_' + instance.instance_type)
-            self.push(self.inventory, type_name, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'types', type_name)
-
-        # Inventory: Group by key pair
-        if self.group_by_key_pair and instance.key_name:
-            key_name = self.to_safe('key_' + instance.key_name)
-            self.push(self.inventory, key_name, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'keys', key_name)
-
-        # Inventory: Group by VPC
-        if self.group_by_vpc_id and instance.vpc_id:
-            vpc_id_name = self.to_safe('vpc_id_' + instance.vpc_id)
-            self.push(self.inventory, vpc_id_name, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'vpcs', vpc_id_name)
-
-        # Inventory: Group by security group
-        if self.group_by_security_group:
-            try:
-                for group in instance.groups:
-                    key = self.to_safe("security_group_" + group.name)
-                    self.push(self.inventory, key, hostname)
-                    if self.nested_groups:
-                        self.push_group(self.inventory, 'security_groups', key)
-            except AttributeError:
-                self.fail_with_error('\n'.join(['Package boto seems a bit older.',
-                                                'Please upgrade boto >= 2.3.0.']))
-
-        # Inventory: Group by tag keys
-        if self.group_by_tag_keys:
-            for k, v in instance.tags.items():
-                if self.expand_csv_tags and v and ',' in v:
-                    values = map(lambda x: x.strip(), v.split(','))
-                else:
-                    values = [v]
-
-                for v in values:
-                    if v:
-                        key = self.to_safe("tag_" + k + "=" + v)
-                    else:
-                        key = self.to_safe("tag_" + k)
-                    self.push(self.inventory, key, hostname)
-                    if self.nested_groups:
-                        self.push_group(self.inventory, 'tags', self.to_safe("tag_" + k))
-                        if v:
-                            self.push_group(self.inventory, self.to_safe("tag_" + k), key)
-
-        # Inventory: Group by Route53 domain names if enabled
-        if self.route53_enabled and self.group_by_route53_names:
-            route53_names = self.get_instance_route53_names(instance)
-            for name in route53_names:
-                self.push(self.inventory, name, hostname)
-                if self.nested_groups:
-                    self.push_group(self.inventory, 'route53', name)
-
-        # Global Tag: instances without tags
-        if self.group_by_tag_none and len(instance.tags) == 0:
-            self.push(self.inventory, 'tag_none', hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'tags', 'tag_none')
-
-        # Global Tag: tag all EC2 instances
-        self.push(self.inventory, 'ec2', hostname)
-
-        self.inventory["_meta"]["hostvars"][hostname] = self.get_host_info_dict_from_instance(instance)
-        self.inventory["_meta"]["hostvars"][hostname]['ansible_ssh_host'] = dest
-
-
-    def add_rds_instance(self, instance, region):
-        ''' Adds an RDS instance to the inventory and index, as long as it is
-        addressable '''
-
-        # Only want available instances unless all_rds_instances is True
-        if not self.all_rds_instances and instance.status != 'available':
-            return
-
-        # Select the best destination address
-        dest = instance.endpoint[0]
-
-        if not dest:
-            # Skip instances we cannot address (e.g. private VPC subnet)
-            return
-
-        # Set the inventory name
-        hostname = None
-        if self.hostname_variable:
-            if self.hostname_variable.startswith('tag_'):
-                hostname = instance.tags.get(self.hostname_variable[4:], None)
-            else:
-                hostname = getattr(instance, self.hostname_variable)
-
-        # If we can't get a nice hostname, use the destination address
-        if not hostname:
-            hostname = dest
-
-        hostname = self.to_safe(hostname).lower()
-
-        # Add to index
-        self.index[hostname] = [region, instance.id]
-
-        # Inventory: Group by instance ID (always a group of 1)
-        if self.group_by_instance_id:
-            self.inventory[instance.id] = [hostname]
-            if self.nested_groups:
-                self.push_group(self.inventory, 'instances', instance.id)
-
-        # Inventory: Group by region
-        if self.group_by_region:
-            self.push(self.inventory, region, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'regions', region)
-
-        # Inventory: Group by availability zone
-        if self.group_by_availability_zone:
-            self.push(self.inventory, instance.availability_zone, hostname)
-            if self.nested_groups:
-                if self.group_by_region:
-                    self.push_group(self.inventory, region, instance.availability_zone)
-                self.push_group(self.inventory, 'zones', instance.availability_zone)
-
-        # Inventory: Group by instance type
-        if self.group_by_instance_type:
-            type_name = self.to_safe('type_' + instance.instance_class)
-            self.push(self.inventory, type_name, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'types', type_name)
-
-        # Inventory: Group by VPC
-        if self.group_by_vpc_id and instance.subnet_group and instance.subnet_group.vpc_id:
-            vpc_id_name = self.to_safe('vpc_id_' + instance.subnet_group.vpc_id)
-            self.push(self.inventory, vpc_id_name, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'vpcs', vpc_id_name)
-
-        # Inventory: Group by security group
-        if self.group_by_security_group:
-            try:
-                if instance.security_group:
-                    key = self.to_safe("security_group_" + instance.security_group.name)
-                    self.push(self.inventory, key, hostname)
-                    if self.nested_groups:
-                        self.push_group(self.inventory, 'security_groups', key)
-
-            except AttributeError:
-                self.fail_with_error('\n'.join(['Package boto seems a bit older.',
-                                                'Please upgrade boto >= 2.3.0.']))
-
-
-        # Inventory: Group by engine
-        if self.group_by_rds_engine:
-            self.push(self.inventory, self.to_safe("rds_" + instance.engine), hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'rds_engines', self.to_safe("rds_" + instance.engine))
-
-        # Inventory: Group by parameter group
-        if self.group_by_rds_parameter_group:
-            self.push(self.inventory, self.to_safe("rds_parameter_group_" + instance.parameter_group.name), hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'rds_parameter_groups', self.to_safe("rds_parameter_group_" + instance.parameter_group.name))
-
-        # Global Tag: all RDS instances
-        self.push(self.inventory, 'rds', hostname)
-
-        self.inventory["_meta"]["hostvars"][hostname] = self.get_host_info_dict_from_instance(instance)
-        self.inventory["_meta"]["hostvars"][hostname]['ansible_ssh_host'] = dest
-
-    def add_elasticache_cluster(self, cluster, region):
-        ''' Adds an ElastiCache cluster to the inventory and index, as long as
-        it's nodes are addressable '''
-
-        # Only want available clusters unless all_elasticache_clusters is True
-        if not self.all_elasticache_clusters and cluster['CacheClusterStatus'] != 'available':
-            return
-
-        # Select the best destination address
-        if 'ConfigurationEndpoint' in cluster and cluster['ConfigurationEndpoint']:
-            # Memcached cluster
-            dest = cluster['ConfigurationEndpoint']['Address']
-            is_redis = False
-        else:
-            # Redis sigle node cluster
-            # Because all Redis clusters are single nodes, we'll merge the
-            # info from the cluster with info about the node
-            dest = cluster['CacheNodes'][0]['Endpoint']['Address']
-            is_redis = True
-
-        if not dest:
-            # Skip clusters we cannot address (e.g. private VPC subnet)
-            return
-
-        # Add to index
-        self.index[dest] = [region, cluster['CacheClusterId']]
-
-        # Inventory: Group by instance ID (always a group of 1)
-        if self.group_by_instance_id:
-            self.inventory[cluster['CacheClusterId']] = [dest]
-            if self.nested_groups:
-                self.push_group(self.inventory, 'instances', cluster['CacheClusterId'])
-
-        # Inventory: Group by region
-        if self.group_by_region and not is_redis:
-            self.push(self.inventory, region, dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'regions', region)
-
-        # Inventory: Group by availability zone
-        if self.group_by_availability_zone and not is_redis:
-            self.push(self.inventory, cluster['PreferredAvailabilityZone'], dest)
-            if self.nested_groups:
-                if self.group_by_region:
-                    self.push_group(self.inventory, region, cluster['PreferredAvailabilityZone'])
-                self.push_group(self.inventory, 'zones', cluster['PreferredAvailabilityZone'])
-
-        # Inventory: Group by node type
-        if self.group_by_instance_type and not is_redis:
-            type_name = self.to_safe('type_' + cluster['CacheNodeType'])
-            self.push(self.inventory, type_name, dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'types', type_name)
-
-        # Inventory: Group by VPC (information not available in the current
-        # AWS API version for ElastiCache)
-
-        # Inventory: Group by security group
-        if self.group_by_security_group and not is_redis:
-
-            # Check for the existence of the 'SecurityGroups' key and also if
-            # this key has some value. When the cluster is not placed in a SG
-            # the query can return None here and cause an error.
-            if 'SecurityGroups' in cluster and cluster['SecurityGroups'] is not None:
-                for security_group in cluster['SecurityGroups']:
-                    key = self.to_safe("security_group_" + security_group['SecurityGroupId'])
-                    self.push(self.inventory, key, dest)
-                    if self.nested_groups:
-                        self.push_group(self.inventory, 'security_groups', key)
-
-        # Inventory: Group by engine
-        if self.group_by_elasticache_engine and not is_redis:
-            self.push(self.inventory, self.to_safe("elasticache_" + cluster['Engine']), dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'elasticache_engines', self.to_safe(cluster['Engine']))
-
-        # Inventory: Group by parameter group
-        if self.group_by_elasticache_parameter_group:
-            self.push(self.inventory, self.to_safe("elasticache_parameter_group_" + cluster['CacheParameterGroup']['CacheParameterGroupName']), dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'elasticache_parameter_groups', self.to_safe(cluster['CacheParameterGroup']['CacheParameterGroupName']))
-
-        # Inventory: Group by replication group
-        if self.group_by_elasticache_replication_group and 'ReplicationGroupId' in cluster and cluster['ReplicationGroupId']:
-            self.push(self.inventory, self.to_safe("elasticache_replication_group_" + cluster['ReplicationGroupId']), dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'elasticache_replication_groups', self.to_safe(cluster['ReplicationGroupId']))
-
-        # Global Tag: all ElastiCache clusters
-        self.push(self.inventory, 'elasticache_clusters', cluster['CacheClusterId'])
-
-        host_info = self.get_host_info_dict_from_describe_dict(cluster)
-
-        self.inventory["_meta"]["hostvars"][dest] = host_info
-
-        # Add the nodes
-        for node in cluster['CacheNodes']:
-            self.add_elasticache_node(node, cluster, region)
-
-    def add_elasticache_node(self, node, cluster, region):
-        ''' Adds an ElastiCache node to the inventory and index, as long as
-        it is addressable '''
-
-        # Only want available nodes unless all_elasticache_nodes is True
-        if not self.all_elasticache_nodes and node['CacheNodeStatus'] != 'available':
-            return
-
-        # Select the best destination address
-        dest = node['Endpoint']['Address']
-
-        if not dest:
-            # Skip nodes we cannot address (e.g. private VPC subnet)
-            return
-
-        node_id = self.to_safe(cluster['CacheClusterId'] + '_' + node['CacheNodeId'])
-
-        # Add to index
-        self.index[dest] = [region, node_id]
-
-        # Inventory: Group by node ID (always a group of 1)
-        if self.group_by_instance_id:
-            self.inventory[node_id] = [dest]
-            if self.nested_groups:
-                self.push_group(self.inventory, 'instances', node_id)
-
-        # Inventory: Group by region
-        if self.group_by_region:
-            self.push(self.inventory, region, dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'regions', region)
-
-        # Inventory: Group by availability zone
-        if self.group_by_availability_zone:
-            self.push(self.inventory, cluster['PreferredAvailabilityZone'], dest)
-            if self.nested_groups:
-                if self.group_by_region:
-                    self.push_group(self.inventory, region, cluster['PreferredAvailabilityZone'])
-                self.push_group(self.inventory, 'zones', cluster['PreferredAvailabilityZone'])
-
-        # Inventory: Group by node type
-        if self.group_by_instance_type:
-            type_name = self.to_safe('type_' + cluster['CacheNodeType'])
-            self.push(self.inventory, type_name, dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'types', type_name)
-
-        # Inventory: Group by VPC (information not available in the current
-        # AWS API version for ElastiCache)
-
-        # Inventory: Group by security group
-        if self.group_by_security_group:
-
-            # Check for the existence of the 'SecurityGroups' key and also if
-            # this key has some value. When the cluster is not placed in a SG
-            # the query can return None here and cause an error.
-            if 'SecurityGroups' in cluster and cluster['SecurityGroups'] is not None:
-                for security_group in cluster['SecurityGroups']:
-                    key = self.to_safe("security_group_" + security_group['SecurityGroupId'])
-                    self.push(self.inventory, key, dest)
-                    if self.nested_groups:
-                        self.push_group(self.inventory, 'security_groups', key)
-
-        # Inventory: Group by engine
-        if self.group_by_elasticache_engine:
-            self.push(self.inventory, self.to_safe("elasticache_" + cluster['Engine']), dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'elasticache_engines', self.to_safe("elasticache_" + cluster['Engine']))
-
-        # Inventory: Group by parameter group (done at cluster level)
-
-        # Inventory: Group by replication group (done at cluster level)
-
-        # Inventory: Group by ElastiCache Cluster
-        if self.group_by_elasticache_cluster:
-            self.push(self.inventory, self.to_safe("elasticache_cluster_" + cluster['CacheClusterId']), dest)
-
-        # Global Tag: all ElastiCache nodes
-        self.push(self.inventory, 'elasticache_nodes', dest)
-
-        host_info = self.get_host_info_dict_from_describe_dict(node)
-
-        if dest in self.inventory["_meta"]["hostvars"]:
-            self.inventory["_meta"]["hostvars"][dest].update(host_info)
-        else:
-            self.inventory["_meta"]["hostvars"][dest] = host_info
-
-    def add_elasticache_replication_group(self, replication_group, region):
-        ''' Adds an ElastiCache replication group to the inventory and index '''
-
-        # Only want available clusters unless all_elasticache_replication_groups is True
-        if not self.all_elasticache_replication_groups and replication_group['Status'] != 'available':
-            return
-
-        # Select the best destination address (PrimaryEndpoint)
-        dest = replication_group['NodeGroups'][0]['PrimaryEndpoint']['Address']
-
-        if not dest:
-            # Skip clusters we cannot address (e.g. private VPC subnet)
-            return
-
-        # Add to index
-        self.index[dest] = [region, replication_group['ReplicationGroupId']]
-
-        # Inventory: Group by ID (always a group of 1)
-        if self.group_by_instance_id:
-            self.inventory[replication_group['ReplicationGroupId']] = [dest]
-            if self.nested_groups:
-                self.push_group(self.inventory, 'instances', replication_group['ReplicationGroupId'])
-
-        # Inventory: Group by region
-        if self.group_by_region:
-            self.push(self.inventory, region, dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'regions', region)
-
-        # Inventory: Group by availability zone (doesn't apply to replication groups)
-
-        # Inventory: Group by node type (doesn't apply to replication groups)
-
-        # Inventory: Group by VPC (information not available in the current
-        # AWS API version for replication groups
-
-        # Inventory: Group by security group (doesn't apply to replication groups)
-        # Check this value in cluster level
-
-        # Inventory: Group by engine (replication groups are always Redis)
-        if self.group_by_elasticache_engine:
-            self.push(self.inventory, 'elasticache_redis', dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'elasticache_engines', 'redis')
-
-        # Global Tag: all ElastiCache clusters
-        self.push(self.inventory, 'elasticache_replication_groups', replication_group['ReplicationGroupId'])
-
-        host_info = self.get_host_info_dict_from_describe_dict(replication_group)
-
-        self.inventory["_meta"]["hostvars"][dest] = host_info
-
-    def get_route53_records(self):
-        ''' Get and store the map of resource records to domain names that
-        point to them. '''
-
-        r53_conn = route53.Route53Connection()
-        all_zones = r53_conn.get_zones()
-
-        route53_zones = [ zone for zone in all_zones if zone.name[:-1]
-                          not in self.route53_excluded_zones ]
-
-        self.route53_records = {}
-
-        for zone in route53_zones:
-            rrsets = r53_conn.get_all_rrsets(zone.id)
-
-            for record_set in rrsets:
-                record_name = record_set.name
-
-                if record_name.endswith('.'):
-                    record_name = record_name[:-1]
-
-                for resource in record_set.resource_records:
-                    self.route53_records.setdefault(resource, set())
-                    self.route53_records[resource].add(record_name)
-
-
-    def get_instance_route53_names(self, instance):
-        ''' Check if an instance is referenced in the records we have from
-        Route53. If it is, return the list of domain names pointing to said
-        instance. If nothing points to it, return an empty list. '''
-
-        instance_attributes = [ 'public_dns_name', 'private_dns_name',
-                                'ip_address', 'private_ip_address' ]
-
-        name_list = set()
-
-        for attrib in instance_attributes:
-            try:
-                value = getattr(instance, attrib)
-            except AttributeError:
-                continue
-
-            if value in self.route53_records:
-                name_list.update(self.route53_records[value])
-
-        return list(name_list)
-
-    def get_host_info_dict_from_instance(self, instance):
-        instance_vars = {}
-        for key in vars(instance):
-            value = getattr(instance, key)
-            key = self.to_safe('ec2_' + key)
-
-            # Handle complex types
-            # state/previous_state changed to properties in boto in https://github.com/boto/boto/commit/a23c379837f698212252720d2af8dec0325c9518
-            if key == 'ec2__state':
-                instance_vars['ec2_state'] = instance.state or ''
-                instance_vars['ec2_state_code'] = instance.state_code
-            elif key == 'ec2__previous_state':
-                instance_vars['ec2_previous_state'] = instance.previous_state or ''
-                instance_vars['ec2_previous_state_code'] = instance.previous_state_code
-            elif type(value) in [int, bool]:
-                instance_vars[key] = value
-            elif isinstance(value, six.string_types):
-                instance_vars[key] = value.strip()
-            elif type(value) == type(None):
-                instance_vars[key] = ''
-            elif key == 'ec2_region':
-                instance_vars[key] = value.name
-            elif key == 'ec2__placement':
-                instance_vars['ec2_placement'] = value.zone
-            elif key == 'ec2_tags':
-                for k, v in value.items():
-                    if self.expand_csv_tags and ',' in v:
-                        v = map(lambda x: x.strip(), v.split(','))
-                    key = self.to_safe('ec2_tag_' + k)
-                    instance_vars[key] = v
-            elif key == 'ec2_groups':
-                group_ids = []
-                group_names = []
-                for group in value:
-                    group_ids.append(group.id)
-                    group_names.append(group.name)
-                instance_vars["ec2_security_group_ids"] = ','.join([str(i) for i in group_ids])
-                instance_vars["ec2_security_group_names"] = ','.join([str(i) for i in group_names])
-            else:
-                pass
-                # TODO Product codes if someone finds them useful
-                #print key
-                #print type(value)
-                #print value
-
-        return instance_vars
-
-    def get_host_info_dict_from_describe_dict(self, describe_dict):
-        ''' Parses the dictionary returned by the API call into a flat list
-            of parameters. This method should be used only when 'describe' is
-            used directly because Boto doesn't provide specific classes. '''
-
-        # I really don't agree with prefixing everything with 'ec2'
-        # because EC2, RDS and ElastiCache are different services.
-        # I'm just following the pattern used until now to not break any
-        # compatibility.
-
-        host_info = {}
-        for key in describe_dict:
-            value = describe_dict[key]
-            key = self.to_safe('ec2_' + self.uncammelize(key))
-
-            # Handle complex types
-
-            # Target: Memcached Cache Clusters
-            if key == 'ec2_configuration_endpoint' and value:
-                host_info['ec2_configuration_endpoint_address'] = value['Address']
-                host_info['ec2_configuration_endpoint_port'] = value['Port']
-
-            # Target: Cache Nodes and Redis Cache Clusters (single node)
-            if key == 'ec2_endpoint' and value:
-                host_info['ec2_endpoint_address'] = value['Address']
-                host_info['ec2_endpoint_port'] = value['Port']
-
-            # Target: Redis Replication Groups
-            if key == 'ec2_node_groups' and value:
-                host_info['ec2_endpoint_address'] = value[0]['PrimaryEndpoint']['Address']
-                host_info['ec2_endpoint_port'] = value[0]['PrimaryEndpoint']['Port']
-                replica_count = 0
-                for node in value[0]['NodeGroupMembers']:
-                    if node['CurrentRole'] == 'primary':
-                        host_info['ec2_primary_cluster_address'] = node['ReadEndpoint']['Address']
-                        host_info['ec2_primary_cluster_port'] = node['ReadEndpoint']['Port']
-                        host_info['ec2_primary_cluster_id'] = node['CacheClusterId']
-                    elif node['CurrentRole'] == 'replica':
-                        host_info['ec2_replica_cluster_address_'+ str(replica_count)] = node['ReadEndpoint']['Address']
-                        host_info['ec2_replica_cluster_port_'+ str(replica_count)] = node['ReadEndpoint']['Port']
-                        host_info['ec2_replica_cluster_id_'+ str(replica_count)] = node['CacheClusterId']
-                        replica_count += 1
-
-            # Target: Redis Replication Groups
-            if key == 'ec2_member_clusters' and value:
-                host_info['ec2_member_clusters'] = ','.join([str(i) for i in value])
-
-            # Target: All Cache Clusters
-            elif key == 'ec2_cache_parameter_group':
-                host_info["ec2_cache_node_ids_to_reboot"] = ','.join([str(i) for i in value['CacheNodeIdsToReboot']])
-                host_info['ec2_cache_parameter_group_name'] = value['CacheParameterGroupName']
-                host_info['ec2_cache_parameter_apply_status'] = value['ParameterApplyStatus']
-
-            # Target: Almost everything
-            elif key == 'ec2_security_groups':
-
-                # Skip if SecurityGroups is None
-                # (it is possible to have the key defined but no value in it).
-                if value is not None:
-                    sg_ids = []
-                    for sg in value:
-                        sg_ids.append(sg['SecurityGroupId'])
-                    host_info["ec2_security_group_ids"] = ','.join([str(i) for i in sg_ids])
-
-            # Target: Everything
-            # Preserve booleans and integers
-            elif type(value) in [int, bool]:
-                host_info[key] = value
-
-            # Target: Everything
-            # Sanitize string values
-            elif isinstance(value, six.string_types):
-                host_info[key] = value.strip()
-
-            # Target: Everything
-            # Replace None by an empty string
-            elif type(value) == type(None):
-                host_info[key] = ''
-
-            else:
-                # Remove non-processed complex types
-                pass
-
-        return host_info
-
-    def get_host_info(self):
-        ''' Get variables about a specific host '''
-
-        if len(self.index) == 0:
-            # Need to load index from cache
-            self.load_index_from_cache()
-
-        if not self.args.host in self.index:
-            # try updating the cache
-            self.do_api_calls_update_cache()
-            if not self.args.host in self.index:
-                # host might not exist anymore
-                return self.json_format_dict({}, True)
-
-        (region, instance_id) = self.index[self.args.host]
-
-        instance = self.get_instance(region, instance_id)
-        return self.json_format_dict(self.get_host_info_dict_from_instance(instance), True)
-
-    def push(self, my_dict, key, element):
-        ''' Push an element onto an array that may not have been defined in
-        the dict '''
-        group_info = my_dict.setdefault(key, [])
-        if isinstance(group_info, dict):
-            host_list = group_info.setdefault('hosts', [])
-            host_list.append(element)
-        else:
-            group_info.append(element)
-
-    def push_group(self, my_dict, key, element):
-        ''' Push a group as a child of another group. '''
-        parent_group = my_dict.setdefault(key, {})
-        if not isinstance(parent_group, dict):
-            parent_group = my_dict[key] = {'hosts': parent_group}
-        child_groups = parent_group.setdefault('children', [])
-        if element not in child_groups:
-            child_groups.append(element)
-
-    def get_inventory_from_cache(self):
-        ''' Reads the inventory from the cache file and returns it as a JSON
-        object '''
-
-        cache = open(self.cache_path_cache, 'r')
-        json_inventory = cache.read()
-        return json_inventory
-
-
-    def load_index_from_cache(self):
-        ''' Reads the index from the cache file sets self.index '''
-
-        cache = open(self.cache_path_index, 'r')
-        json_index = cache.read()
-        self.index = json.loads(json_index)
-
-
-    def write_to_cache(self, data, filename):
-        ''' Writes data in JSON format to a file '''
-
-        json_data = self.json_format_dict(data, True)
-        cache = open(filename, 'w')
-        cache.write(json_data)
-        cache.close()
-
-    def uncammelize(self, key):
-        temp = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', key)
-        return re.sub('([a-z0-9])([A-Z])', r'\1_\2', temp).lower()
-
-    def to_safe(self, word):
-        ''' Converts 'bad' characters in a string to underscores so they can be used as Ansible groups '''
-        regex = "[^A-Za-z0-9\_"
-        if not self.replace_dash_in_groups:
-            regex += "\-"
-        return re.sub(regex + "]", "_", word)
-
-    def json_format_dict(self, data, pretty=False):
-        ''' Converts a dict to a JSON object and dumps it as a formatted
-        string '''
-
-        if pretty:
-            return json.dumps(data, sort_keys=True, indent=2)
-        else:
-            return json.dumps(data)
-
-
-# Run the script
-Ec2Inventory()
diff --git a/edge-1701-dc2/inventory b/edge-1701-dc2/inventory
deleted file mode 100644
index 436da8b..0000000
--- a/edge-1701-dc2/inventory
+++ /dev/null
@@ -1,75 +0,0 @@
-[tag_Name_dc2_n1]
-[tag_Name_dc2_n2]
-[tag_Name_dc2_n3]
-[tag_Name_dc2_n4]
-[tag_Name_dc2_n5]
-
-[planet:children]
-dc-1
-
-[dc-1:children]
-tag_Name_dc2_n1
-tag_Name_dc2_n2
-tag_Name_dc2_n3
-tag_Name_dc2_n4
-tag_Name_dc2_n5
-
-[ds:children]
-dc-1-ds
-
-[dc-1-ds:children]
-tag_Name_dc2_n1
-tag_Name_dc2_n2
-tag_Name_dc2_n3
-
-[ms:children]
-dc-1-ms
-
-[dc-1-ms:children]
-tag_Name_dc2_n1
-
-[ui:children]
-dc-1-ui
-
-[dc-1-ui:children]
-tag_Name_dc2_n1
-
-[ldap:children]
-dc-1-ldap
-
-[dc-1-ldap:children]
-tag_Name_dc2_n1
-
-[rmp:children]
-dc-1-rmp
-
-[dc-1-rmp:children]
-tag_Name_dc2_n2
-tag_Name_dc2_n3
-
-[qpid:children]
-dc-1-qpid
-
-[dc-1-qpid:children]
-tag_Name_dc2_n4
-tag_Name_dc2_n5
-
-[pg:children]
-dc-1-pg
-
-[dc-1-pg:children]
-dc-1-pgmaster
-dc-1-pgstandby
-
-[pgmaster:children]
-dc-1-pgmaster
-
-[dc-1-pgmaster:children]
-tag_Name_dc2_n4
-
-[pgstandby:children]
-dc-1-pgstandby
-
-[dc-1-pgstandby:children]
-tag_Name_dc2_n5
-
diff --git a/edge-1701-dc5/ec2.ini b/edge-1701-dc5/ec2.ini
deleted file mode 100644
index 36b3921..0000000
--- a/edge-1701-dc5/ec2.ini
+++ /dev/null
@@ -1,200 +0,0 @@
-# Ansible EC2 external inventory script settings
-#
-
-[ec2]
-
-# to talk to a private eucalyptus instance uncomment these lines
-# and edit edit eucalyptus_host to be the host name of your cloud controller
-#eucalyptus = True
-#eucalyptus_host = clc.cloud.domain.org
-
-# AWS regions to make calls to. Set this to 'all' to make request to all regions
-# in AWS and merge the results together. Alternatively, set this to a comma
-# separated list of regions. E.g. 'us-east-1,us-west-1,us-west-2'
-regions = all
-regions_exclude = us-gov-west-1,cn-north-1
-
-# When generating inventory, Ansible needs to know how to address a server.
-# Each EC2 instance has a lot of variables associated with it. Here is the list:
-#   http://docs.pythonboto.org/en/latest/ref/ec2.html#module-boto.ec2.instance
-# Below are 2 variables that are used as the address of a server:
-#   - destination_variable
-#   - vpc_destination_variable
-
-# This is the normal destination variable to use. If you are running Ansible
-# from outside EC2, then 'public_dns_name' makes the most sense. If you are
-# running Ansible from within EC2, then perhaps you want to use the internal
-# address, and should set this to 'private_dns_name'. The key of an EC2 tag
-# may optionally be used; however the boto instance variables hold precedence
-# in the event of a collision.
-destination_variable = public_dns_name
-
-# This allows you to override the inventory_name with an ec2 variable, instead
-# of using the destination_variable above. Addressing (aka ansible_ssh_host)
-# will still use destination_variable. Tags should be written as 'tag_TAGNAME'.
-#hostname_variable = tag_Name
-
-# For server inside a VPC, using DNS names may not make sense. When an instance
-# has 'subnet_id' set, this variable is used. If the subnet is public, setting
-# this to 'ip_address' will return the public IP address. For instances in a
-# private subnet, this should be set to 'private_ip_address', and Ansible must
-# be run from within EC2. The key of an EC2 tag may optionally be used; however
-# the boto instance variables hold precedence in the event of a collision.
-# WARNING: - instances that are in the private vpc, _without_ public ip address
-# will not be listed in the inventory until You set:
-# vpc_destination_variable = private_ip_address
-vpc_destination_variable = ip_address
-
-# The following two settings allow flexible ansible host naming based on a
-# python format string and a comma-separated list of ec2 tags.  Note that:
-#
-# 1) If the tags referenced are not present for some instances, empty strings
-#    will be substituted in the format string.
-# 2) This overrides both destination_variable and vpc_destination_variable.
-#
-#destination_format = {0}.{1}.example.com
-#destination_format_tags = Name,environment
-
-# To tag instances on EC2 with the resource records that point to them from
-# Route53, uncomment and set 'route53' to True.
-route53 = False
-
-# To exclude RDS instances from the inventory, uncomment and set to False.
-rds = False
-
-# To exclude ElastiCache instances from the inventory, uncomment and set to False.
-elasticache = False
-
-# Additionally, you can specify the list of zones to exclude looking up in
-# 'route53_excluded_zones' as a comma-separated list.
-# route53_excluded_zones = samplezone1.com, samplezone2.com
-
-# By default, only EC2 instances in the 'running' state are returned. Set
-# 'all_instances' to True to return all instances regardless of state.
-all_instances = True
-
-# By default, only EC2 instances in the 'running' state are returned. Specify
-# EC2 instance states to return as a comma-separated list. This
-# option is overriden when 'all_instances' is True.
-# instance_states = pending, running, shutting-down, terminated, stopping, stopped
-
-# By default, only RDS instances in the 'available' state are returned.  Set
-# 'all_rds_instances' to True return all RDS instances regardless of state.
-all_rds_instances = False
-
-# By default, only ElastiCache clusters and nodes in the 'available' state
-# are returned. Set 'all_elasticache_clusters' and/or 'all_elastic_nodes'
-# to True return all ElastiCache clusters and nodes, regardless of state.
-#
-# Note that all_elasticache_nodes only applies to listed clusters. That means
-# if you set all_elastic_clusters to false, no node will be return from
-# unavailable clusters, regardless of the state and to what you set for
-# all_elasticache_nodes.
-all_elasticache_replication_groups = False
-all_elasticache_clusters = False
-all_elasticache_nodes = False
-
-# API calls to EC2 are slow. For this reason, we cache the results of an API
-# call. Set this to the path you want cache files to be written to. Two files
-# will be written to this directory:
-#   - ansible-ec2.cache
-#   - ansible-ec2.index
-cache_path = ~/.ansible/tmp
-
-# The number of seconds a cache file is considered valid. After this many
-# seconds, a new API call will be made, and the cache file will be updated.
-# To disable the cache, set this value to 0
-cache_max_age = 300
-
-# Organize groups into a nested/hierarchy instead of a flat namespace.
-nested_groups = False
-
-# Replace - tags when creating groups to avoid issues with ansible
-replace_dash_in_groups = True
-
-# If set to true, any tag of the form "a,b,c" is expanded into a list
-# and the results are used to create additional tag_* inventory groups.
-expand_csv_tags = False
-
-# The EC2 inventory output can become very large. To manage its size,
-# configure which groups should be created.
-group_by_instance_id = True
-group_by_region = True
-group_by_availability_zone = True
-group_by_ami_id = True
-group_by_instance_type = True
-group_by_key_pair = True
-group_by_vpc_id = True
-group_by_security_group = True
-group_by_tag_keys = True
-group_by_tag_none = True
-group_by_route53_names = True
-group_by_rds_engine = False
-group_by_rds_parameter_group = False
-group_by_elasticache_engine = True
-group_by_elasticache_cluster = True
-group_by_elasticache_parameter_group = True
-group_by_elasticache_replication_group = True
-
-# If you only want to include hosts that match a certain regular expression
-# pattern_include = staging-*
-
-# If you want to exclude any hosts that match a certain regular expression
-# pattern_exclude = staging-*
-# Ansible EC2 external inventory script settings
-#
-
-##[ec2]
-##
-### to talk to a private eucalyptus instance uncomment these lines
-### and edit edit eucalyptus_host to be the host name of your cloud controller
-###eucalyptus = True
-###eucalyptus_host = clc.cloud.domain.org
-##
-### AWS regions to make calls to. Set this to 'all' to make request to all regions
-##
-### in AWS and merge the results together. Alternatively, set this to a comma
-### separated list of regions. E.g. 'us-east-1,us-west-1,us-west-2'
-##regions = all
-##regions_exclude = us-gov-west-1,cn-north-1
-##
-### When generating inventory, Ansible needs to know how to address a server.
-### Each EC2 instance has a lot of variables associated with it. Here is the list:
-###   http://docs.pythonboto.org/en/latest/ref/ec2.html#module-boto.ec2.instance
-### Below are 2 variables that are used as the address of a server:
-###   - destination_variable
-###   - vpc_destination_variable
-##
-### This is the normal destination variable to use. If you are running Ansible
-### from outside EC2, then 'public_dns_name' makes the most sense. If you are
-### running Ansible from within EC2, then perhaps you want to use the internal
-### address, and should set this to 'private_dns_name'. The key of an EC2 tag
-##...skipping...
-### pattern_include = staging-*
-##
-### If you want to exclude any hosts that match a certain regular expression
-### pattern_exclude = staging-*
-
-# Instance filters can be used to control which instances are retrieved for
-# inventory. For the full list of possible filters, please read the EC2 API
-# docs: http://docs.aws.amazon.com/AWSEC2/latest/APIReference/ApiReference-query-DescribeInstances.html#query-DescribeInstances-filters
-# Filters are key/value pairs separated by '=', to list multiple filters use
-# a list separated by commas. See examples below.
-
-# Retrieve only instances with (key=value) env=staging tag
-# instance_filters = tag:env=staging
-
-# Retrieve only instances with role=webservers OR role=dbservers tag
-# instance_filters = tag:role=webservers,tag:role=dbservers
-
-# Retrieve only t1.micro instances OR instances with tag env=staging
-# instance_filters = instance-type=t1.micro,tag:env=staging
-
-# You can use wildcards in filter values also. Below will list instances which
-# tag Name value matches webservers1*
-# (ex. webservers15, webservers1a, webservers123 etc)
-# instance_filters = tag:Name=webservers1*
-
-# A boto configuration profile may be used to separate out credentials
-# see http://boto.readthedocs.org/en/latest/boto_config_tut.html
-# boto_profile = some-boto-profile-name
diff --git a/edge-1701-dc5/ec2.py b/edge-1701-dc5/ec2.py
deleted file mode 100755
index f30958a..0000000
--- a/edge-1701-dc5/ec2.py
+++ /dev/null
@@ -1,1385 +0,0 @@
-#!/usr/bin/env python
-
-'''
-EC2 external inventory script
-=================================
-
-Generates inventory that Ansible can understand by making API request to
-AWS EC2 using the Boto library.
-
-NOTE: This script assumes Ansible is being executed where the environment
-variables needed for Boto have already been set:
-    export AWS_ACCESS_KEY_ID='AK123'
-    export AWS_SECRET_ACCESS_KEY='abc123'
-
-This script also assumes there is an ec2.ini file alongside it.  To specify a
-different path to ec2.ini, define the EC2_INI_PATH environment variable:
-
-    export EC2_INI_PATH=/path/to/my_ec2.ini
-
-If you're using eucalyptus you need to set the above variables and
-you need to define:
-
-    export EC2_URL=http://hostname_of_your_cc:port/services/Eucalyptus
-
-If you're using boto profiles (requires boto>=2.24.0) you can choose a profile
-using the --boto-profile command line argument (e.g. ec2.py --boto-profile prod) or using
-the AWS_PROFILE variable:
-
-    AWS_PROFILE=prod ansible-playbook -i ec2.py myplaybook.yml
-
-For more details, see: http://docs.pythonboto.org/en/latest/boto_config_tut.html
-
-When run against a specific host, this script returns the following variables:
- - ec2_ami_launch_index
- - ec2_architecture
- - ec2_association
- - ec2_attachTime
- - ec2_attachment
- - ec2_attachmentId
- - ec2_client_token
- - ec2_deleteOnTermination
- - ec2_description
- - ec2_deviceIndex
- - ec2_dns_name
- - ec2_eventsSet
- - ec2_group_name
- - ec2_hypervisor
- - ec2_id
- - ec2_image_id
- - ec2_instanceState
- - ec2_instance_type
- - ec2_ipOwnerId
- - ec2_ip_address
- - ec2_item
- - ec2_kernel
- - ec2_key_name
- - ec2_launch_time
- - ec2_monitored
- - ec2_monitoring
- - ec2_networkInterfaceId
- - ec2_ownerId
- - ec2_persistent
- - ec2_placement
- - ec2_platform
- - ec2_previous_state
- - ec2_private_dns_name
- - ec2_private_ip_address
- - ec2_publicIp
- - ec2_public_dns_name
- - ec2_ramdisk
- - ec2_reason
- - ec2_region
- - ec2_requester_id
- - ec2_root_device_name
- - ec2_root_device_type
- - ec2_security_group_ids
- - ec2_security_group_names
- - ec2_shutdown_state
- - ec2_sourceDestCheck
- - ec2_spot_instance_request_id
- - ec2_state
- - ec2_state_code
- - ec2_state_reason
- - ec2_status
- - ec2_subnet_id
- - ec2_tenancy
- - ec2_virtualization_type
- - ec2_vpc_id
-
-These variables are pulled out of a boto.ec2.instance object. There is a lack of
-consistency with variable spellings (camelCase and underscores) since this
-just loops through all variables the object exposes. It is preferred to use the
-ones with underscores when multiple exist.
-
-In addition, if an instance has AWS Tags associated with it, each tag is a new
-variable named:
- - ec2_tag_[Key] = [Value]
-
-Security groups are comma-separated in 'ec2_security_group_ids' and
-'ec2_security_group_names'.
-'''
-
-# (c) 2012, Peter Sankauskas
-#
-# This file is part of Ansible,
-#
-# Ansible is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# Ansible is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with Ansible.  If not, see <http://www.gnu.org/licenses/>.
-
-######################################################################
-
-import sys
-import os
-import argparse
-import re
-from time import time
-import boto
-from boto import ec2
-from boto import rds
-from boto import elasticache
-from boto import route53
-import six
-
-from six.moves import configparser
-from collections import defaultdict
-
-try:
-    import json
-except ImportError:
-    import simplejson as json
-
-
-class Ec2Inventory(object):
-
-    def _empty_inventory(self):
-        return {"_meta" : {"hostvars" : {}}}
-
-    def __init__(self):
-        ''' Main execution path '''
-
-        # Inventory grouped by instance IDs, tags, security groups, regions,
-        # and availability zones
-        self.inventory = self._empty_inventory()
-
-        # Index of hostname (address) to instance ID
-        self.index = {}
-
-        # Boto profile to use (if any)
-        self.boto_profile = None
-
-        # Read settings and parse CLI arguments
-        self.parse_cli_args()
-        self.read_settings()
-
-        # Make sure that profile_name is not passed at all if not set
-        # as pre 2.24 boto will fall over otherwise
-        if self.boto_profile:
-            if not hasattr(boto.ec2.EC2Connection, 'profile_name'):
-                self.fail_with_error("boto version must be >= 2.24 to use profile")
-
-        # Cache
-        if self.args.refresh_cache:
-            self.do_api_calls_update_cache()
-        elif not self.is_cache_valid():
-            self.do_api_calls_update_cache()
-
-        # Data to print
-        if self.args.host:
-            data_to_print = self.get_host_info()
-
-        elif self.args.list:
-            # Display list of instances for inventory
-            if self.inventory == self._empty_inventory():
-                data_to_print = self.get_inventory_from_cache()
-            else:
-                data_to_print = self.json_format_dict(self.inventory, True)
-
-        print(data_to_print)
-
-
-    def is_cache_valid(self):
-        ''' Determines if the cache files have expired, or if it is still valid '''
-
-        if os.path.isfile(self.cache_path_cache):
-            mod_time = os.path.getmtime(self.cache_path_cache)
-            current_time = time()
-            if (mod_time + self.cache_max_age) > current_time:
-                if os.path.isfile(self.cache_path_index):
-                    return True
-
-        return False
-
-
-    def read_settings(self):
-        ''' Reads the settings from the ec2.ini file '''
-        if six.PY3:
-            config = configparser.ConfigParser()
-        else:
-            config = configparser.SafeConfigParser()
-        ec2_default_ini_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'ec2.ini')
-        ec2_ini_path = os.path.expanduser(os.path.expandvars(os.environ.get('EC2_INI_PATH', ec2_default_ini_path)))
-        config.read(ec2_ini_path)
-
-        # is eucalyptus?
-        self.eucalyptus_host = None
-        self.eucalyptus = False
-        if config.has_option('ec2', 'eucalyptus'):
-            self.eucalyptus = config.getboolean('ec2', 'eucalyptus')
-        if self.eucalyptus and config.has_option('ec2', 'eucalyptus_host'):
-            self.eucalyptus_host = config.get('ec2', 'eucalyptus_host')
-
-        # Regions
-        self.regions = []
-        configRegions = config.get('ec2', 'regions')
-        configRegions_exclude = config.get('ec2', 'regions_exclude')
-        if (configRegions == 'all'):
-            if self.eucalyptus_host:
-                self.regions.append(boto.connect_euca(host=self.eucalyptus_host).region.name)
-            else:
-                for regionInfo in ec2.regions():
-                    if regionInfo.name not in configRegions_exclude:
-                        self.regions.append(regionInfo.name)
-        else:
-            self.regions = configRegions.split(",")
-
-        # Destination addresses
-        self.destination_variable = config.get('ec2', 'destination_variable')
-        self.vpc_destination_variable = config.get('ec2', 'vpc_destination_variable')
-
-        if config.has_option('ec2', 'hostname_variable'):
-            self.hostname_variable = config.get('ec2', 'hostname_variable')
-        else:
-            self.hostname_variable = None
-
-        if config.has_option('ec2', 'destination_format') and \
-                config.has_option('ec2', 'destination_format_tags'):
-            self.destination_format = config.get('ec2', 'destination_format')
-            self.destination_format_tags = config.get('ec2', 'destination_format_tags').split(',')
-        else:
-            self.destination_format = None
-            self.destination_format_tags = None
-
-        # Route53
-        self.route53_enabled = config.getboolean('ec2', 'route53')
-        self.route53_excluded_zones = []
-        if config.has_option('ec2', 'route53_excluded_zones'):
-            self.route53_excluded_zones.extend(
-                    config.get('ec2', 'route53_excluded_zones', '').split(','))
-
-        # Include RDS instances?
-        self.rds_enabled = True
-        if config.has_option('ec2', 'rds'):
-            self.rds_enabled = config.getboolean('ec2', 'rds')
-
-        # Include ElastiCache instances?
-        self.elasticache_enabled = True
-        if config.has_option('ec2', 'elasticache'):
-            self.elasticache_enabled = config.getboolean('ec2', 'elasticache')
-
-        # Return all EC2 instances?
-        if config.has_option('ec2', 'all_instances'):
-            self.all_instances = config.getboolean('ec2', 'all_instances')
-        else:
-            self.all_instances = False
-
-        # Instance states to be gathered in inventory. Default is 'running'.
-        # Setting 'all_instances' to 'yes' overrides this option.
-        ec2_valid_instance_states = [
-            'pending',
-            'running',
-            'shutting-down',
-            'terminated',
-            'stopping',
-            'stopped'
-        ]
-        self.ec2_instance_states = []
-        if self.all_instances:
-            self.ec2_instance_states = ec2_valid_instance_states
-        elif config.has_option('ec2', 'instance_states'):
-            for instance_state in config.get('ec2', 'instance_states').split(','):
-                instance_state = instance_state.strip()
-                if instance_state not in ec2_valid_instance_states:
-                    continue
-                self.ec2_instance_states.append(instance_state)
-        else:
-            self.ec2_instance_states = ['running']
-
-        # Return all RDS instances? (if RDS is enabled)
-        if config.has_option('ec2', 'all_rds_instances') and self.rds_enabled:
-            self.all_rds_instances = config.getboolean('ec2', 'all_rds_instances')
-        else:
-            self.all_rds_instances = False
-
-        # Return all ElastiCache replication groups? (if ElastiCache is enabled)
-        if config.has_option('ec2', 'all_elasticache_replication_groups') and self.elasticache_enabled:
-            self.all_elasticache_replication_groups = config.getboolean('ec2', 'all_elasticache_replication_groups')
-        else:
-            self.all_elasticache_replication_groups = False
-
-        # Return all ElastiCache clusters? (if ElastiCache is enabled)
-        if config.has_option('ec2', 'all_elasticache_clusters') and self.elasticache_enabled:
-            self.all_elasticache_clusters = config.getboolean('ec2', 'all_elasticache_clusters')
-        else:
-            self.all_elasticache_clusters = False
-
-        # Return all ElastiCache nodes? (if ElastiCache is enabled)
-        if config.has_option('ec2', 'all_elasticache_nodes') and self.elasticache_enabled:
-            self.all_elasticache_nodes = config.getboolean('ec2', 'all_elasticache_nodes')
-        else:
-            self.all_elasticache_nodes = False
-
-        # boto configuration profile (prefer CLI argument)
-        self.boto_profile = self.args.boto_profile
-        if config.has_option('ec2', 'boto_profile') and not self.boto_profile:
-            self.boto_profile = config.get('ec2', 'boto_profile')
-
-        # Cache related
-        cache_dir = os.path.expanduser(config.get('ec2', 'cache_path'))
-        if self.boto_profile:
-            cache_dir = os.path.join(cache_dir, 'profile_' + self.boto_profile)
-        if not os.path.exists(cache_dir):
-            os.makedirs(cache_dir)
-
-        cache_name = 'ansible-ec2'
-        aws_profile = lambda: (self.boto_profile or
-                               os.environ.get('AWS_PROFILE') or
-                               os.environ.get('AWS_ACCESS_KEY_ID'))
-        if aws_profile():
-            cache_name = '%s-%s' % (cache_name, aws_profile())
-        self.cache_path_cache = cache_dir + "/%s.cache" % cache_name
-        self.cache_path_index = cache_dir + "/%s.index" % cache_name
-        self.cache_max_age = config.getint('ec2', 'cache_max_age')
-
-        if config.has_option('ec2', 'expand_csv_tags'):
-            self.expand_csv_tags = config.getboolean('ec2', 'expand_csv_tags')
-        else:
-            self.expand_csv_tags = False
-
-        # Configure nested groups instead of flat namespace.
-        if config.has_option('ec2', 'nested_groups'):
-            self.nested_groups = config.getboolean('ec2', 'nested_groups')
-        else:
-            self.nested_groups = False
-
-        # Replace dash or not in group names
-        if config.has_option('ec2', 'replace_dash_in_groups'):
-            self.replace_dash_in_groups = config.getboolean('ec2', 'replace_dash_in_groups')
-        else:
-            self.replace_dash_in_groups = True
-
-        # Configure which groups should be created.
-        group_by_options = [
-            'group_by_instance_id',
-            'group_by_region',
-            'group_by_availability_zone',
-            'group_by_ami_id',
-            'group_by_instance_type',
-            'group_by_key_pair',
-            'group_by_vpc_id',
-            'group_by_security_group',
-            'group_by_tag_keys',
-            'group_by_tag_none',
-            'group_by_route53_names',
-            'group_by_rds_engine',
-            'group_by_rds_parameter_group',
-            'group_by_elasticache_engine',
-            'group_by_elasticache_cluster',
-            'group_by_elasticache_parameter_group',
-            'group_by_elasticache_replication_group',
-        ]
-        for option in group_by_options:
-            if config.has_option('ec2', option):
-                setattr(self, option, config.getboolean('ec2', option))
-            else:
-                setattr(self, option, True)
-
-        # Do we need to just include hosts that match a pattern?
-        try:
-            pattern_include = config.get('ec2', 'pattern_include')
-            if pattern_include and len(pattern_include) > 0:
-                self.pattern_include = re.compile(pattern_include)
-            else:
-                self.pattern_include = None
-        except configparser.NoOptionError:
-            self.pattern_include = None
-
-        # Do we need to exclude hosts that match a pattern?
-        try:
-            pattern_exclude = config.get('ec2', 'pattern_exclude');
-            if pattern_exclude and len(pattern_exclude) > 0:
-                self.pattern_exclude = re.compile(pattern_exclude)
-            else:
-                self.pattern_exclude = None
-        except configparser.NoOptionError:
-            self.pattern_exclude = None
-
-        # Instance filters (see boto and EC2 API docs). Ignore invalid filters.
-        self.ec2_instance_filters = defaultdict(list)
-        if config.has_option('ec2', 'instance_filters'):
-
-            filters = [f for f in config.get('ec2', 'instance_filters').split(',') if f]
-
-            for instance_filter in filters:
-                instance_filter = instance_filter.strip()
-                if not instance_filter or '=' not in instance_filter:
-                    continue
-                filter_key, filter_value = [x.strip() for x in instance_filter.split('=', 1)]
-                if not filter_key:
-                    continue
-                self.ec2_instance_filters[filter_key].append(filter_value)
-
-    def parse_cli_args(self):
-        ''' Command line argument processing '''
-
-        parser = argparse.ArgumentParser(description='Produce an Ansible Inventory file based on EC2')
-        parser.add_argument('--list', action='store_true', default=True,
-                            help='List instances (default: True)')
-        parser.add_argument('--host', action='store',
-                            help='Get all the variables about a specific instance')
-        parser.add_argument('--refresh-cache', action='store_true', default=False,
-                            help='Force refresh of cache by making API requests to EC2 (default: False - use cache files)')
-        parser.add_argument('--profile', '--boto-profile', action='store', dest='boto_profile',
-                            help='Use boto profile for connections to EC2')
-        self.args = parser.parse_args()
-
-
-    def do_api_calls_update_cache(self):
-        ''' Do API calls to each region, and save data in cache files '''
-
-        if self.route53_enabled:
-            self.get_route53_records()
-
-        for region in self.regions:
-            self.get_instances_by_region(region)
-            if self.rds_enabled:
-                self.get_rds_instances_by_region(region)
-            if self.elasticache_enabled:
-                self.get_elasticache_clusters_by_region(region)
-                self.get_elasticache_replication_groups_by_region(region)
-
-        self.write_to_cache(self.inventory, self.cache_path_cache)
-        self.write_to_cache(self.index, self.cache_path_index)
-
-    def connect(self, region):
-        ''' create connection to api server'''
-        if self.eucalyptus:
-            conn = boto.connect_euca(host=self.eucalyptus_host)
-            conn.APIVersion = '2010-08-31'
-        else:
-            conn = self.connect_to_aws(ec2, region)
-        return conn
-
-    def boto_fix_security_token_in_profile(self, connect_args):
-        ''' monkey patch for boto issue boto/boto#2100 '''
-        profile = 'profile ' + self.boto_profile
-        if boto.config.has_option(profile, 'aws_security_token'):
-            connect_args['security_token'] = boto.config.get(profile, 'aws_security_token')
-        return connect_args
-
-    def connect_to_aws(self, module, region):
-        connect_args = {}
-
-        # only pass the profile name if it's set (as it is not supported by older boto versions)
-        if self.boto_profile:
-            connect_args['profile_name'] = self.boto_profile
-            self.boto_fix_security_token_in_profile(connect_args)
-
-        conn = module.connect_to_region(region, **connect_args)
-        # connect_to_region will fail "silently" by returning None if the region name is wrong or not supported
-        if conn is None:
-            self.fail_with_error("region name: %s likely not supported, or AWS is down.  connection to region failed." % region)
-        return conn
-
-    def get_instances_by_region(self, region):
-        ''' Makes an AWS EC2 API call to the list of instances in a particular
-        region '''
-
-        try:
-            conn = self.connect(region)
-            reservations = []
-            if self.ec2_instance_filters:
-                for filter_key, filter_values in self.ec2_instance_filters.items():
-                    reservations.extend(conn.get_all_instances(filters = { filter_key : filter_values }))
-            else:
-                reservations = conn.get_all_instances()
-
-            for reservation in reservations:
-                for instance in reservation.instances:
-                    self.add_instance(instance, region)
-
-        except boto.exception.BotoServerError as e:
-            if e.error_code == 'AuthFailure':
-                error = self.get_auth_error_message()
-            else:
-                backend = 'Eucalyptus' if self.eucalyptus else 'AWS'
-                error = "Error connecting to %s backend.\n%s" % (backend, e.message)
-            self.fail_with_error(error, 'getting EC2 instances')
-
-    def get_rds_instances_by_region(self, region):
-        ''' Makes an AWS API call to the list of RDS instances in a particular
-        region '''
-
-        try:
-            conn = self.connect_to_aws(rds, region)
-            if conn:
-                marker = None
-                while True:
-                    instances = conn.get_all_dbinstances(marker=marker)
-                    marker = instances.marker
-                    for instance in instances:
-                        self.add_rds_instance(instance, region)
-                    if not marker:
-                        break
-        except boto.exception.BotoServerError as e:
-            error = e.reason
-
-            if e.error_code == 'AuthFailure':
-                error = self.get_auth_error_message()
-            if not e.reason == "Forbidden":
-                error = "Looks like AWS RDS is down:\n%s" % e.message
-            self.fail_with_error(error, 'getting RDS instances')
-
-    def get_elasticache_clusters_by_region(self, region):
-        ''' Makes an AWS API call to the list of ElastiCache clusters (with
-        nodes' info) in a particular region.'''
-
-        # ElastiCache boto module doesn't provide a get_all_intances method,
-        # that's why we need to call describe directly (it would be called by
-        # the shorthand method anyway...)
-        try:
-            conn = self.connect_to_aws(elasticache, region)
-            if conn:
-                # show_cache_node_info = True
-                # because we also want nodes' information
-                response = conn.describe_cache_clusters(None, None, None, True)
-
-        except boto.exception.BotoServerError as e:
-            error = e.reason
-
-            if e.error_code == 'AuthFailure':
-                error = self.get_auth_error_message()
-            if not e.reason == "Forbidden":
-                error = "Looks like AWS ElastiCache is down:\n%s" % e.message
-            self.fail_with_error(error, 'getting ElastiCache clusters')
-
-        try:
-            # Boto also doesn't provide wrapper classes to CacheClusters or
-            # CacheNodes. Because of that wo can't make use of the get_list
-            # method in the AWSQueryConnection. Let's do the work manually
-            clusters = response['DescribeCacheClustersResponse']['DescribeCacheClustersResult']['CacheClusters']
-
-        except KeyError as e:
-            error = "ElastiCache query to AWS failed (unexpected format)."
-            self.fail_with_error(error, 'getting ElastiCache clusters')
-
-        for cluster in clusters:
-            self.add_elasticache_cluster(cluster, region)
-
-    def get_elasticache_replication_groups_by_region(self, region):
-        ''' Makes an AWS API call to the list of ElastiCache replication groups
-        in a particular region.'''
-
-        # ElastiCache boto module doesn't provide a get_all_intances method,
-        # that's why we need to call describe directly (it would be called by
-        # the shorthand method anyway...)
-        try:
-            conn = self.connect_to_aws(elasticache, region)
-            if conn:
-                response = conn.describe_replication_groups()
-
-        except boto.exception.BotoServerError as e:
-            error = e.reason
-
-            if e.error_code == 'AuthFailure':
-                error = self.get_auth_error_message()
-            if not e.reason == "Forbidden":
-                error = "Looks like AWS ElastiCache [Replication Groups] is down:\n%s" % e.message
-            self.fail_with_error(error, 'getting ElastiCache clusters')
-
-        try:
-            # Boto also doesn't provide wrapper classes to ReplicationGroups
-            # Because of that wo can't make use of the get_list method in the
-            # AWSQueryConnection. Let's do the work manually
-            replication_groups = response['DescribeReplicationGroupsResponse']['DescribeReplicationGroupsResult']['ReplicationGroups']
-
-        except KeyError as e:
-            error = "ElastiCache [Replication Groups] query to AWS failed (unexpected format)."
-            self.fail_with_error(error, 'getting ElastiCache clusters')
-
-        for replication_group in replication_groups:
-            self.add_elasticache_replication_group(replication_group, region)
-
-    def get_auth_error_message(self):
-        ''' create an informative error message if there is an issue authenticating'''
-        errors = ["Authentication error retrieving ec2 inventory."]
-        if None in [os.environ.get('AWS_ACCESS_KEY_ID'), os.environ.get('AWS_SECRET_ACCESS_KEY')]:
-            errors.append(' - No AWS_ACCESS_KEY_ID or AWS_SECRET_ACCESS_KEY environment vars found')
-        else:
-            errors.append(' - AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY environment vars found but may not be correct')
-
-        boto_paths = ['/etc/boto.cfg', '~/.boto', '~/.aws/credentials']
-        boto_config_found = list(p for p in boto_paths if os.path.isfile(os.path.expanduser(p)))
-        if len(boto_config_found) > 0:
-            errors.append(" - Boto configs found at '%s', but the credentials contained may not be correct" % ', '.join(boto_config_found))
-        else:
-            errors.append(" - No Boto config found at any expected location '%s'" % ', '.join(boto_paths))
-
-        return '\n'.join(errors)
-
-    def fail_with_error(self, err_msg, err_operation=None):
-        '''log an error to std err for ansible-playbook to consume and exit'''
-        if err_operation:
-            err_msg = 'ERROR: "{err_msg}", while: {err_operation}'.format(
-                    err_msg=err_msg, err_operation=err_operation)
-        sys.stderr.write(err_msg)
-        sys.exit(1)
-
-    def get_instance(self, region, instance_id):
-        conn = self.connect(region)
-
-        reservations = conn.get_all_instances([instance_id])
-        for reservation in reservations:
-            for instance in reservation.instances:
-                return instance
-
-    def add_instance(self, instance, region):
-        ''' Adds an instance to the inventory and index, as long as it is
-        addressable '''
-
-        # Only return instances with desired instance states
-        if instance.state not in self.ec2_instance_states:
-            return
-
-        # Select the best destination address
-        if self.destination_format and self.destination_format_tags:
-            dest = self.destination_format.format(*[ getattr(instance, 'tags').get(tag, '') for tag in self.destination_format_tags ])
-        elif instance.subnet_id:
-            dest = getattr(instance, self.vpc_destination_variable, None)
-            if dest is None:
-                dest = getattr(instance, 'tags').get(self.vpc_destination_variable, None)
-        else:
-            dest = getattr(instance, self.destination_variable, None)
-            if dest is None:
-                dest = getattr(instance, 'tags').get(self.destination_variable, None)
-
-        if not dest:
-            # Skip instances we cannot address (e.g. private VPC subnet)
-            return
-
-        # Set the inventory name
-        hostname = None
-        if self.hostname_variable:
-            if self.hostname_variable.startswith('tag_'):
-                hostname = instance.tags.get(self.hostname_variable[4:], None)
-            else:
-                hostname = getattr(instance, self.hostname_variable)
-
-        # If we can't get a nice hostname, use the destination address
-        if not hostname:
-            hostname = dest
-        else:
-            hostname = self.to_safe(hostname).lower()
-
-        # if we only want to include hosts that match a pattern, skip those that don't
-        if self.pattern_include and not self.pattern_include.match(hostname):
-            return
-
-        # if we need to exclude hosts that match a pattern, skip those
-        if self.pattern_exclude and self.pattern_exclude.match(hostname):
-            return
-
-        # Add to index
-        self.index[hostname] = [region, instance.id]
-
-        # Inventory: Group by instance ID (always a group of 1)
-        if self.group_by_instance_id:
-            self.inventory[instance.id] = [hostname]
-            if self.nested_groups:
-                self.push_group(self.inventory, 'instances', instance.id)
-
-        # Inventory: Group by region
-        if self.group_by_region:
-            self.push(self.inventory, region, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'regions', region)
-
-        # Inventory: Group by availability zone
-        if self.group_by_availability_zone:
-            self.push(self.inventory, instance.placement, hostname)
-            if self.nested_groups:
-                if self.group_by_region:
-                    self.push_group(self.inventory, region, instance.placement)
-                self.push_group(self.inventory, 'zones', instance.placement)
-
-        # Inventory: Group by Amazon Machine Image (AMI) ID
-        if self.group_by_ami_id:
-            ami_id = self.to_safe(instance.image_id)
-            self.push(self.inventory, ami_id, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'images', ami_id)
-
-        # Inventory: Group by instance type
-        if self.group_by_instance_type:
-            type_name = self.to_safe('type_' + instance.instance_type)
-            self.push(self.inventory, type_name, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'types', type_name)
-
-        # Inventory: Group by key pair
-        if self.group_by_key_pair and instance.key_name:
-            key_name = self.to_safe('key_' + instance.key_name)
-            self.push(self.inventory, key_name, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'keys', key_name)
-
-        # Inventory: Group by VPC
-        if self.group_by_vpc_id and instance.vpc_id:
-            vpc_id_name = self.to_safe('vpc_id_' + instance.vpc_id)
-            self.push(self.inventory, vpc_id_name, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'vpcs', vpc_id_name)
-
-        # Inventory: Group by security group
-        if self.group_by_security_group:
-            try:
-                for group in instance.groups:
-                    key = self.to_safe("security_group_" + group.name)
-                    self.push(self.inventory, key, hostname)
-                    if self.nested_groups:
-                        self.push_group(self.inventory, 'security_groups', key)
-            except AttributeError:
-                self.fail_with_error('\n'.join(['Package boto seems a bit older.',
-                                                'Please upgrade boto >= 2.3.0.']))
-
-        # Inventory: Group by tag keys
-        if self.group_by_tag_keys:
-            for k, v in instance.tags.items():
-                if self.expand_csv_tags and v and ',' in v:
-                    values = map(lambda x: x.strip(), v.split(','))
-                else:
-                    values = [v]
-
-                for v in values:
-                    if v:
-                        key = self.to_safe("tag_" + k + "=" + v)
-                    else:
-                        key = self.to_safe("tag_" + k)
-                    self.push(self.inventory, key, hostname)
-                    if self.nested_groups:
-                        self.push_group(self.inventory, 'tags', self.to_safe("tag_" + k))
-                        if v:
-                            self.push_group(self.inventory, self.to_safe("tag_" + k), key)
-
-        # Inventory: Group by Route53 domain names if enabled
-        if self.route53_enabled and self.group_by_route53_names:
-            route53_names = self.get_instance_route53_names(instance)
-            for name in route53_names:
-                self.push(self.inventory, name, hostname)
-                if self.nested_groups:
-                    self.push_group(self.inventory, 'route53', name)
-
-        # Global Tag: instances without tags
-        if self.group_by_tag_none and len(instance.tags) == 0:
-            self.push(self.inventory, 'tag_none', hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'tags', 'tag_none')
-
-        # Global Tag: tag all EC2 instances
-        self.push(self.inventory, 'ec2', hostname)
-
-        self.inventory["_meta"]["hostvars"][hostname] = self.get_host_info_dict_from_instance(instance)
-        self.inventory["_meta"]["hostvars"][hostname]['ansible_ssh_host'] = dest
-
-
-    def add_rds_instance(self, instance, region):
-        ''' Adds an RDS instance to the inventory and index, as long as it is
-        addressable '''
-
-        # Only want available instances unless all_rds_instances is True
-        if not self.all_rds_instances and instance.status != 'available':
-            return
-
-        # Select the best destination address
-        dest = instance.endpoint[0]
-
-        if not dest:
-            # Skip instances we cannot address (e.g. private VPC subnet)
-            return
-
-        # Set the inventory name
-        hostname = None
-        if self.hostname_variable:
-            if self.hostname_variable.startswith('tag_'):
-                hostname = instance.tags.get(self.hostname_variable[4:], None)
-            else:
-                hostname = getattr(instance, self.hostname_variable)
-
-        # If we can't get a nice hostname, use the destination address
-        if not hostname:
-            hostname = dest
-
-        hostname = self.to_safe(hostname).lower()
-
-        # Add to index
-        self.index[hostname] = [region, instance.id]
-
-        # Inventory: Group by instance ID (always a group of 1)
-        if self.group_by_instance_id:
-            self.inventory[instance.id] = [hostname]
-            if self.nested_groups:
-                self.push_group(self.inventory, 'instances', instance.id)
-
-        # Inventory: Group by region
-        if self.group_by_region:
-            self.push(self.inventory, region, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'regions', region)
-
-        # Inventory: Group by availability zone
-        if self.group_by_availability_zone:
-            self.push(self.inventory, instance.availability_zone, hostname)
-            if self.nested_groups:
-                if self.group_by_region:
-                    self.push_group(self.inventory, region, instance.availability_zone)
-                self.push_group(self.inventory, 'zones', instance.availability_zone)
-
-        # Inventory: Group by instance type
-        if self.group_by_instance_type:
-            type_name = self.to_safe('type_' + instance.instance_class)
-            self.push(self.inventory, type_name, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'types', type_name)
-
-        # Inventory: Group by VPC
-        if self.group_by_vpc_id and instance.subnet_group and instance.subnet_group.vpc_id:
-            vpc_id_name = self.to_safe('vpc_id_' + instance.subnet_group.vpc_id)
-            self.push(self.inventory, vpc_id_name, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'vpcs', vpc_id_name)
-
-        # Inventory: Group by security group
-        if self.group_by_security_group:
-            try:
-                if instance.security_group:
-                    key = self.to_safe("security_group_" + instance.security_group.name)
-                    self.push(self.inventory, key, hostname)
-                    if self.nested_groups:
-                        self.push_group(self.inventory, 'security_groups', key)
-
-            except AttributeError:
-                self.fail_with_error('\n'.join(['Package boto seems a bit older.',
-                                                'Please upgrade boto >= 2.3.0.']))
-
-
-        # Inventory: Group by engine
-        if self.group_by_rds_engine:
-            self.push(self.inventory, self.to_safe("rds_" + instance.engine), hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'rds_engines', self.to_safe("rds_" + instance.engine))
-
-        # Inventory: Group by parameter group
-        if self.group_by_rds_parameter_group:
-            self.push(self.inventory, self.to_safe("rds_parameter_group_" + instance.parameter_group.name), hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'rds_parameter_groups', self.to_safe("rds_parameter_group_" + instance.parameter_group.name))
-
-        # Global Tag: all RDS instances
-        self.push(self.inventory, 'rds', hostname)
-
-        self.inventory["_meta"]["hostvars"][hostname] = self.get_host_info_dict_from_instance(instance)
-        self.inventory["_meta"]["hostvars"][hostname]['ansible_ssh_host'] = dest
-
-    def add_elasticache_cluster(self, cluster, region):
-        ''' Adds an ElastiCache cluster to the inventory and index, as long as
-        it's nodes are addressable '''
-
-        # Only want available clusters unless all_elasticache_clusters is True
-        if not self.all_elasticache_clusters and cluster['CacheClusterStatus'] != 'available':
-            return
-
-        # Select the best destination address
-        if 'ConfigurationEndpoint' in cluster and cluster['ConfigurationEndpoint']:
-            # Memcached cluster
-            dest = cluster['ConfigurationEndpoint']['Address']
-            is_redis = False
-        else:
-            # Redis sigle node cluster
-            # Because all Redis clusters are single nodes, we'll merge the
-            # info from the cluster with info about the node
-            dest = cluster['CacheNodes'][0]['Endpoint']['Address']
-            is_redis = True
-
-        if not dest:
-            # Skip clusters we cannot address (e.g. private VPC subnet)
-            return
-
-        # Add to index
-        self.index[dest] = [region, cluster['CacheClusterId']]
-
-        # Inventory: Group by instance ID (always a group of 1)
-        if self.group_by_instance_id:
-            self.inventory[cluster['CacheClusterId']] = [dest]
-            if self.nested_groups:
-                self.push_group(self.inventory, 'instances', cluster['CacheClusterId'])
-
-        # Inventory: Group by region
-        if self.group_by_region and not is_redis:
-            self.push(self.inventory, region, dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'regions', region)
-
-        # Inventory: Group by availability zone
-        if self.group_by_availability_zone and not is_redis:
-            self.push(self.inventory, cluster['PreferredAvailabilityZone'], dest)
-            if self.nested_groups:
-                if self.group_by_region:
-                    self.push_group(self.inventory, region, cluster['PreferredAvailabilityZone'])
-                self.push_group(self.inventory, 'zones', cluster['PreferredAvailabilityZone'])
-
-        # Inventory: Group by node type
-        if self.group_by_instance_type and not is_redis:
-            type_name = self.to_safe('type_' + cluster['CacheNodeType'])
-            self.push(self.inventory, type_name, dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'types', type_name)
-
-        # Inventory: Group by VPC (information not available in the current
-        # AWS API version for ElastiCache)
-
-        # Inventory: Group by security group
-        if self.group_by_security_group and not is_redis:
-
-            # Check for the existence of the 'SecurityGroups' key and also if
-            # this key has some value. When the cluster is not placed in a SG
-            # the query can return None here and cause an error.
-            if 'SecurityGroups' in cluster and cluster['SecurityGroups'] is not None:
-                for security_group in cluster['SecurityGroups']:
-                    key = self.to_safe("security_group_" + security_group['SecurityGroupId'])
-                    self.push(self.inventory, key, dest)
-                    if self.nested_groups:
-                        self.push_group(self.inventory, 'security_groups', key)
-
-        # Inventory: Group by engine
-        if self.group_by_elasticache_engine and not is_redis:
-            self.push(self.inventory, self.to_safe("elasticache_" + cluster['Engine']), dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'elasticache_engines', self.to_safe(cluster['Engine']))
-
-        # Inventory: Group by parameter group
-        if self.group_by_elasticache_parameter_group:
-            self.push(self.inventory, self.to_safe("elasticache_parameter_group_" + cluster['CacheParameterGroup']['CacheParameterGroupName']), dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'elasticache_parameter_groups', self.to_safe(cluster['CacheParameterGroup']['CacheParameterGroupName']))
-
-        # Inventory: Group by replication group
-        if self.group_by_elasticache_replication_group and 'ReplicationGroupId' in cluster and cluster['ReplicationGroupId']:
-            self.push(self.inventory, self.to_safe("elasticache_replication_group_" + cluster['ReplicationGroupId']), dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'elasticache_replication_groups', self.to_safe(cluster['ReplicationGroupId']))
-
-        # Global Tag: all ElastiCache clusters
-        self.push(self.inventory, 'elasticache_clusters', cluster['CacheClusterId'])
-
-        host_info = self.get_host_info_dict_from_describe_dict(cluster)
-
-        self.inventory["_meta"]["hostvars"][dest] = host_info
-
-        # Add the nodes
-        for node in cluster['CacheNodes']:
-            self.add_elasticache_node(node, cluster, region)
-
-    def add_elasticache_node(self, node, cluster, region):
-        ''' Adds an ElastiCache node to the inventory and index, as long as
-        it is addressable '''
-
-        # Only want available nodes unless all_elasticache_nodes is True
-        if not self.all_elasticache_nodes and node['CacheNodeStatus'] != 'available':
-            return
-
-        # Select the best destination address
-        dest = node['Endpoint']['Address']
-
-        if not dest:
-            # Skip nodes we cannot address (e.g. private VPC subnet)
-            return
-
-        node_id = self.to_safe(cluster['CacheClusterId'] + '_' + node['CacheNodeId'])
-
-        # Add to index
-        self.index[dest] = [region, node_id]
-
-        # Inventory: Group by node ID (always a group of 1)
-        if self.group_by_instance_id:
-            self.inventory[node_id] = [dest]
-            if self.nested_groups:
-                self.push_group(self.inventory, 'instances', node_id)
-
-        # Inventory: Group by region
-        if self.group_by_region:
-            self.push(self.inventory, region, dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'regions', region)
-
-        # Inventory: Group by availability zone
-        if self.group_by_availability_zone:
-            self.push(self.inventory, cluster['PreferredAvailabilityZone'], dest)
-            if self.nested_groups:
-                if self.group_by_region:
-                    self.push_group(self.inventory, region, cluster['PreferredAvailabilityZone'])
-                self.push_group(self.inventory, 'zones', cluster['PreferredAvailabilityZone'])
-
-        # Inventory: Group by node type
-        if self.group_by_instance_type:
-            type_name = self.to_safe('type_' + cluster['CacheNodeType'])
-            self.push(self.inventory, type_name, dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'types', type_name)
-
-        # Inventory: Group by VPC (information not available in the current
-        # AWS API version for ElastiCache)
-
-        # Inventory: Group by security group
-        if self.group_by_security_group:
-
-            # Check for the existence of the 'SecurityGroups' key and also if
-            # this key has some value. When the cluster is not placed in a SG
-            # the query can return None here and cause an error.
-            if 'SecurityGroups' in cluster and cluster['SecurityGroups'] is not None:
-                for security_group in cluster['SecurityGroups']:
-                    key = self.to_safe("security_group_" + security_group['SecurityGroupId'])
-                    self.push(self.inventory, key, dest)
-                    if self.nested_groups:
-                        self.push_group(self.inventory, 'security_groups', key)
-
-        # Inventory: Group by engine
-        if self.group_by_elasticache_engine:
-            self.push(self.inventory, self.to_safe("elasticache_" + cluster['Engine']), dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'elasticache_engines', self.to_safe("elasticache_" + cluster['Engine']))
-
-        # Inventory: Group by parameter group (done at cluster level)
-
-        # Inventory: Group by replication group (done at cluster level)
-
-        # Inventory: Group by ElastiCache Cluster
-        if self.group_by_elasticache_cluster:
-            self.push(self.inventory, self.to_safe("elasticache_cluster_" + cluster['CacheClusterId']), dest)
-
-        # Global Tag: all ElastiCache nodes
-        self.push(self.inventory, 'elasticache_nodes', dest)
-
-        host_info = self.get_host_info_dict_from_describe_dict(node)
-
-        if dest in self.inventory["_meta"]["hostvars"]:
-            self.inventory["_meta"]["hostvars"][dest].update(host_info)
-        else:
-            self.inventory["_meta"]["hostvars"][dest] = host_info
-
-    def add_elasticache_replication_group(self, replication_group, region):
-        ''' Adds an ElastiCache replication group to the inventory and index '''
-
-        # Only want available clusters unless all_elasticache_replication_groups is True
-        if not self.all_elasticache_replication_groups and replication_group['Status'] != 'available':
-            return
-
-        # Select the best destination address (PrimaryEndpoint)
-        dest = replication_group['NodeGroups'][0]['PrimaryEndpoint']['Address']
-
-        if not dest:
-            # Skip clusters we cannot address (e.g. private VPC subnet)
-            return
-
-        # Add to index
-        self.index[dest] = [region, replication_group['ReplicationGroupId']]
-
-        # Inventory: Group by ID (always a group of 1)
-        if self.group_by_instance_id:
-            self.inventory[replication_group['ReplicationGroupId']] = [dest]
-            if self.nested_groups:
-                self.push_group(self.inventory, 'instances', replication_group['ReplicationGroupId'])
-
-        # Inventory: Group by region
-        if self.group_by_region:
-            self.push(self.inventory, region, dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'regions', region)
-
-        # Inventory: Group by availability zone (doesn't apply to replication groups)
-
-        # Inventory: Group by node type (doesn't apply to replication groups)
-
-        # Inventory: Group by VPC (information not available in the current
-        # AWS API version for replication groups
-
-        # Inventory: Group by security group (doesn't apply to replication groups)
-        # Check this value in cluster level
-
-        # Inventory: Group by engine (replication groups are always Redis)
-        if self.group_by_elasticache_engine:
-            self.push(self.inventory, 'elasticache_redis', dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'elasticache_engines', 'redis')
-
-        # Global Tag: all ElastiCache clusters
-        self.push(self.inventory, 'elasticache_replication_groups', replication_group['ReplicationGroupId'])
-
-        host_info = self.get_host_info_dict_from_describe_dict(replication_group)
-
-        self.inventory["_meta"]["hostvars"][dest] = host_info
-
-    def get_route53_records(self):
-        ''' Get and store the map of resource records to domain names that
-        point to them. '''
-
-        r53_conn = route53.Route53Connection()
-        all_zones = r53_conn.get_zones()
-
-        route53_zones = [ zone for zone in all_zones if zone.name[:-1]
-                          not in self.route53_excluded_zones ]
-
-        self.route53_records = {}
-
-        for zone in route53_zones:
-            rrsets = r53_conn.get_all_rrsets(zone.id)
-
-            for record_set in rrsets:
-                record_name = record_set.name
-
-                if record_name.endswith('.'):
-                    record_name = record_name[:-1]
-
-                for resource in record_set.resource_records:
-                    self.route53_records.setdefault(resource, set())
-                    self.route53_records[resource].add(record_name)
-
-
-    def get_instance_route53_names(self, instance):
-        ''' Check if an instance is referenced in the records we have from
-        Route53. If it is, return the list of domain names pointing to said
-        instance. If nothing points to it, return an empty list. '''
-
-        instance_attributes = [ 'public_dns_name', 'private_dns_name',
-                                'ip_address', 'private_ip_address' ]
-
-        name_list = set()
-
-        for attrib in instance_attributes:
-            try:
-                value = getattr(instance, attrib)
-            except AttributeError:
-                continue
-
-            if value in self.route53_records:
-                name_list.update(self.route53_records[value])
-
-        return list(name_list)
-
-    def get_host_info_dict_from_instance(self, instance):
-        instance_vars = {}
-        for key in vars(instance):
-            value = getattr(instance, key)
-            key = self.to_safe('ec2_' + key)
-
-            # Handle complex types
-            # state/previous_state changed to properties in boto in https://github.com/boto/boto/commit/a23c379837f698212252720d2af8dec0325c9518
-            if key == 'ec2__state':
-                instance_vars['ec2_state'] = instance.state or ''
-                instance_vars['ec2_state_code'] = instance.state_code
-            elif key == 'ec2__previous_state':
-                instance_vars['ec2_previous_state'] = instance.previous_state or ''
-                instance_vars['ec2_previous_state_code'] = instance.previous_state_code
-            elif type(value) in [int, bool]:
-                instance_vars[key] = value
-            elif isinstance(value, six.string_types):
-                instance_vars[key] = value.strip()
-            elif type(value) == type(None):
-                instance_vars[key] = ''
-            elif key == 'ec2_region':
-                instance_vars[key] = value.name
-            elif key == 'ec2__placement':
-                instance_vars['ec2_placement'] = value.zone
-            elif key == 'ec2_tags':
-                for k, v in value.items():
-                    if self.expand_csv_tags and ',' in v:
-                        v = map(lambda x: x.strip(), v.split(','))
-                    key = self.to_safe('ec2_tag_' + k)
-                    instance_vars[key] = v
-            elif key == 'ec2_groups':
-                group_ids = []
-                group_names = []
-                for group in value:
-                    group_ids.append(group.id)
-                    group_names.append(group.name)
-                instance_vars["ec2_security_group_ids"] = ','.join([str(i) for i in group_ids])
-                instance_vars["ec2_security_group_names"] = ','.join([str(i) for i in group_names])
-            else:
-                pass
-                # TODO Product codes if someone finds them useful
-                #print key
-                #print type(value)
-                #print value
-
-        return instance_vars
-
-    def get_host_info_dict_from_describe_dict(self, describe_dict):
-        ''' Parses the dictionary returned by the API call into a flat list
-            of parameters. This method should be used only when 'describe' is
-            used directly because Boto doesn't provide specific classes. '''
-
-        # I really don't agree with prefixing everything with 'ec2'
-        # because EC2, RDS and ElastiCache are different services.
-        # I'm just following the pattern used until now to not break any
-        # compatibility.
-
-        host_info = {}
-        for key in describe_dict:
-            value = describe_dict[key]
-            key = self.to_safe('ec2_' + self.uncammelize(key))
-
-            # Handle complex types
-
-            # Target: Memcached Cache Clusters
-            if key == 'ec2_configuration_endpoint' and value:
-                host_info['ec2_configuration_endpoint_address'] = value['Address']
-                host_info['ec2_configuration_endpoint_port'] = value['Port']
-
-            # Target: Cache Nodes and Redis Cache Clusters (single node)
-            if key == 'ec2_endpoint' and value:
-                host_info['ec2_endpoint_address'] = value['Address']
-                host_info['ec2_endpoint_port'] = value['Port']
-
-            # Target: Redis Replication Groups
-            if key == 'ec2_node_groups' and value:
-                host_info['ec2_endpoint_address'] = value[0]['PrimaryEndpoint']['Address']
-                host_info['ec2_endpoint_port'] = value[0]['PrimaryEndpoint']['Port']
-                replica_count = 0
-                for node in value[0]['NodeGroupMembers']:
-                    if node['CurrentRole'] == 'primary':
-                        host_info['ec2_primary_cluster_address'] = node['ReadEndpoint']['Address']
-                        host_info['ec2_primary_cluster_port'] = node['ReadEndpoint']['Port']
-                        host_info['ec2_primary_cluster_id'] = node['CacheClusterId']
-                    elif node['CurrentRole'] == 'replica':
-                        host_info['ec2_replica_cluster_address_'+ str(replica_count)] = node['ReadEndpoint']['Address']
-                        host_info['ec2_replica_cluster_port_'+ str(replica_count)] = node['ReadEndpoint']['Port']
-                        host_info['ec2_replica_cluster_id_'+ str(replica_count)] = node['CacheClusterId']
-                        replica_count += 1
-
-            # Target: Redis Replication Groups
-            if key == 'ec2_member_clusters' and value:
-                host_info['ec2_member_clusters'] = ','.join([str(i) for i in value])
-
-            # Target: All Cache Clusters
-            elif key == 'ec2_cache_parameter_group':
-                host_info["ec2_cache_node_ids_to_reboot"] = ','.join([str(i) for i in value['CacheNodeIdsToReboot']])
-                host_info['ec2_cache_parameter_group_name'] = value['CacheParameterGroupName']
-                host_info['ec2_cache_parameter_apply_status'] = value['ParameterApplyStatus']
-
-            # Target: Almost everything
-            elif key == 'ec2_security_groups':
-
-                # Skip if SecurityGroups is None
-                # (it is possible to have the key defined but no value in it).
-                if value is not None:
-                    sg_ids = []
-                    for sg in value:
-                        sg_ids.append(sg['SecurityGroupId'])
-                    host_info["ec2_security_group_ids"] = ','.join([str(i) for i in sg_ids])
-
-            # Target: Everything
-            # Preserve booleans and integers
-            elif type(value) in [int, bool]:
-                host_info[key] = value
-
-            # Target: Everything
-            # Sanitize string values
-            elif isinstance(value, six.string_types):
-                host_info[key] = value.strip()
-
-            # Target: Everything
-            # Replace None by an empty string
-            elif type(value) == type(None):
-                host_info[key] = ''
-
-            else:
-                # Remove non-processed complex types
-                pass
-
-        return host_info
-
-    def get_host_info(self):
-        ''' Get variables about a specific host '''
-
-        if len(self.index) == 0:
-            # Need to load index from cache
-            self.load_index_from_cache()
-
-        if not self.args.host in self.index:
-            # try updating the cache
-            self.do_api_calls_update_cache()
-            if not self.args.host in self.index:
-                # host might not exist anymore
-                return self.json_format_dict({}, True)
-
-        (region, instance_id) = self.index[self.args.host]
-
-        instance = self.get_instance(region, instance_id)
-        return self.json_format_dict(self.get_host_info_dict_from_instance(instance), True)
-
-    def push(self, my_dict, key, element):
-        ''' Push an element onto an array that may not have been defined in
-        the dict '''
-        group_info = my_dict.setdefault(key, [])
-        if isinstance(group_info, dict):
-            host_list = group_info.setdefault('hosts', [])
-            host_list.append(element)
-        else:
-            group_info.append(element)
-
-    def push_group(self, my_dict, key, element):
-        ''' Push a group as a child of another group. '''
-        parent_group = my_dict.setdefault(key, {})
-        if not isinstance(parent_group, dict):
-            parent_group = my_dict[key] = {'hosts': parent_group}
-        child_groups = parent_group.setdefault('children', [])
-        if element not in child_groups:
-            child_groups.append(element)
-
-    def get_inventory_from_cache(self):
-        ''' Reads the inventory from the cache file and returns it as a JSON
-        object '''
-
-        cache = open(self.cache_path_cache, 'r')
-        json_inventory = cache.read()
-        return json_inventory
-
-
-    def load_index_from_cache(self):
-        ''' Reads the index from the cache file sets self.index '''
-
-        cache = open(self.cache_path_index, 'r')
-        json_index = cache.read()
-        self.index = json.loads(json_index)
-
-
-    def write_to_cache(self, data, filename):
-        ''' Writes data in JSON format to a file '''
-
-        json_data = self.json_format_dict(data, True)
-        cache = open(filename, 'w')
-        cache.write(json_data)
-        cache.close()
-
-    def uncammelize(self, key):
-        temp = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', key)
-        return re.sub('([a-z0-9])([A-Z])', r'\1_\2', temp).lower()
-
-    def to_safe(self, word):
-        ''' Converts 'bad' characters in a string to underscores so they can be used as Ansible groups '''
-        regex = "[^A-Za-z0-9\_"
-        if not self.replace_dash_in_groups:
-            regex += "\-"
-        return re.sub(regex + "]", "_", word)
-
-    def json_format_dict(self, data, pretty=False):
-        ''' Converts a dict to a JSON object and dumps it as a formatted
-        string '''
-
-        if pretty:
-            return json.dumps(data, sort_keys=True, indent=2)
-        else:
-            return json.dumps(data)
-
-
-# Run the script
-Ec2Inventory()
diff --git a/edge-1701-dc5/inventory b/edge-1701-dc5/inventory
deleted file mode 100644
index 332a944..0000000
--- a/edge-1701-dc5/inventory
+++ /dev/null
@@ -1,75 +0,0 @@
-[tag_Name_dc5_n1]
-[tag_Name_dc5_n2]
-[tag_Name_dc5_n3]
-[tag_Name_dc5_n4]
-[tag_Name_dc5_n5]
-
-[planet:children]
-dc-1
-
-[dc-1:children]
-tag_Name_dc5_n1
-tag_Name_dc5_n2
-tag_Name_dc5_n3
-tag_Name_dc5_n4
-tag_Name_dc5_n5
-
-[ds:children]
-dc-1-ds
-
-[dc-1-ds:children]
-tag_Name_dc5_n1
-tag_Name_dc5_n2
-tag_Name_dc5_n3
-
-[ms:children]
-dc-1-ms
-
-[dc-1-ms:children]
-tag_Name_dc5_n1
-
-[ui:children]
-dc-1-ui
-
-[dc-1-ui:children]
-tag_Name_dc5_n1
-
-[ldap:children]
-dc-1-ldap
-
-[dc-1-ldap:children]
-tag_Name_dc5_n1
-
-[rmp:children]
-dc-1-rmp
-
-[dc-1-rmp:children]
-tag_Name_dc5_n2
-tag_Name_dc5_n3
-
-[qpid:children]
-dc-1-qpid
-
-[dc-1-qpid:children]
-tag_Name_dc5_n4
-tag_Name_dc5_n5
-
-[pg:children]
-dc-1-pg
-
-[dc-1-pg:children]
-dc-1-pgmaster
-dc-1-pgstandby
-
-[pgmaster:children]
-dc-1-pgmaster
-
-[dc-1-pgmaster:children]
-tag_Name_dc5_n4
-
-[pgstandby:children]
-dc-1-pgstandby
-
-[dc-1-pgstandby:children]
-tag_Name_dc5_n5
-
diff --git a/edge-1701-dc7/ec2.ini b/edge-1701-dc7/ec2.ini
deleted file mode 100644
index 36b3921..0000000
--- a/edge-1701-dc7/ec2.ini
+++ /dev/null
@@ -1,200 +0,0 @@
-# Ansible EC2 external inventory script settings
-#
-
-[ec2]
-
-# to talk to a private eucalyptus instance uncomment these lines
-# and edit edit eucalyptus_host to be the host name of your cloud controller
-#eucalyptus = True
-#eucalyptus_host = clc.cloud.domain.org
-
-# AWS regions to make calls to. Set this to 'all' to make request to all regions
-# in AWS and merge the results together. Alternatively, set this to a comma
-# separated list of regions. E.g. 'us-east-1,us-west-1,us-west-2'
-regions = all
-regions_exclude = us-gov-west-1,cn-north-1
-
-# When generating inventory, Ansible needs to know how to address a server.
-# Each EC2 instance has a lot of variables associated with it. Here is the list:
-#   http://docs.pythonboto.org/en/latest/ref/ec2.html#module-boto.ec2.instance
-# Below are 2 variables that are used as the address of a server:
-#   - destination_variable
-#   - vpc_destination_variable
-
-# This is the normal destination variable to use. If you are running Ansible
-# from outside EC2, then 'public_dns_name' makes the most sense. If you are
-# running Ansible from within EC2, then perhaps you want to use the internal
-# address, and should set this to 'private_dns_name'. The key of an EC2 tag
-# may optionally be used; however the boto instance variables hold precedence
-# in the event of a collision.
-destination_variable = public_dns_name
-
-# This allows you to override the inventory_name with an ec2 variable, instead
-# of using the destination_variable above. Addressing (aka ansible_ssh_host)
-# will still use destination_variable. Tags should be written as 'tag_TAGNAME'.
-#hostname_variable = tag_Name
-
-# For server inside a VPC, using DNS names may not make sense. When an instance
-# has 'subnet_id' set, this variable is used. If the subnet is public, setting
-# this to 'ip_address' will return the public IP address. For instances in a
-# private subnet, this should be set to 'private_ip_address', and Ansible must
-# be run from within EC2. The key of an EC2 tag may optionally be used; however
-# the boto instance variables hold precedence in the event of a collision.
-# WARNING: - instances that are in the private vpc, _without_ public ip address
-# will not be listed in the inventory until You set:
-# vpc_destination_variable = private_ip_address
-vpc_destination_variable = ip_address
-
-# The following two settings allow flexible ansible host naming based on a
-# python format string and a comma-separated list of ec2 tags.  Note that:
-#
-# 1) If the tags referenced are not present for some instances, empty strings
-#    will be substituted in the format string.
-# 2) This overrides both destination_variable and vpc_destination_variable.
-#
-#destination_format = {0}.{1}.example.com
-#destination_format_tags = Name,environment
-
-# To tag instances on EC2 with the resource records that point to them from
-# Route53, uncomment and set 'route53' to True.
-route53 = False
-
-# To exclude RDS instances from the inventory, uncomment and set to False.
-rds = False
-
-# To exclude ElastiCache instances from the inventory, uncomment and set to False.
-elasticache = False
-
-# Additionally, you can specify the list of zones to exclude looking up in
-# 'route53_excluded_zones' as a comma-separated list.
-# route53_excluded_zones = samplezone1.com, samplezone2.com
-
-# By default, only EC2 instances in the 'running' state are returned. Set
-# 'all_instances' to True to return all instances regardless of state.
-all_instances = True
-
-# By default, only EC2 instances in the 'running' state are returned. Specify
-# EC2 instance states to return as a comma-separated list. This
-# option is overriden when 'all_instances' is True.
-# instance_states = pending, running, shutting-down, terminated, stopping, stopped
-
-# By default, only RDS instances in the 'available' state are returned.  Set
-# 'all_rds_instances' to True return all RDS instances regardless of state.
-all_rds_instances = False
-
-# By default, only ElastiCache clusters and nodes in the 'available' state
-# are returned. Set 'all_elasticache_clusters' and/or 'all_elastic_nodes'
-# to True return all ElastiCache clusters and nodes, regardless of state.
-#
-# Note that all_elasticache_nodes only applies to listed clusters. That means
-# if you set all_elastic_clusters to false, no node will be return from
-# unavailable clusters, regardless of the state and to what you set for
-# all_elasticache_nodes.
-all_elasticache_replication_groups = False
-all_elasticache_clusters = False
-all_elasticache_nodes = False
-
-# API calls to EC2 are slow. For this reason, we cache the results of an API
-# call. Set this to the path you want cache files to be written to. Two files
-# will be written to this directory:
-#   - ansible-ec2.cache
-#   - ansible-ec2.index
-cache_path = ~/.ansible/tmp
-
-# The number of seconds a cache file is considered valid. After this many
-# seconds, a new API call will be made, and the cache file will be updated.
-# To disable the cache, set this value to 0
-cache_max_age = 300
-
-# Organize groups into a nested/hierarchy instead of a flat namespace.
-nested_groups = False
-
-# Replace - tags when creating groups to avoid issues with ansible
-replace_dash_in_groups = True
-
-# If set to true, any tag of the form "a,b,c" is expanded into a list
-# and the results are used to create additional tag_* inventory groups.
-expand_csv_tags = False
-
-# The EC2 inventory output can become very large. To manage its size,
-# configure which groups should be created.
-group_by_instance_id = True
-group_by_region = True
-group_by_availability_zone = True
-group_by_ami_id = True
-group_by_instance_type = True
-group_by_key_pair = True
-group_by_vpc_id = True
-group_by_security_group = True
-group_by_tag_keys = True
-group_by_tag_none = True
-group_by_route53_names = True
-group_by_rds_engine = False
-group_by_rds_parameter_group = False
-group_by_elasticache_engine = True
-group_by_elasticache_cluster = True
-group_by_elasticache_parameter_group = True
-group_by_elasticache_replication_group = True
-
-# If you only want to include hosts that match a certain regular expression
-# pattern_include = staging-*
-
-# If you want to exclude any hosts that match a certain regular expression
-# pattern_exclude = staging-*
-# Ansible EC2 external inventory script settings
-#
-
-##[ec2]
-##
-### to talk to a private eucalyptus instance uncomment these lines
-### and edit edit eucalyptus_host to be the host name of your cloud controller
-###eucalyptus = True
-###eucalyptus_host = clc.cloud.domain.org
-##
-### AWS regions to make calls to. Set this to 'all' to make request to all regions
-##
-### in AWS and merge the results together. Alternatively, set this to a comma
-### separated list of regions. E.g. 'us-east-1,us-west-1,us-west-2'
-##regions = all
-##regions_exclude = us-gov-west-1,cn-north-1
-##
-### When generating inventory, Ansible needs to know how to address a server.
-### Each EC2 instance has a lot of variables associated with it. Here is the list:
-###   http://docs.pythonboto.org/en/latest/ref/ec2.html#module-boto.ec2.instance
-### Below are 2 variables that are used as the address of a server:
-###   - destination_variable
-###   - vpc_destination_variable
-##
-### This is the normal destination variable to use. If you are running Ansible
-### from outside EC2, then 'public_dns_name' makes the most sense. If you are
-### running Ansible from within EC2, then perhaps you want to use the internal
-### address, and should set this to 'private_dns_name'. The key of an EC2 tag
-##...skipping...
-### pattern_include = staging-*
-##
-### If you want to exclude any hosts that match a certain regular expression
-### pattern_exclude = staging-*
-
-# Instance filters can be used to control which instances are retrieved for
-# inventory. For the full list of possible filters, please read the EC2 API
-# docs: http://docs.aws.amazon.com/AWSEC2/latest/APIReference/ApiReference-query-DescribeInstances.html#query-DescribeInstances-filters
-# Filters are key/value pairs separated by '=', to list multiple filters use
-# a list separated by commas. See examples below.
-
-# Retrieve only instances with (key=value) env=staging tag
-# instance_filters = tag:env=staging
-
-# Retrieve only instances with role=webservers OR role=dbservers tag
-# instance_filters = tag:role=webservers,tag:role=dbservers
-
-# Retrieve only t1.micro instances OR instances with tag env=staging
-# instance_filters = instance-type=t1.micro,tag:env=staging
-
-# You can use wildcards in filter values also. Below will list instances which
-# tag Name value matches webservers1*
-# (ex. webservers15, webservers1a, webservers123 etc)
-# instance_filters = tag:Name=webservers1*
-
-# A boto configuration profile may be used to separate out credentials
-# see http://boto.readthedocs.org/en/latest/boto_config_tut.html
-# boto_profile = some-boto-profile-name
diff --git a/edge-1701-dc7/ec2.py b/edge-1701-dc7/ec2.py
deleted file mode 100755
index f30958a..0000000
--- a/edge-1701-dc7/ec2.py
+++ /dev/null
@@ -1,1385 +0,0 @@
-#!/usr/bin/env python
-
-'''
-EC2 external inventory script
-=================================
-
-Generates inventory that Ansible can understand by making API request to
-AWS EC2 using the Boto library.
-
-NOTE: This script assumes Ansible is being executed where the environment
-variables needed for Boto have already been set:
-    export AWS_ACCESS_KEY_ID='AK123'
-    export AWS_SECRET_ACCESS_KEY='abc123'
-
-This script also assumes there is an ec2.ini file alongside it.  To specify a
-different path to ec2.ini, define the EC2_INI_PATH environment variable:
-
-    export EC2_INI_PATH=/path/to/my_ec2.ini
-
-If you're using eucalyptus you need to set the above variables and
-you need to define:
-
-    export EC2_URL=http://hostname_of_your_cc:port/services/Eucalyptus
-
-If you're using boto profiles (requires boto>=2.24.0) you can choose a profile
-using the --boto-profile command line argument (e.g. ec2.py --boto-profile prod) or using
-the AWS_PROFILE variable:
-
-    AWS_PROFILE=prod ansible-playbook -i ec2.py myplaybook.yml
-
-For more details, see: http://docs.pythonboto.org/en/latest/boto_config_tut.html
-
-When run against a specific host, this script returns the following variables:
- - ec2_ami_launch_index
- - ec2_architecture
- - ec2_association
- - ec2_attachTime
- - ec2_attachment
- - ec2_attachmentId
- - ec2_client_token
- - ec2_deleteOnTermination
- - ec2_description
- - ec2_deviceIndex
- - ec2_dns_name
- - ec2_eventsSet
- - ec2_group_name
- - ec2_hypervisor
- - ec2_id
- - ec2_image_id
- - ec2_instanceState
- - ec2_instance_type
- - ec2_ipOwnerId
- - ec2_ip_address
- - ec2_item
- - ec2_kernel
- - ec2_key_name
- - ec2_launch_time
- - ec2_monitored
- - ec2_monitoring
- - ec2_networkInterfaceId
- - ec2_ownerId
- - ec2_persistent
- - ec2_placement
- - ec2_platform
- - ec2_previous_state
- - ec2_private_dns_name
- - ec2_private_ip_address
- - ec2_publicIp
- - ec2_public_dns_name
- - ec2_ramdisk
- - ec2_reason
- - ec2_region
- - ec2_requester_id
- - ec2_root_device_name
- - ec2_root_device_type
- - ec2_security_group_ids
- - ec2_security_group_names
- - ec2_shutdown_state
- - ec2_sourceDestCheck
- - ec2_spot_instance_request_id
- - ec2_state
- - ec2_state_code
- - ec2_state_reason
- - ec2_status
- - ec2_subnet_id
- - ec2_tenancy
- - ec2_virtualization_type
- - ec2_vpc_id
-
-These variables are pulled out of a boto.ec2.instance object. There is a lack of
-consistency with variable spellings (camelCase and underscores) since this
-just loops through all variables the object exposes. It is preferred to use the
-ones with underscores when multiple exist.
-
-In addition, if an instance has AWS Tags associated with it, each tag is a new
-variable named:
- - ec2_tag_[Key] = [Value]
-
-Security groups are comma-separated in 'ec2_security_group_ids' and
-'ec2_security_group_names'.
-'''
-
-# (c) 2012, Peter Sankauskas
-#
-# This file is part of Ansible,
-#
-# Ansible is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# Ansible is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with Ansible.  If not, see <http://www.gnu.org/licenses/>.
-
-######################################################################
-
-import sys
-import os
-import argparse
-import re
-from time import time
-import boto
-from boto import ec2
-from boto import rds
-from boto import elasticache
-from boto import route53
-import six
-
-from six.moves import configparser
-from collections import defaultdict
-
-try:
-    import json
-except ImportError:
-    import simplejson as json
-
-
-class Ec2Inventory(object):
-
-    def _empty_inventory(self):
-        return {"_meta" : {"hostvars" : {}}}
-
-    def __init__(self):
-        ''' Main execution path '''
-
-        # Inventory grouped by instance IDs, tags, security groups, regions,
-        # and availability zones
-        self.inventory = self._empty_inventory()
-
-        # Index of hostname (address) to instance ID
-        self.index = {}
-
-        # Boto profile to use (if any)
-        self.boto_profile = None
-
-        # Read settings and parse CLI arguments
-        self.parse_cli_args()
-        self.read_settings()
-
-        # Make sure that profile_name is not passed at all if not set
-        # as pre 2.24 boto will fall over otherwise
-        if self.boto_profile:
-            if not hasattr(boto.ec2.EC2Connection, 'profile_name'):
-                self.fail_with_error("boto version must be >= 2.24 to use profile")
-
-        # Cache
-        if self.args.refresh_cache:
-            self.do_api_calls_update_cache()
-        elif not self.is_cache_valid():
-            self.do_api_calls_update_cache()
-
-        # Data to print
-        if self.args.host:
-            data_to_print = self.get_host_info()
-
-        elif self.args.list:
-            # Display list of instances for inventory
-            if self.inventory == self._empty_inventory():
-                data_to_print = self.get_inventory_from_cache()
-            else:
-                data_to_print = self.json_format_dict(self.inventory, True)
-
-        print(data_to_print)
-
-
-    def is_cache_valid(self):
-        ''' Determines if the cache files have expired, or if it is still valid '''
-
-        if os.path.isfile(self.cache_path_cache):
-            mod_time = os.path.getmtime(self.cache_path_cache)
-            current_time = time()
-            if (mod_time + self.cache_max_age) > current_time:
-                if os.path.isfile(self.cache_path_index):
-                    return True
-
-        return False
-
-
-    def read_settings(self):
-        ''' Reads the settings from the ec2.ini file '''
-        if six.PY3:
-            config = configparser.ConfigParser()
-        else:
-            config = configparser.SafeConfigParser()
-        ec2_default_ini_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'ec2.ini')
-        ec2_ini_path = os.path.expanduser(os.path.expandvars(os.environ.get('EC2_INI_PATH', ec2_default_ini_path)))
-        config.read(ec2_ini_path)
-
-        # is eucalyptus?
-        self.eucalyptus_host = None
-        self.eucalyptus = False
-        if config.has_option('ec2', 'eucalyptus'):
-            self.eucalyptus = config.getboolean('ec2', 'eucalyptus')
-        if self.eucalyptus and config.has_option('ec2', 'eucalyptus_host'):
-            self.eucalyptus_host = config.get('ec2', 'eucalyptus_host')
-
-        # Regions
-        self.regions = []
-        configRegions = config.get('ec2', 'regions')
-        configRegions_exclude = config.get('ec2', 'regions_exclude')
-        if (configRegions == 'all'):
-            if self.eucalyptus_host:
-                self.regions.append(boto.connect_euca(host=self.eucalyptus_host).region.name)
-            else:
-                for regionInfo in ec2.regions():
-                    if regionInfo.name not in configRegions_exclude:
-                        self.regions.append(regionInfo.name)
-        else:
-            self.regions = configRegions.split(",")
-
-        # Destination addresses
-        self.destination_variable = config.get('ec2', 'destination_variable')
-        self.vpc_destination_variable = config.get('ec2', 'vpc_destination_variable')
-
-        if config.has_option('ec2', 'hostname_variable'):
-            self.hostname_variable = config.get('ec2', 'hostname_variable')
-        else:
-            self.hostname_variable = None
-
-        if config.has_option('ec2', 'destination_format') and \
-                config.has_option('ec2', 'destination_format_tags'):
-            self.destination_format = config.get('ec2', 'destination_format')
-            self.destination_format_tags = config.get('ec2', 'destination_format_tags').split(',')
-        else:
-            self.destination_format = None
-            self.destination_format_tags = None
-
-        # Route53
-        self.route53_enabled = config.getboolean('ec2', 'route53')
-        self.route53_excluded_zones = []
-        if config.has_option('ec2', 'route53_excluded_zones'):
-            self.route53_excluded_zones.extend(
-                    config.get('ec2', 'route53_excluded_zones', '').split(','))
-
-        # Include RDS instances?
-        self.rds_enabled = True
-        if config.has_option('ec2', 'rds'):
-            self.rds_enabled = config.getboolean('ec2', 'rds')
-
-        # Include ElastiCache instances?
-        self.elasticache_enabled = True
-        if config.has_option('ec2', 'elasticache'):
-            self.elasticache_enabled = config.getboolean('ec2', 'elasticache')
-
-        # Return all EC2 instances?
-        if config.has_option('ec2', 'all_instances'):
-            self.all_instances = config.getboolean('ec2', 'all_instances')
-        else:
-            self.all_instances = False
-
-        # Instance states to be gathered in inventory. Default is 'running'.
-        # Setting 'all_instances' to 'yes' overrides this option.
-        ec2_valid_instance_states = [
-            'pending',
-            'running',
-            'shutting-down',
-            'terminated',
-            'stopping',
-            'stopped'
-        ]
-        self.ec2_instance_states = []
-        if self.all_instances:
-            self.ec2_instance_states = ec2_valid_instance_states
-        elif config.has_option('ec2', 'instance_states'):
-            for instance_state in config.get('ec2', 'instance_states').split(','):
-                instance_state = instance_state.strip()
-                if instance_state not in ec2_valid_instance_states:
-                    continue
-                self.ec2_instance_states.append(instance_state)
-        else:
-            self.ec2_instance_states = ['running']
-
-        # Return all RDS instances? (if RDS is enabled)
-        if config.has_option('ec2', 'all_rds_instances') and self.rds_enabled:
-            self.all_rds_instances = config.getboolean('ec2', 'all_rds_instances')
-        else:
-            self.all_rds_instances = False
-
-        # Return all ElastiCache replication groups? (if ElastiCache is enabled)
-        if config.has_option('ec2', 'all_elasticache_replication_groups') and self.elasticache_enabled:
-            self.all_elasticache_replication_groups = config.getboolean('ec2', 'all_elasticache_replication_groups')
-        else:
-            self.all_elasticache_replication_groups = False
-
-        # Return all ElastiCache clusters? (if ElastiCache is enabled)
-        if config.has_option('ec2', 'all_elasticache_clusters') and self.elasticache_enabled:
-            self.all_elasticache_clusters = config.getboolean('ec2', 'all_elasticache_clusters')
-        else:
-            self.all_elasticache_clusters = False
-
-        # Return all ElastiCache nodes? (if ElastiCache is enabled)
-        if config.has_option('ec2', 'all_elasticache_nodes') and self.elasticache_enabled:
-            self.all_elasticache_nodes = config.getboolean('ec2', 'all_elasticache_nodes')
-        else:
-            self.all_elasticache_nodes = False
-
-        # boto configuration profile (prefer CLI argument)
-        self.boto_profile = self.args.boto_profile
-        if config.has_option('ec2', 'boto_profile') and not self.boto_profile:
-            self.boto_profile = config.get('ec2', 'boto_profile')
-
-        # Cache related
-        cache_dir = os.path.expanduser(config.get('ec2', 'cache_path'))
-        if self.boto_profile:
-            cache_dir = os.path.join(cache_dir, 'profile_' + self.boto_profile)
-        if not os.path.exists(cache_dir):
-            os.makedirs(cache_dir)
-
-        cache_name = 'ansible-ec2'
-        aws_profile = lambda: (self.boto_profile or
-                               os.environ.get('AWS_PROFILE') or
-                               os.environ.get('AWS_ACCESS_KEY_ID'))
-        if aws_profile():
-            cache_name = '%s-%s' % (cache_name, aws_profile())
-        self.cache_path_cache = cache_dir + "/%s.cache" % cache_name
-        self.cache_path_index = cache_dir + "/%s.index" % cache_name
-        self.cache_max_age = config.getint('ec2', 'cache_max_age')
-
-        if config.has_option('ec2', 'expand_csv_tags'):
-            self.expand_csv_tags = config.getboolean('ec2', 'expand_csv_tags')
-        else:
-            self.expand_csv_tags = False
-
-        # Configure nested groups instead of flat namespace.
-        if config.has_option('ec2', 'nested_groups'):
-            self.nested_groups = config.getboolean('ec2', 'nested_groups')
-        else:
-            self.nested_groups = False
-
-        # Replace dash or not in group names
-        if config.has_option('ec2', 'replace_dash_in_groups'):
-            self.replace_dash_in_groups = config.getboolean('ec2', 'replace_dash_in_groups')
-        else:
-            self.replace_dash_in_groups = True
-
-        # Configure which groups should be created.
-        group_by_options = [
-            'group_by_instance_id',
-            'group_by_region',
-            'group_by_availability_zone',
-            'group_by_ami_id',
-            'group_by_instance_type',
-            'group_by_key_pair',
-            'group_by_vpc_id',
-            'group_by_security_group',
-            'group_by_tag_keys',
-            'group_by_tag_none',
-            'group_by_route53_names',
-            'group_by_rds_engine',
-            'group_by_rds_parameter_group',
-            'group_by_elasticache_engine',
-            'group_by_elasticache_cluster',
-            'group_by_elasticache_parameter_group',
-            'group_by_elasticache_replication_group',
-        ]
-        for option in group_by_options:
-            if config.has_option('ec2', option):
-                setattr(self, option, config.getboolean('ec2', option))
-            else:
-                setattr(self, option, True)
-
-        # Do we need to just include hosts that match a pattern?
-        try:
-            pattern_include = config.get('ec2', 'pattern_include')
-            if pattern_include and len(pattern_include) > 0:
-                self.pattern_include = re.compile(pattern_include)
-            else:
-                self.pattern_include = None
-        except configparser.NoOptionError:
-            self.pattern_include = None
-
-        # Do we need to exclude hosts that match a pattern?
-        try:
-            pattern_exclude = config.get('ec2', 'pattern_exclude');
-            if pattern_exclude and len(pattern_exclude) > 0:
-                self.pattern_exclude = re.compile(pattern_exclude)
-            else:
-                self.pattern_exclude = None
-        except configparser.NoOptionError:
-            self.pattern_exclude = None
-
-        # Instance filters (see boto and EC2 API docs). Ignore invalid filters.
-        self.ec2_instance_filters = defaultdict(list)
-        if config.has_option('ec2', 'instance_filters'):
-
-            filters = [f for f in config.get('ec2', 'instance_filters').split(',') if f]
-
-            for instance_filter in filters:
-                instance_filter = instance_filter.strip()
-                if not instance_filter or '=' not in instance_filter:
-                    continue
-                filter_key, filter_value = [x.strip() for x in instance_filter.split('=', 1)]
-                if not filter_key:
-                    continue
-                self.ec2_instance_filters[filter_key].append(filter_value)
-
-    def parse_cli_args(self):
-        ''' Command line argument processing '''
-
-        parser = argparse.ArgumentParser(description='Produce an Ansible Inventory file based on EC2')
-        parser.add_argument('--list', action='store_true', default=True,
-                            help='List instances (default: True)')
-        parser.add_argument('--host', action='store',
-                            help='Get all the variables about a specific instance')
-        parser.add_argument('--refresh-cache', action='store_true', default=False,
-                            help='Force refresh of cache by making API requests to EC2 (default: False - use cache files)')
-        parser.add_argument('--profile', '--boto-profile', action='store', dest='boto_profile',
-                            help='Use boto profile for connections to EC2')
-        self.args = parser.parse_args()
-
-
-    def do_api_calls_update_cache(self):
-        ''' Do API calls to each region, and save data in cache files '''
-
-        if self.route53_enabled:
-            self.get_route53_records()
-
-        for region in self.regions:
-            self.get_instances_by_region(region)
-            if self.rds_enabled:
-                self.get_rds_instances_by_region(region)
-            if self.elasticache_enabled:
-                self.get_elasticache_clusters_by_region(region)
-                self.get_elasticache_replication_groups_by_region(region)
-
-        self.write_to_cache(self.inventory, self.cache_path_cache)
-        self.write_to_cache(self.index, self.cache_path_index)
-
-    def connect(self, region):
-        ''' create connection to api server'''
-        if self.eucalyptus:
-            conn = boto.connect_euca(host=self.eucalyptus_host)
-            conn.APIVersion = '2010-08-31'
-        else:
-            conn = self.connect_to_aws(ec2, region)
-        return conn
-
-    def boto_fix_security_token_in_profile(self, connect_args):
-        ''' monkey patch for boto issue boto/boto#2100 '''
-        profile = 'profile ' + self.boto_profile
-        if boto.config.has_option(profile, 'aws_security_token'):
-            connect_args['security_token'] = boto.config.get(profile, 'aws_security_token')
-        return connect_args
-
-    def connect_to_aws(self, module, region):
-        connect_args = {}
-
-        # only pass the profile name if it's set (as it is not supported by older boto versions)
-        if self.boto_profile:
-            connect_args['profile_name'] = self.boto_profile
-            self.boto_fix_security_token_in_profile(connect_args)
-
-        conn = module.connect_to_region(region, **connect_args)
-        # connect_to_region will fail "silently" by returning None if the region name is wrong or not supported
-        if conn is None:
-            self.fail_with_error("region name: %s likely not supported, or AWS is down.  connection to region failed." % region)
-        return conn
-
-    def get_instances_by_region(self, region):
-        ''' Makes an AWS EC2 API call to the list of instances in a particular
-        region '''
-
-        try:
-            conn = self.connect(region)
-            reservations = []
-            if self.ec2_instance_filters:
-                for filter_key, filter_values in self.ec2_instance_filters.items():
-                    reservations.extend(conn.get_all_instances(filters = { filter_key : filter_values }))
-            else:
-                reservations = conn.get_all_instances()
-
-            for reservation in reservations:
-                for instance in reservation.instances:
-                    self.add_instance(instance, region)
-
-        except boto.exception.BotoServerError as e:
-            if e.error_code == 'AuthFailure':
-                error = self.get_auth_error_message()
-            else:
-                backend = 'Eucalyptus' if self.eucalyptus else 'AWS'
-                error = "Error connecting to %s backend.\n%s" % (backend, e.message)
-            self.fail_with_error(error, 'getting EC2 instances')
-
-    def get_rds_instances_by_region(self, region):
-        ''' Makes an AWS API call to the list of RDS instances in a particular
-        region '''
-
-        try:
-            conn = self.connect_to_aws(rds, region)
-            if conn:
-                marker = None
-                while True:
-                    instances = conn.get_all_dbinstances(marker=marker)
-                    marker = instances.marker
-                    for instance in instances:
-                        self.add_rds_instance(instance, region)
-                    if not marker:
-                        break
-        except boto.exception.BotoServerError as e:
-            error = e.reason
-
-            if e.error_code == 'AuthFailure':
-                error = self.get_auth_error_message()
-            if not e.reason == "Forbidden":
-                error = "Looks like AWS RDS is down:\n%s" % e.message
-            self.fail_with_error(error, 'getting RDS instances')
-
-    def get_elasticache_clusters_by_region(self, region):
-        ''' Makes an AWS API call to the list of ElastiCache clusters (with
-        nodes' info) in a particular region.'''
-
-        # ElastiCache boto module doesn't provide a get_all_intances method,
-        # that's why we need to call describe directly (it would be called by
-        # the shorthand method anyway...)
-        try:
-            conn = self.connect_to_aws(elasticache, region)
-            if conn:
-                # show_cache_node_info = True
-                # because we also want nodes' information
-                response = conn.describe_cache_clusters(None, None, None, True)
-
-        except boto.exception.BotoServerError as e:
-            error = e.reason
-
-            if e.error_code == 'AuthFailure':
-                error = self.get_auth_error_message()
-            if not e.reason == "Forbidden":
-                error = "Looks like AWS ElastiCache is down:\n%s" % e.message
-            self.fail_with_error(error, 'getting ElastiCache clusters')
-
-        try:
-            # Boto also doesn't provide wrapper classes to CacheClusters or
-            # CacheNodes. Because of that wo can't make use of the get_list
-            # method in the AWSQueryConnection. Let's do the work manually
-            clusters = response['DescribeCacheClustersResponse']['DescribeCacheClustersResult']['CacheClusters']
-
-        except KeyError as e:
-            error = "ElastiCache query to AWS failed (unexpected format)."
-            self.fail_with_error(error, 'getting ElastiCache clusters')
-
-        for cluster in clusters:
-            self.add_elasticache_cluster(cluster, region)
-
-    def get_elasticache_replication_groups_by_region(self, region):
-        ''' Makes an AWS API call to the list of ElastiCache replication groups
-        in a particular region.'''
-
-        # ElastiCache boto module doesn't provide a get_all_intances method,
-        # that's why we need to call describe directly (it would be called by
-        # the shorthand method anyway...)
-        try:
-            conn = self.connect_to_aws(elasticache, region)
-            if conn:
-                response = conn.describe_replication_groups()
-
-        except boto.exception.BotoServerError as e:
-            error = e.reason
-
-            if e.error_code == 'AuthFailure':
-                error = self.get_auth_error_message()
-            if not e.reason == "Forbidden":
-                error = "Looks like AWS ElastiCache [Replication Groups] is down:\n%s" % e.message
-            self.fail_with_error(error, 'getting ElastiCache clusters')
-
-        try:
-            # Boto also doesn't provide wrapper classes to ReplicationGroups
-            # Because of that wo can't make use of the get_list method in the
-            # AWSQueryConnection. Let's do the work manually
-            replication_groups = response['DescribeReplicationGroupsResponse']['DescribeReplicationGroupsResult']['ReplicationGroups']
-
-        except KeyError as e:
-            error = "ElastiCache [Replication Groups] query to AWS failed (unexpected format)."
-            self.fail_with_error(error, 'getting ElastiCache clusters')
-
-        for replication_group in replication_groups:
-            self.add_elasticache_replication_group(replication_group, region)
-
-    def get_auth_error_message(self):
-        ''' create an informative error message if there is an issue authenticating'''
-        errors = ["Authentication error retrieving ec2 inventory."]
-        if None in [os.environ.get('AWS_ACCESS_KEY_ID'), os.environ.get('AWS_SECRET_ACCESS_KEY')]:
-            errors.append(' - No AWS_ACCESS_KEY_ID or AWS_SECRET_ACCESS_KEY environment vars found')
-        else:
-            errors.append(' - AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY environment vars found but may not be correct')
-
-        boto_paths = ['/etc/boto.cfg', '~/.boto', '~/.aws/credentials']
-        boto_config_found = list(p for p in boto_paths if os.path.isfile(os.path.expanduser(p)))
-        if len(boto_config_found) > 0:
-            errors.append(" - Boto configs found at '%s', but the credentials contained may not be correct" % ', '.join(boto_config_found))
-        else:
-            errors.append(" - No Boto config found at any expected location '%s'" % ', '.join(boto_paths))
-
-        return '\n'.join(errors)
-
-    def fail_with_error(self, err_msg, err_operation=None):
-        '''log an error to std err for ansible-playbook to consume and exit'''
-        if err_operation:
-            err_msg = 'ERROR: "{err_msg}", while: {err_operation}'.format(
-                    err_msg=err_msg, err_operation=err_operation)
-        sys.stderr.write(err_msg)
-        sys.exit(1)
-
-    def get_instance(self, region, instance_id):
-        conn = self.connect(region)
-
-        reservations = conn.get_all_instances([instance_id])
-        for reservation in reservations:
-            for instance in reservation.instances:
-                return instance
-
-    def add_instance(self, instance, region):
-        ''' Adds an instance to the inventory and index, as long as it is
-        addressable '''
-
-        # Only return instances with desired instance states
-        if instance.state not in self.ec2_instance_states:
-            return
-
-        # Select the best destination address
-        if self.destination_format and self.destination_format_tags:
-            dest = self.destination_format.format(*[ getattr(instance, 'tags').get(tag, '') for tag in self.destination_format_tags ])
-        elif instance.subnet_id:
-            dest = getattr(instance, self.vpc_destination_variable, None)
-            if dest is None:
-                dest = getattr(instance, 'tags').get(self.vpc_destination_variable, None)
-        else:
-            dest = getattr(instance, self.destination_variable, None)
-            if dest is None:
-                dest = getattr(instance, 'tags').get(self.destination_variable, None)
-
-        if not dest:
-            # Skip instances we cannot address (e.g. private VPC subnet)
-            return
-
-        # Set the inventory name
-        hostname = None
-        if self.hostname_variable:
-            if self.hostname_variable.startswith('tag_'):
-                hostname = instance.tags.get(self.hostname_variable[4:], None)
-            else:
-                hostname = getattr(instance, self.hostname_variable)
-
-        # If we can't get a nice hostname, use the destination address
-        if not hostname:
-            hostname = dest
-        else:
-            hostname = self.to_safe(hostname).lower()
-
-        # if we only want to include hosts that match a pattern, skip those that don't
-        if self.pattern_include and not self.pattern_include.match(hostname):
-            return
-
-        # if we need to exclude hosts that match a pattern, skip those
-        if self.pattern_exclude and self.pattern_exclude.match(hostname):
-            return
-
-        # Add to index
-        self.index[hostname] = [region, instance.id]
-
-        # Inventory: Group by instance ID (always a group of 1)
-        if self.group_by_instance_id:
-            self.inventory[instance.id] = [hostname]
-            if self.nested_groups:
-                self.push_group(self.inventory, 'instances', instance.id)
-
-        # Inventory: Group by region
-        if self.group_by_region:
-            self.push(self.inventory, region, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'regions', region)
-
-        # Inventory: Group by availability zone
-        if self.group_by_availability_zone:
-            self.push(self.inventory, instance.placement, hostname)
-            if self.nested_groups:
-                if self.group_by_region:
-                    self.push_group(self.inventory, region, instance.placement)
-                self.push_group(self.inventory, 'zones', instance.placement)
-
-        # Inventory: Group by Amazon Machine Image (AMI) ID
-        if self.group_by_ami_id:
-            ami_id = self.to_safe(instance.image_id)
-            self.push(self.inventory, ami_id, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'images', ami_id)
-
-        # Inventory: Group by instance type
-        if self.group_by_instance_type:
-            type_name = self.to_safe('type_' + instance.instance_type)
-            self.push(self.inventory, type_name, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'types', type_name)
-
-        # Inventory: Group by key pair
-        if self.group_by_key_pair and instance.key_name:
-            key_name = self.to_safe('key_' + instance.key_name)
-            self.push(self.inventory, key_name, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'keys', key_name)
-
-        # Inventory: Group by VPC
-        if self.group_by_vpc_id and instance.vpc_id:
-            vpc_id_name = self.to_safe('vpc_id_' + instance.vpc_id)
-            self.push(self.inventory, vpc_id_name, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'vpcs', vpc_id_name)
-
-        # Inventory: Group by security group
-        if self.group_by_security_group:
-            try:
-                for group in instance.groups:
-                    key = self.to_safe("security_group_" + group.name)
-                    self.push(self.inventory, key, hostname)
-                    if self.nested_groups:
-                        self.push_group(self.inventory, 'security_groups', key)
-            except AttributeError:
-                self.fail_with_error('\n'.join(['Package boto seems a bit older.',
-                                                'Please upgrade boto >= 2.3.0.']))
-
-        # Inventory: Group by tag keys
-        if self.group_by_tag_keys:
-            for k, v in instance.tags.items():
-                if self.expand_csv_tags and v and ',' in v:
-                    values = map(lambda x: x.strip(), v.split(','))
-                else:
-                    values = [v]
-
-                for v in values:
-                    if v:
-                        key = self.to_safe("tag_" + k + "=" + v)
-                    else:
-                        key = self.to_safe("tag_" + k)
-                    self.push(self.inventory, key, hostname)
-                    if self.nested_groups:
-                        self.push_group(self.inventory, 'tags', self.to_safe("tag_" + k))
-                        if v:
-                            self.push_group(self.inventory, self.to_safe("tag_" + k), key)
-
-        # Inventory: Group by Route53 domain names if enabled
-        if self.route53_enabled and self.group_by_route53_names:
-            route53_names = self.get_instance_route53_names(instance)
-            for name in route53_names:
-                self.push(self.inventory, name, hostname)
-                if self.nested_groups:
-                    self.push_group(self.inventory, 'route53', name)
-
-        # Global Tag: instances without tags
-        if self.group_by_tag_none and len(instance.tags) == 0:
-            self.push(self.inventory, 'tag_none', hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'tags', 'tag_none')
-
-        # Global Tag: tag all EC2 instances
-        self.push(self.inventory, 'ec2', hostname)
-
-        self.inventory["_meta"]["hostvars"][hostname] = self.get_host_info_dict_from_instance(instance)
-        self.inventory["_meta"]["hostvars"][hostname]['ansible_ssh_host'] = dest
-
-
-    def add_rds_instance(self, instance, region):
-        ''' Adds an RDS instance to the inventory and index, as long as it is
-        addressable '''
-
-        # Only want available instances unless all_rds_instances is True
-        if not self.all_rds_instances and instance.status != 'available':
-            return
-
-        # Select the best destination address
-        dest = instance.endpoint[0]
-
-        if not dest:
-            # Skip instances we cannot address (e.g. private VPC subnet)
-            return
-
-        # Set the inventory name
-        hostname = None
-        if self.hostname_variable:
-            if self.hostname_variable.startswith('tag_'):
-                hostname = instance.tags.get(self.hostname_variable[4:], None)
-            else:
-                hostname = getattr(instance, self.hostname_variable)
-
-        # If we can't get a nice hostname, use the destination address
-        if not hostname:
-            hostname = dest
-
-        hostname = self.to_safe(hostname).lower()
-
-        # Add to index
-        self.index[hostname] = [region, instance.id]
-
-        # Inventory: Group by instance ID (always a group of 1)
-        if self.group_by_instance_id:
-            self.inventory[instance.id] = [hostname]
-            if self.nested_groups:
-                self.push_group(self.inventory, 'instances', instance.id)
-
-        # Inventory: Group by region
-        if self.group_by_region:
-            self.push(self.inventory, region, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'regions', region)
-
-        # Inventory: Group by availability zone
-        if self.group_by_availability_zone:
-            self.push(self.inventory, instance.availability_zone, hostname)
-            if self.nested_groups:
-                if self.group_by_region:
-                    self.push_group(self.inventory, region, instance.availability_zone)
-                self.push_group(self.inventory, 'zones', instance.availability_zone)
-
-        # Inventory: Group by instance type
-        if self.group_by_instance_type:
-            type_name = self.to_safe('type_' + instance.instance_class)
-            self.push(self.inventory, type_name, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'types', type_name)
-
-        # Inventory: Group by VPC
-        if self.group_by_vpc_id and instance.subnet_group and instance.subnet_group.vpc_id:
-            vpc_id_name = self.to_safe('vpc_id_' + instance.subnet_group.vpc_id)
-            self.push(self.inventory, vpc_id_name, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'vpcs', vpc_id_name)
-
-        # Inventory: Group by security group
-        if self.group_by_security_group:
-            try:
-                if instance.security_group:
-                    key = self.to_safe("security_group_" + instance.security_group.name)
-                    self.push(self.inventory, key, hostname)
-                    if self.nested_groups:
-                        self.push_group(self.inventory, 'security_groups', key)
-
-            except AttributeError:
-                self.fail_with_error('\n'.join(['Package boto seems a bit older.',
-                                                'Please upgrade boto >= 2.3.0.']))
-
-
-        # Inventory: Group by engine
-        if self.group_by_rds_engine:
-            self.push(self.inventory, self.to_safe("rds_" + instance.engine), hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'rds_engines', self.to_safe("rds_" + instance.engine))
-
-        # Inventory: Group by parameter group
-        if self.group_by_rds_parameter_group:
-            self.push(self.inventory, self.to_safe("rds_parameter_group_" + instance.parameter_group.name), hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'rds_parameter_groups', self.to_safe("rds_parameter_group_" + instance.parameter_group.name))
-
-        # Global Tag: all RDS instances
-        self.push(self.inventory, 'rds', hostname)
-
-        self.inventory["_meta"]["hostvars"][hostname] = self.get_host_info_dict_from_instance(instance)
-        self.inventory["_meta"]["hostvars"][hostname]['ansible_ssh_host'] = dest
-
-    def add_elasticache_cluster(self, cluster, region):
-        ''' Adds an ElastiCache cluster to the inventory and index, as long as
-        it's nodes are addressable '''
-
-        # Only want available clusters unless all_elasticache_clusters is True
-        if not self.all_elasticache_clusters and cluster['CacheClusterStatus'] != 'available':
-            return
-
-        # Select the best destination address
-        if 'ConfigurationEndpoint' in cluster and cluster['ConfigurationEndpoint']:
-            # Memcached cluster
-            dest = cluster['ConfigurationEndpoint']['Address']
-            is_redis = False
-        else:
-            # Redis sigle node cluster
-            # Because all Redis clusters are single nodes, we'll merge the
-            # info from the cluster with info about the node
-            dest = cluster['CacheNodes'][0]['Endpoint']['Address']
-            is_redis = True
-
-        if not dest:
-            # Skip clusters we cannot address (e.g. private VPC subnet)
-            return
-
-        # Add to index
-        self.index[dest] = [region, cluster['CacheClusterId']]
-
-        # Inventory: Group by instance ID (always a group of 1)
-        if self.group_by_instance_id:
-            self.inventory[cluster['CacheClusterId']] = [dest]
-            if self.nested_groups:
-                self.push_group(self.inventory, 'instances', cluster['CacheClusterId'])
-
-        # Inventory: Group by region
-        if self.group_by_region and not is_redis:
-            self.push(self.inventory, region, dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'regions', region)
-
-        # Inventory: Group by availability zone
-        if self.group_by_availability_zone and not is_redis:
-            self.push(self.inventory, cluster['PreferredAvailabilityZone'], dest)
-            if self.nested_groups:
-                if self.group_by_region:
-                    self.push_group(self.inventory, region, cluster['PreferredAvailabilityZone'])
-                self.push_group(self.inventory, 'zones', cluster['PreferredAvailabilityZone'])
-
-        # Inventory: Group by node type
-        if self.group_by_instance_type and not is_redis:
-            type_name = self.to_safe('type_' + cluster['CacheNodeType'])
-            self.push(self.inventory, type_name, dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'types', type_name)
-
-        # Inventory: Group by VPC (information not available in the current
-        # AWS API version for ElastiCache)
-
-        # Inventory: Group by security group
-        if self.group_by_security_group and not is_redis:
-
-            # Check for the existence of the 'SecurityGroups' key and also if
-            # this key has some value. When the cluster is not placed in a SG
-            # the query can return None here and cause an error.
-            if 'SecurityGroups' in cluster and cluster['SecurityGroups'] is not None:
-                for security_group in cluster['SecurityGroups']:
-                    key = self.to_safe("security_group_" + security_group['SecurityGroupId'])
-                    self.push(self.inventory, key, dest)
-                    if self.nested_groups:
-                        self.push_group(self.inventory, 'security_groups', key)
-
-        # Inventory: Group by engine
-        if self.group_by_elasticache_engine and not is_redis:
-            self.push(self.inventory, self.to_safe("elasticache_" + cluster['Engine']), dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'elasticache_engines', self.to_safe(cluster['Engine']))
-
-        # Inventory: Group by parameter group
-        if self.group_by_elasticache_parameter_group:
-            self.push(self.inventory, self.to_safe("elasticache_parameter_group_" + cluster['CacheParameterGroup']['CacheParameterGroupName']), dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'elasticache_parameter_groups', self.to_safe(cluster['CacheParameterGroup']['CacheParameterGroupName']))
-
-        # Inventory: Group by replication group
-        if self.group_by_elasticache_replication_group and 'ReplicationGroupId' in cluster and cluster['ReplicationGroupId']:
-            self.push(self.inventory, self.to_safe("elasticache_replication_group_" + cluster['ReplicationGroupId']), dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'elasticache_replication_groups', self.to_safe(cluster['ReplicationGroupId']))
-
-        # Global Tag: all ElastiCache clusters
-        self.push(self.inventory, 'elasticache_clusters', cluster['CacheClusterId'])
-
-        host_info = self.get_host_info_dict_from_describe_dict(cluster)
-
-        self.inventory["_meta"]["hostvars"][dest] = host_info
-
-        # Add the nodes
-        for node in cluster['CacheNodes']:
-            self.add_elasticache_node(node, cluster, region)
-
-    def add_elasticache_node(self, node, cluster, region):
-        ''' Adds an ElastiCache node to the inventory and index, as long as
-        it is addressable '''
-
-        # Only want available nodes unless all_elasticache_nodes is True
-        if not self.all_elasticache_nodes and node['CacheNodeStatus'] != 'available':
-            return
-
-        # Select the best destination address
-        dest = node['Endpoint']['Address']
-
-        if not dest:
-            # Skip nodes we cannot address (e.g. private VPC subnet)
-            return
-
-        node_id = self.to_safe(cluster['CacheClusterId'] + '_' + node['CacheNodeId'])
-
-        # Add to index
-        self.index[dest] = [region, node_id]
-
-        # Inventory: Group by node ID (always a group of 1)
-        if self.group_by_instance_id:
-            self.inventory[node_id] = [dest]
-            if self.nested_groups:
-                self.push_group(self.inventory, 'instances', node_id)
-
-        # Inventory: Group by region
-        if self.group_by_region:
-            self.push(self.inventory, region, dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'regions', region)
-
-        # Inventory: Group by availability zone
-        if self.group_by_availability_zone:
-            self.push(self.inventory, cluster['PreferredAvailabilityZone'], dest)
-            if self.nested_groups:
-                if self.group_by_region:
-                    self.push_group(self.inventory, region, cluster['PreferredAvailabilityZone'])
-                self.push_group(self.inventory, 'zones', cluster['PreferredAvailabilityZone'])
-
-        # Inventory: Group by node type
-        if self.group_by_instance_type:
-            type_name = self.to_safe('type_' + cluster['CacheNodeType'])
-            self.push(self.inventory, type_name, dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'types', type_name)
-
-        # Inventory: Group by VPC (information not available in the current
-        # AWS API version for ElastiCache)
-
-        # Inventory: Group by security group
-        if self.group_by_security_group:
-
-            # Check for the existence of the 'SecurityGroups' key and also if
-            # this key has some value. When the cluster is not placed in a SG
-            # the query can return None here and cause an error.
-            if 'SecurityGroups' in cluster and cluster['SecurityGroups'] is not None:
-                for security_group in cluster['SecurityGroups']:
-                    key = self.to_safe("security_group_" + security_group['SecurityGroupId'])
-                    self.push(self.inventory, key, dest)
-                    if self.nested_groups:
-                        self.push_group(self.inventory, 'security_groups', key)
-
-        # Inventory: Group by engine
-        if self.group_by_elasticache_engine:
-            self.push(self.inventory, self.to_safe("elasticache_" + cluster['Engine']), dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'elasticache_engines', self.to_safe("elasticache_" + cluster['Engine']))
-
-        # Inventory: Group by parameter group (done at cluster level)
-
-        # Inventory: Group by replication group (done at cluster level)
-
-        # Inventory: Group by ElastiCache Cluster
-        if self.group_by_elasticache_cluster:
-            self.push(self.inventory, self.to_safe("elasticache_cluster_" + cluster['CacheClusterId']), dest)
-
-        # Global Tag: all ElastiCache nodes
-        self.push(self.inventory, 'elasticache_nodes', dest)
-
-        host_info = self.get_host_info_dict_from_describe_dict(node)
-
-        if dest in self.inventory["_meta"]["hostvars"]:
-            self.inventory["_meta"]["hostvars"][dest].update(host_info)
-        else:
-            self.inventory["_meta"]["hostvars"][dest] = host_info
-
-    def add_elasticache_replication_group(self, replication_group, region):
-        ''' Adds an ElastiCache replication group to the inventory and index '''
-
-        # Only want available clusters unless all_elasticache_replication_groups is True
-        if not self.all_elasticache_replication_groups and replication_group['Status'] != 'available':
-            return
-
-        # Select the best destination address (PrimaryEndpoint)
-        dest = replication_group['NodeGroups'][0]['PrimaryEndpoint']['Address']
-
-        if not dest:
-            # Skip clusters we cannot address (e.g. private VPC subnet)
-            return
-
-        # Add to index
-        self.index[dest] = [region, replication_group['ReplicationGroupId']]
-
-        # Inventory: Group by ID (always a group of 1)
-        if self.group_by_instance_id:
-            self.inventory[replication_group['ReplicationGroupId']] = [dest]
-            if self.nested_groups:
-                self.push_group(self.inventory, 'instances', replication_group['ReplicationGroupId'])
-
-        # Inventory: Group by region
-        if self.group_by_region:
-            self.push(self.inventory, region, dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'regions', region)
-
-        # Inventory: Group by availability zone (doesn't apply to replication groups)
-
-        # Inventory: Group by node type (doesn't apply to replication groups)
-
-        # Inventory: Group by VPC (information not available in the current
-        # AWS API version for replication groups
-
-        # Inventory: Group by security group (doesn't apply to replication groups)
-        # Check this value in cluster level
-
-        # Inventory: Group by engine (replication groups are always Redis)
-        if self.group_by_elasticache_engine:
-            self.push(self.inventory, 'elasticache_redis', dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'elasticache_engines', 'redis')
-
-        # Global Tag: all ElastiCache clusters
-        self.push(self.inventory, 'elasticache_replication_groups', replication_group['ReplicationGroupId'])
-
-        host_info = self.get_host_info_dict_from_describe_dict(replication_group)
-
-        self.inventory["_meta"]["hostvars"][dest] = host_info
-
-    def get_route53_records(self):
-        ''' Get and store the map of resource records to domain names that
-        point to them. '''
-
-        r53_conn = route53.Route53Connection()
-        all_zones = r53_conn.get_zones()
-
-        route53_zones = [ zone for zone in all_zones if zone.name[:-1]
-                          not in self.route53_excluded_zones ]
-
-        self.route53_records = {}
-
-        for zone in route53_zones:
-            rrsets = r53_conn.get_all_rrsets(zone.id)
-
-            for record_set in rrsets:
-                record_name = record_set.name
-
-                if record_name.endswith('.'):
-                    record_name = record_name[:-1]
-
-                for resource in record_set.resource_records:
-                    self.route53_records.setdefault(resource, set())
-                    self.route53_records[resource].add(record_name)
-
-
-    def get_instance_route53_names(self, instance):
-        ''' Check if an instance is referenced in the records we have from
-        Route53. If it is, return the list of domain names pointing to said
-        instance. If nothing points to it, return an empty list. '''
-
-        instance_attributes = [ 'public_dns_name', 'private_dns_name',
-                                'ip_address', 'private_ip_address' ]
-
-        name_list = set()
-
-        for attrib in instance_attributes:
-            try:
-                value = getattr(instance, attrib)
-            except AttributeError:
-                continue
-
-            if value in self.route53_records:
-                name_list.update(self.route53_records[value])
-
-        return list(name_list)
-
-    def get_host_info_dict_from_instance(self, instance):
-        instance_vars = {}
-        for key in vars(instance):
-            value = getattr(instance, key)
-            key = self.to_safe('ec2_' + key)
-
-            # Handle complex types
-            # state/previous_state changed to properties in boto in https://github.com/boto/boto/commit/a23c379837f698212252720d2af8dec0325c9518
-            if key == 'ec2__state':
-                instance_vars['ec2_state'] = instance.state or ''
-                instance_vars['ec2_state_code'] = instance.state_code
-            elif key == 'ec2__previous_state':
-                instance_vars['ec2_previous_state'] = instance.previous_state or ''
-                instance_vars['ec2_previous_state_code'] = instance.previous_state_code
-            elif type(value) in [int, bool]:
-                instance_vars[key] = value
-            elif isinstance(value, six.string_types):
-                instance_vars[key] = value.strip()
-            elif type(value) == type(None):
-                instance_vars[key] = ''
-            elif key == 'ec2_region':
-                instance_vars[key] = value.name
-            elif key == 'ec2__placement':
-                instance_vars['ec2_placement'] = value.zone
-            elif key == 'ec2_tags':
-                for k, v in value.items():
-                    if self.expand_csv_tags and ',' in v:
-                        v = map(lambda x: x.strip(), v.split(','))
-                    key = self.to_safe('ec2_tag_' + k)
-                    instance_vars[key] = v
-            elif key == 'ec2_groups':
-                group_ids = []
-                group_names = []
-                for group in value:
-                    group_ids.append(group.id)
-                    group_names.append(group.name)
-                instance_vars["ec2_security_group_ids"] = ','.join([str(i) for i in group_ids])
-                instance_vars["ec2_security_group_names"] = ','.join([str(i) for i in group_names])
-            else:
-                pass
-                # TODO Product codes if someone finds them useful
-                #print key
-                #print type(value)
-                #print value
-
-        return instance_vars
-
-    def get_host_info_dict_from_describe_dict(self, describe_dict):
-        ''' Parses the dictionary returned by the API call into a flat list
-            of parameters. This method should be used only when 'describe' is
-            used directly because Boto doesn't provide specific classes. '''
-
-        # I really don't agree with prefixing everything with 'ec2'
-        # because EC2, RDS and ElastiCache are different services.
-        # I'm just following the pattern used until now to not break any
-        # compatibility.
-
-        host_info = {}
-        for key in describe_dict:
-            value = describe_dict[key]
-            key = self.to_safe('ec2_' + self.uncammelize(key))
-
-            # Handle complex types
-
-            # Target: Memcached Cache Clusters
-            if key == 'ec2_configuration_endpoint' and value:
-                host_info['ec2_configuration_endpoint_address'] = value['Address']
-                host_info['ec2_configuration_endpoint_port'] = value['Port']
-
-            # Target: Cache Nodes and Redis Cache Clusters (single node)
-            if key == 'ec2_endpoint' and value:
-                host_info['ec2_endpoint_address'] = value['Address']
-                host_info['ec2_endpoint_port'] = value['Port']
-
-            # Target: Redis Replication Groups
-            if key == 'ec2_node_groups' and value:
-                host_info['ec2_endpoint_address'] = value[0]['PrimaryEndpoint']['Address']
-                host_info['ec2_endpoint_port'] = value[0]['PrimaryEndpoint']['Port']
-                replica_count = 0
-                for node in value[0]['NodeGroupMembers']:
-                    if node['CurrentRole'] == 'primary':
-                        host_info['ec2_primary_cluster_address'] = node['ReadEndpoint']['Address']
-                        host_info['ec2_primary_cluster_port'] = node['ReadEndpoint']['Port']
-                        host_info['ec2_primary_cluster_id'] = node['CacheClusterId']
-                    elif node['CurrentRole'] == 'replica':
-                        host_info['ec2_replica_cluster_address_'+ str(replica_count)] = node['ReadEndpoint']['Address']
-                        host_info['ec2_replica_cluster_port_'+ str(replica_count)] = node['ReadEndpoint']['Port']
-                        host_info['ec2_replica_cluster_id_'+ str(replica_count)] = node['CacheClusterId']
-                        replica_count += 1
-
-            # Target: Redis Replication Groups
-            if key == 'ec2_member_clusters' and value:
-                host_info['ec2_member_clusters'] = ','.join([str(i) for i in value])
-
-            # Target: All Cache Clusters
-            elif key == 'ec2_cache_parameter_group':
-                host_info["ec2_cache_node_ids_to_reboot"] = ','.join([str(i) for i in value['CacheNodeIdsToReboot']])
-                host_info['ec2_cache_parameter_group_name'] = value['CacheParameterGroupName']
-                host_info['ec2_cache_parameter_apply_status'] = value['ParameterApplyStatus']
-
-            # Target: Almost everything
-            elif key == 'ec2_security_groups':
-
-                # Skip if SecurityGroups is None
-                # (it is possible to have the key defined but no value in it).
-                if value is not None:
-                    sg_ids = []
-                    for sg in value:
-                        sg_ids.append(sg['SecurityGroupId'])
-                    host_info["ec2_security_group_ids"] = ','.join([str(i) for i in sg_ids])
-
-            # Target: Everything
-            # Preserve booleans and integers
-            elif type(value) in [int, bool]:
-                host_info[key] = value
-
-            # Target: Everything
-            # Sanitize string values
-            elif isinstance(value, six.string_types):
-                host_info[key] = value.strip()
-
-            # Target: Everything
-            # Replace None by an empty string
-            elif type(value) == type(None):
-                host_info[key] = ''
-
-            else:
-                # Remove non-processed complex types
-                pass
-
-        return host_info
-
-    def get_host_info(self):
-        ''' Get variables about a specific host '''
-
-        if len(self.index) == 0:
-            # Need to load index from cache
-            self.load_index_from_cache()
-
-        if not self.args.host in self.index:
-            # try updating the cache
-            self.do_api_calls_update_cache()
-            if not self.args.host in self.index:
-                # host might not exist anymore
-                return self.json_format_dict({}, True)
-
-        (region, instance_id) = self.index[self.args.host]
-
-        instance = self.get_instance(region, instance_id)
-        return self.json_format_dict(self.get_host_info_dict_from_instance(instance), True)
-
-    def push(self, my_dict, key, element):
-        ''' Push an element onto an array that may not have been defined in
-        the dict '''
-        group_info = my_dict.setdefault(key, [])
-        if isinstance(group_info, dict):
-            host_list = group_info.setdefault('hosts', [])
-            host_list.append(element)
-        else:
-            group_info.append(element)
-
-    def push_group(self, my_dict, key, element):
-        ''' Push a group as a child of another group. '''
-        parent_group = my_dict.setdefault(key, {})
-        if not isinstance(parent_group, dict):
-            parent_group = my_dict[key] = {'hosts': parent_group}
-        child_groups = parent_group.setdefault('children', [])
-        if element not in child_groups:
-            child_groups.append(element)
-
-    def get_inventory_from_cache(self):
-        ''' Reads the inventory from the cache file and returns it as a JSON
-        object '''
-
-        cache = open(self.cache_path_cache, 'r')
-        json_inventory = cache.read()
-        return json_inventory
-
-
-    def load_index_from_cache(self):
-        ''' Reads the index from the cache file sets self.index '''
-
-        cache = open(self.cache_path_index, 'r')
-        json_index = cache.read()
-        self.index = json.loads(json_index)
-
-
-    def write_to_cache(self, data, filename):
-        ''' Writes data in JSON format to a file '''
-
-        json_data = self.json_format_dict(data, True)
-        cache = open(filename, 'w')
-        cache.write(json_data)
-        cache.close()
-
-    def uncammelize(self, key):
-        temp = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', key)
-        return re.sub('([a-z0-9])([A-Z])', r'\1_\2', temp).lower()
-
-    def to_safe(self, word):
-        ''' Converts 'bad' characters in a string to underscores so they can be used as Ansible groups '''
-        regex = "[^A-Za-z0-9\_"
-        if not self.replace_dash_in_groups:
-            regex += "\-"
-        return re.sub(regex + "]", "_", word)
-
-    def json_format_dict(self, data, pretty=False):
-        ''' Converts a dict to a JSON object and dumps it as a formatted
-        string '''
-
-        if pretty:
-            return json.dumps(data, sort_keys=True, indent=2)
-        else:
-            return json.dumps(data)
-
-
-# Run the script
-Ec2Inventory()
diff --git a/edge-1701-dc7/inventory b/edge-1701-dc7/inventory
deleted file mode 100644
index 21862f9..0000000
--- a/edge-1701-dc7/inventory
+++ /dev/null
@@ -1,84 +0,0 @@
-[tag_Name_dc7_n1]
-[tag_Name_dc7_n2]
-[tag_Name_dc7_n3]
-[tag_Name_dc7_n4]
-[tag_Name_dc7_n5]
-[tag_Name_dc7_n6]
-[tag_Name_dc7_n7]
-[tag_Name_dc7_n8]
-[tag_Name_dc7_n9]
-[tag_Name_dc7_n10]
-
-[planet:children]
-dc-1
-
-[dc-1:children]
-tag_Name_dc7_n1
-tag_Name_dc7_n2
-tag_Name_dc7_n3
-tag_Name_dc7_n4
-tag_Name_dc7_n5
-tag_Name_dc7_n6
-tag_Name_dc7_n7
-tag_Name_dc7_n8
-tag_Name_dc7_n9
-tag_Name_dc7_n10
-
-[ds:children]
-dc-1-ds
-
-[dc-1-ds:children]
-tag_Name_dc7_n1
-tag_Name_dc7_n2
-tag_Name_dc7_n3
-
-[ms:children]
-dc-1-ms
-
-[dc-1-ms:children]
-tag_Name_dc7_n4
-
-[ui:children]
-dc-1-ui
-
-[dc-1-ui:children]
-tag_Name_dc7_n4
-
-[ldap:children]
-dc-1-ldap
-
-[dc-1-ldap:children]
-tag_Name_dc7_n4
-
-[rmp:children]
-dc-1-rmp
-
-[dc-1-rmp:children]
-tag_Name_dc7_n5
-tag_Name_dc7_n6
-
-[qpid:children]
-dc-1-qpid
-
-[dc-1-qpid:children]
-tag_Name_dc7_n7
-tag_Name_dc7_n8
-
-[pg:children]
-dc-1-pg
-
-[dc-1-pg:children]
-dc-1-pgmaster
-dc-1-pgstandby
-
-[pgmaster:children]
-dc-1-pgmaster
-
-[dc-1-pgmaster:children]
-tag_Name_dc7_n9
-
-[pgstandby:children]
-dc-1-pgstandby
-
-[dc-1-pgstandby:children]
-tag_Name_dc7_n10
diff --git a/edge-baas-portal-1701-dc7/ec2.ini b/edge-baas-portal-1701-dc7/ec2.ini
deleted file mode 100644
index 36b3921..0000000
--- a/edge-baas-portal-1701-dc7/ec2.ini
+++ /dev/null
@@ -1,200 +0,0 @@
-# Ansible EC2 external inventory script settings
-#
-
-[ec2]
-
-# to talk to a private eucalyptus instance uncomment these lines
-# and edit edit eucalyptus_host to be the host name of your cloud controller
-#eucalyptus = True
-#eucalyptus_host = clc.cloud.domain.org
-
-# AWS regions to make calls to. Set this to 'all' to make request to all regions
-# in AWS and merge the results together. Alternatively, set this to a comma
-# separated list of regions. E.g. 'us-east-1,us-west-1,us-west-2'
-regions = all
-regions_exclude = us-gov-west-1,cn-north-1
-
-# When generating inventory, Ansible needs to know how to address a server.
-# Each EC2 instance has a lot of variables associated with it. Here is the list:
-#   http://docs.pythonboto.org/en/latest/ref/ec2.html#module-boto.ec2.instance
-# Below are 2 variables that are used as the address of a server:
-#   - destination_variable
-#   - vpc_destination_variable
-
-# This is the normal destination variable to use. If you are running Ansible
-# from outside EC2, then 'public_dns_name' makes the most sense. If you are
-# running Ansible from within EC2, then perhaps you want to use the internal
-# address, and should set this to 'private_dns_name'. The key of an EC2 tag
-# may optionally be used; however the boto instance variables hold precedence
-# in the event of a collision.
-destination_variable = public_dns_name
-
-# This allows you to override the inventory_name with an ec2 variable, instead
-# of using the destination_variable above. Addressing (aka ansible_ssh_host)
-# will still use destination_variable. Tags should be written as 'tag_TAGNAME'.
-#hostname_variable = tag_Name
-
-# For server inside a VPC, using DNS names may not make sense. When an instance
-# has 'subnet_id' set, this variable is used. If the subnet is public, setting
-# this to 'ip_address' will return the public IP address. For instances in a
-# private subnet, this should be set to 'private_ip_address', and Ansible must
-# be run from within EC2. The key of an EC2 tag may optionally be used; however
-# the boto instance variables hold precedence in the event of a collision.
-# WARNING: - instances that are in the private vpc, _without_ public ip address
-# will not be listed in the inventory until You set:
-# vpc_destination_variable = private_ip_address
-vpc_destination_variable = ip_address
-
-# The following two settings allow flexible ansible host naming based on a
-# python format string and a comma-separated list of ec2 tags.  Note that:
-#
-# 1) If the tags referenced are not present for some instances, empty strings
-#    will be substituted in the format string.
-# 2) This overrides both destination_variable and vpc_destination_variable.
-#
-#destination_format = {0}.{1}.example.com
-#destination_format_tags = Name,environment
-
-# To tag instances on EC2 with the resource records that point to them from
-# Route53, uncomment and set 'route53' to True.
-route53 = False
-
-# To exclude RDS instances from the inventory, uncomment and set to False.
-rds = False
-
-# To exclude ElastiCache instances from the inventory, uncomment and set to False.
-elasticache = False
-
-# Additionally, you can specify the list of zones to exclude looking up in
-# 'route53_excluded_zones' as a comma-separated list.
-# route53_excluded_zones = samplezone1.com, samplezone2.com
-
-# By default, only EC2 instances in the 'running' state are returned. Set
-# 'all_instances' to True to return all instances regardless of state.
-all_instances = True
-
-# By default, only EC2 instances in the 'running' state are returned. Specify
-# EC2 instance states to return as a comma-separated list. This
-# option is overriden when 'all_instances' is True.
-# instance_states = pending, running, shutting-down, terminated, stopping, stopped
-
-# By default, only RDS instances in the 'available' state are returned.  Set
-# 'all_rds_instances' to True return all RDS instances regardless of state.
-all_rds_instances = False
-
-# By default, only ElastiCache clusters and nodes in the 'available' state
-# are returned. Set 'all_elasticache_clusters' and/or 'all_elastic_nodes'
-# to True return all ElastiCache clusters and nodes, regardless of state.
-#
-# Note that all_elasticache_nodes only applies to listed clusters. That means
-# if you set all_elastic_clusters to false, no node will be return from
-# unavailable clusters, regardless of the state and to what you set for
-# all_elasticache_nodes.
-all_elasticache_replication_groups = False
-all_elasticache_clusters = False
-all_elasticache_nodes = False
-
-# API calls to EC2 are slow. For this reason, we cache the results of an API
-# call. Set this to the path you want cache files to be written to. Two files
-# will be written to this directory:
-#   - ansible-ec2.cache
-#   - ansible-ec2.index
-cache_path = ~/.ansible/tmp
-
-# The number of seconds a cache file is considered valid. After this many
-# seconds, a new API call will be made, and the cache file will be updated.
-# To disable the cache, set this value to 0
-cache_max_age = 300
-
-# Organize groups into a nested/hierarchy instead of a flat namespace.
-nested_groups = False
-
-# Replace - tags when creating groups to avoid issues with ansible
-replace_dash_in_groups = True
-
-# If set to true, any tag of the form "a,b,c" is expanded into a list
-# and the results are used to create additional tag_* inventory groups.
-expand_csv_tags = False
-
-# The EC2 inventory output can become very large. To manage its size,
-# configure which groups should be created.
-group_by_instance_id = True
-group_by_region = True
-group_by_availability_zone = True
-group_by_ami_id = True
-group_by_instance_type = True
-group_by_key_pair = True
-group_by_vpc_id = True
-group_by_security_group = True
-group_by_tag_keys = True
-group_by_tag_none = True
-group_by_route53_names = True
-group_by_rds_engine = False
-group_by_rds_parameter_group = False
-group_by_elasticache_engine = True
-group_by_elasticache_cluster = True
-group_by_elasticache_parameter_group = True
-group_by_elasticache_replication_group = True
-
-# If you only want to include hosts that match a certain regular expression
-# pattern_include = staging-*
-
-# If you want to exclude any hosts that match a certain regular expression
-# pattern_exclude = staging-*
-# Ansible EC2 external inventory script settings
-#
-
-##[ec2]
-##
-### to talk to a private eucalyptus instance uncomment these lines
-### and edit edit eucalyptus_host to be the host name of your cloud controller
-###eucalyptus = True
-###eucalyptus_host = clc.cloud.domain.org
-##
-### AWS regions to make calls to. Set this to 'all' to make request to all regions
-##
-### in AWS and merge the results together. Alternatively, set this to a comma
-### separated list of regions. E.g. 'us-east-1,us-west-1,us-west-2'
-##regions = all
-##regions_exclude = us-gov-west-1,cn-north-1
-##
-### When generating inventory, Ansible needs to know how to address a server.
-### Each EC2 instance has a lot of variables associated with it. Here is the list:
-###   http://docs.pythonboto.org/en/latest/ref/ec2.html#module-boto.ec2.instance
-### Below are 2 variables that are used as the address of a server:
-###   - destination_variable
-###   - vpc_destination_variable
-##
-### This is the normal destination variable to use. If you are running Ansible
-### from outside EC2, then 'public_dns_name' makes the most sense. If you are
-### running Ansible from within EC2, then perhaps you want to use the internal
-### address, and should set this to 'private_dns_name'. The key of an EC2 tag
-##...skipping...
-### pattern_include = staging-*
-##
-### If you want to exclude any hosts that match a certain regular expression
-### pattern_exclude = staging-*
-
-# Instance filters can be used to control which instances are retrieved for
-# inventory. For the full list of possible filters, please read the EC2 API
-# docs: http://docs.aws.amazon.com/AWSEC2/latest/APIReference/ApiReference-query-DescribeInstances.html#query-DescribeInstances-filters
-# Filters are key/value pairs separated by '=', to list multiple filters use
-# a list separated by commas. See examples below.
-
-# Retrieve only instances with (key=value) env=staging tag
-# instance_filters = tag:env=staging
-
-# Retrieve only instances with role=webservers OR role=dbservers tag
-# instance_filters = tag:role=webservers,tag:role=dbservers
-
-# Retrieve only t1.micro instances OR instances with tag env=staging
-# instance_filters = instance-type=t1.micro,tag:env=staging
-
-# You can use wildcards in filter values also. Below will list instances which
-# tag Name value matches webservers1*
-# (ex. webservers15, webservers1a, webservers123 etc)
-# instance_filters = tag:Name=webservers1*
-
-# A boto configuration profile may be used to separate out credentials
-# see http://boto.readthedocs.org/en/latest/boto_config_tut.html
-# boto_profile = some-boto-profile-name
diff --git a/edge-baas-portal-1701-dc7/ec2.py b/edge-baas-portal-1701-dc7/ec2.py
deleted file mode 100755
index f30958a..0000000
--- a/edge-baas-portal-1701-dc7/ec2.py
+++ /dev/null
@@ -1,1385 +0,0 @@
-#!/usr/bin/env python
-
-'''
-EC2 external inventory script
-=================================
-
-Generates inventory that Ansible can understand by making API request to
-AWS EC2 using the Boto library.
-
-NOTE: This script assumes Ansible is being executed where the environment
-variables needed for Boto have already been set:
-    export AWS_ACCESS_KEY_ID='AK123'
-    export AWS_SECRET_ACCESS_KEY='abc123'
-
-This script also assumes there is an ec2.ini file alongside it.  To specify a
-different path to ec2.ini, define the EC2_INI_PATH environment variable:
-
-    export EC2_INI_PATH=/path/to/my_ec2.ini
-
-If you're using eucalyptus you need to set the above variables and
-you need to define:
-
-    export EC2_URL=http://hostname_of_your_cc:port/services/Eucalyptus
-
-If you're using boto profiles (requires boto>=2.24.0) you can choose a profile
-using the --boto-profile command line argument (e.g. ec2.py --boto-profile prod) or using
-the AWS_PROFILE variable:
-
-    AWS_PROFILE=prod ansible-playbook -i ec2.py myplaybook.yml
-
-For more details, see: http://docs.pythonboto.org/en/latest/boto_config_tut.html
-
-When run against a specific host, this script returns the following variables:
- - ec2_ami_launch_index
- - ec2_architecture
- - ec2_association
- - ec2_attachTime
- - ec2_attachment
- - ec2_attachmentId
- - ec2_client_token
- - ec2_deleteOnTermination
- - ec2_description
- - ec2_deviceIndex
- - ec2_dns_name
- - ec2_eventsSet
- - ec2_group_name
- - ec2_hypervisor
- - ec2_id
- - ec2_image_id
- - ec2_instanceState
- - ec2_instance_type
- - ec2_ipOwnerId
- - ec2_ip_address
- - ec2_item
- - ec2_kernel
- - ec2_key_name
- - ec2_launch_time
- - ec2_monitored
- - ec2_monitoring
- - ec2_networkInterfaceId
- - ec2_ownerId
- - ec2_persistent
- - ec2_placement
- - ec2_platform
- - ec2_previous_state
- - ec2_private_dns_name
- - ec2_private_ip_address
- - ec2_publicIp
- - ec2_public_dns_name
- - ec2_ramdisk
- - ec2_reason
- - ec2_region
- - ec2_requester_id
- - ec2_root_device_name
- - ec2_root_device_type
- - ec2_security_group_ids
- - ec2_security_group_names
- - ec2_shutdown_state
- - ec2_sourceDestCheck
- - ec2_spot_instance_request_id
- - ec2_state
- - ec2_state_code
- - ec2_state_reason
- - ec2_status
- - ec2_subnet_id
- - ec2_tenancy
- - ec2_virtualization_type
- - ec2_vpc_id
-
-These variables are pulled out of a boto.ec2.instance object. There is a lack of
-consistency with variable spellings (camelCase and underscores) since this
-just loops through all variables the object exposes. It is preferred to use the
-ones with underscores when multiple exist.
-
-In addition, if an instance has AWS Tags associated with it, each tag is a new
-variable named:
- - ec2_tag_[Key] = [Value]
-
-Security groups are comma-separated in 'ec2_security_group_ids' and
-'ec2_security_group_names'.
-'''
-
-# (c) 2012, Peter Sankauskas
-#
-# This file is part of Ansible,
-#
-# Ansible is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# Ansible is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with Ansible.  If not, see <http://www.gnu.org/licenses/>.
-
-######################################################################
-
-import sys
-import os
-import argparse
-import re
-from time import time
-import boto
-from boto import ec2
-from boto import rds
-from boto import elasticache
-from boto import route53
-import six
-
-from six.moves import configparser
-from collections import defaultdict
-
-try:
-    import json
-except ImportError:
-    import simplejson as json
-
-
-class Ec2Inventory(object):
-
-    def _empty_inventory(self):
-        return {"_meta" : {"hostvars" : {}}}
-
-    def __init__(self):
-        ''' Main execution path '''
-
-        # Inventory grouped by instance IDs, tags, security groups, regions,
-        # and availability zones
-        self.inventory = self._empty_inventory()
-
-        # Index of hostname (address) to instance ID
-        self.index = {}
-
-        # Boto profile to use (if any)
-        self.boto_profile = None
-
-        # Read settings and parse CLI arguments
-        self.parse_cli_args()
-        self.read_settings()
-
-        # Make sure that profile_name is not passed at all if not set
-        # as pre 2.24 boto will fall over otherwise
-        if self.boto_profile:
-            if not hasattr(boto.ec2.EC2Connection, 'profile_name'):
-                self.fail_with_error("boto version must be >= 2.24 to use profile")
-
-        # Cache
-        if self.args.refresh_cache:
-            self.do_api_calls_update_cache()
-        elif not self.is_cache_valid():
-            self.do_api_calls_update_cache()
-
-        # Data to print
-        if self.args.host:
-            data_to_print = self.get_host_info()
-
-        elif self.args.list:
-            # Display list of instances for inventory
-            if self.inventory == self._empty_inventory():
-                data_to_print = self.get_inventory_from_cache()
-            else:
-                data_to_print = self.json_format_dict(self.inventory, True)
-
-        print(data_to_print)
-
-
-    def is_cache_valid(self):
-        ''' Determines if the cache files have expired, or if it is still valid '''
-
-        if os.path.isfile(self.cache_path_cache):
-            mod_time = os.path.getmtime(self.cache_path_cache)
-            current_time = time()
-            if (mod_time + self.cache_max_age) > current_time:
-                if os.path.isfile(self.cache_path_index):
-                    return True
-
-        return False
-
-
-    def read_settings(self):
-        ''' Reads the settings from the ec2.ini file '''
-        if six.PY3:
-            config = configparser.ConfigParser()
-        else:
-            config = configparser.SafeConfigParser()
-        ec2_default_ini_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'ec2.ini')
-        ec2_ini_path = os.path.expanduser(os.path.expandvars(os.environ.get('EC2_INI_PATH', ec2_default_ini_path)))
-        config.read(ec2_ini_path)
-
-        # is eucalyptus?
-        self.eucalyptus_host = None
-        self.eucalyptus = False
-        if config.has_option('ec2', 'eucalyptus'):
-            self.eucalyptus = config.getboolean('ec2', 'eucalyptus')
-        if self.eucalyptus and config.has_option('ec2', 'eucalyptus_host'):
-            self.eucalyptus_host = config.get('ec2', 'eucalyptus_host')
-
-        # Regions
-        self.regions = []
-        configRegions = config.get('ec2', 'regions')
-        configRegions_exclude = config.get('ec2', 'regions_exclude')
-        if (configRegions == 'all'):
-            if self.eucalyptus_host:
-                self.regions.append(boto.connect_euca(host=self.eucalyptus_host).region.name)
-            else:
-                for regionInfo in ec2.regions():
-                    if regionInfo.name not in configRegions_exclude:
-                        self.regions.append(regionInfo.name)
-        else:
-            self.regions = configRegions.split(",")
-
-        # Destination addresses
-        self.destination_variable = config.get('ec2', 'destination_variable')
-        self.vpc_destination_variable = config.get('ec2', 'vpc_destination_variable')
-
-        if config.has_option('ec2', 'hostname_variable'):
-            self.hostname_variable = config.get('ec2', 'hostname_variable')
-        else:
-            self.hostname_variable = None
-
-        if config.has_option('ec2', 'destination_format') and \
-                config.has_option('ec2', 'destination_format_tags'):
-            self.destination_format = config.get('ec2', 'destination_format')
-            self.destination_format_tags = config.get('ec2', 'destination_format_tags').split(',')
-        else:
-            self.destination_format = None
-            self.destination_format_tags = None
-
-        # Route53
-        self.route53_enabled = config.getboolean('ec2', 'route53')
-        self.route53_excluded_zones = []
-        if config.has_option('ec2', 'route53_excluded_zones'):
-            self.route53_excluded_zones.extend(
-                    config.get('ec2', 'route53_excluded_zones', '').split(','))
-
-        # Include RDS instances?
-        self.rds_enabled = True
-        if config.has_option('ec2', 'rds'):
-            self.rds_enabled = config.getboolean('ec2', 'rds')
-
-        # Include ElastiCache instances?
-        self.elasticache_enabled = True
-        if config.has_option('ec2', 'elasticache'):
-            self.elasticache_enabled = config.getboolean('ec2', 'elasticache')
-
-        # Return all EC2 instances?
-        if config.has_option('ec2', 'all_instances'):
-            self.all_instances = config.getboolean('ec2', 'all_instances')
-        else:
-            self.all_instances = False
-
-        # Instance states to be gathered in inventory. Default is 'running'.
-        # Setting 'all_instances' to 'yes' overrides this option.
-        ec2_valid_instance_states = [
-            'pending',
-            'running',
-            'shutting-down',
-            'terminated',
-            'stopping',
-            'stopped'
-        ]
-        self.ec2_instance_states = []
-        if self.all_instances:
-            self.ec2_instance_states = ec2_valid_instance_states
-        elif config.has_option('ec2', 'instance_states'):
-            for instance_state in config.get('ec2', 'instance_states').split(','):
-                instance_state = instance_state.strip()
-                if instance_state not in ec2_valid_instance_states:
-                    continue
-                self.ec2_instance_states.append(instance_state)
-        else:
-            self.ec2_instance_states = ['running']
-
-        # Return all RDS instances? (if RDS is enabled)
-        if config.has_option('ec2', 'all_rds_instances') and self.rds_enabled:
-            self.all_rds_instances = config.getboolean('ec2', 'all_rds_instances')
-        else:
-            self.all_rds_instances = False
-
-        # Return all ElastiCache replication groups? (if ElastiCache is enabled)
-        if config.has_option('ec2', 'all_elasticache_replication_groups') and self.elasticache_enabled:
-            self.all_elasticache_replication_groups = config.getboolean('ec2', 'all_elasticache_replication_groups')
-        else:
-            self.all_elasticache_replication_groups = False
-
-        # Return all ElastiCache clusters? (if ElastiCache is enabled)
-        if config.has_option('ec2', 'all_elasticache_clusters') and self.elasticache_enabled:
-            self.all_elasticache_clusters = config.getboolean('ec2', 'all_elasticache_clusters')
-        else:
-            self.all_elasticache_clusters = False
-
-        # Return all ElastiCache nodes? (if ElastiCache is enabled)
-        if config.has_option('ec2', 'all_elasticache_nodes') and self.elasticache_enabled:
-            self.all_elasticache_nodes = config.getboolean('ec2', 'all_elasticache_nodes')
-        else:
-            self.all_elasticache_nodes = False
-
-        # boto configuration profile (prefer CLI argument)
-        self.boto_profile = self.args.boto_profile
-        if config.has_option('ec2', 'boto_profile') and not self.boto_profile:
-            self.boto_profile = config.get('ec2', 'boto_profile')
-
-        # Cache related
-        cache_dir = os.path.expanduser(config.get('ec2', 'cache_path'))
-        if self.boto_profile:
-            cache_dir = os.path.join(cache_dir, 'profile_' + self.boto_profile)
-        if not os.path.exists(cache_dir):
-            os.makedirs(cache_dir)
-
-        cache_name = 'ansible-ec2'
-        aws_profile = lambda: (self.boto_profile or
-                               os.environ.get('AWS_PROFILE') or
-                               os.environ.get('AWS_ACCESS_KEY_ID'))
-        if aws_profile():
-            cache_name = '%s-%s' % (cache_name, aws_profile())
-        self.cache_path_cache = cache_dir + "/%s.cache" % cache_name
-        self.cache_path_index = cache_dir + "/%s.index" % cache_name
-        self.cache_max_age = config.getint('ec2', 'cache_max_age')
-
-        if config.has_option('ec2', 'expand_csv_tags'):
-            self.expand_csv_tags = config.getboolean('ec2', 'expand_csv_tags')
-        else:
-            self.expand_csv_tags = False
-
-        # Configure nested groups instead of flat namespace.
-        if config.has_option('ec2', 'nested_groups'):
-            self.nested_groups = config.getboolean('ec2', 'nested_groups')
-        else:
-            self.nested_groups = False
-
-        # Replace dash or not in group names
-        if config.has_option('ec2', 'replace_dash_in_groups'):
-            self.replace_dash_in_groups = config.getboolean('ec2', 'replace_dash_in_groups')
-        else:
-            self.replace_dash_in_groups = True
-
-        # Configure which groups should be created.
-        group_by_options = [
-            'group_by_instance_id',
-            'group_by_region',
-            'group_by_availability_zone',
-            'group_by_ami_id',
-            'group_by_instance_type',
-            'group_by_key_pair',
-            'group_by_vpc_id',
-            'group_by_security_group',
-            'group_by_tag_keys',
-            'group_by_tag_none',
-            'group_by_route53_names',
-            'group_by_rds_engine',
-            'group_by_rds_parameter_group',
-            'group_by_elasticache_engine',
-            'group_by_elasticache_cluster',
-            'group_by_elasticache_parameter_group',
-            'group_by_elasticache_replication_group',
-        ]
-        for option in group_by_options:
-            if config.has_option('ec2', option):
-                setattr(self, option, config.getboolean('ec2', option))
-            else:
-                setattr(self, option, True)
-
-        # Do we need to just include hosts that match a pattern?
-        try:
-            pattern_include = config.get('ec2', 'pattern_include')
-            if pattern_include and len(pattern_include) > 0:
-                self.pattern_include = re.compile(pattern_include)
-            else:
-                self.pattern_include = None
-        except configparser.NoOptionError:
-            self.pattern_include = None
-
-        # Do we need to exclude hosts that match a pattern?
-        try:
-            pattern_exclude = config.get('ec2', 'pattern_exclude');
-            if pattern_exclude and len(pattern_exclude) > 0:
-                self.pattern_exclude = re.compile(pattern_exclude)
-            else:
-                self.pattern_exclude = None
-        except configparser.NoOptionError:
-            self.pattern_exclude = None
-
-        # Instance filters (see boto and EC2 API docs). Ignore invalid filters.
-        self.ec2_instance_filters = defaultdict(list)
-        if config.has_option('ec2', 'instance_filters'):
-
-            filters = [f for f in config.get('ec2', 'instance_filters').split(',') if f]
-
-            for instance_filter in filters:
-                instance_filter = instance_filter.strip()
-                if not instance_filter or '=' not in instance_filter:
-                    continue
-                filter_key, filter_value = [x.strip() for x in instance_filter.split('=', 1)]
-                if not filter_key:
-                    continue
-                self.ec2_instance_filters[filter_key].append(filter_value)
-
-    def parse_cli_args(self):
-        ''' Command line argument processing '''
-
-        parser = argparse.ArgumentParser(description='Produce an Ansible Inventory file based on EC2')
-        parser.add_argument('--list', action='store_true', default=True,
-                            help='List instances (default: True)')
-        parser.add_argument('--host', action='store',
-                            help='Get all the variables about a specific instance')
-        parser.add_argument('--refresh-cache', action='store_true', default=False,
-                            help='Force refresh of cache by making API requests to EC2 (default: False - use cache files)')
-        parser.add_argument('--profile', '--boto-profile', action='store', dest='boto_profile',
-                            help='Use boto profile for connections to EC2')
-        self.args = parser.parse_args()
-
-
-    def do_api_calls_update_cache(self):
-        ''' Do API calls to each region, and save data in cache files '''
-
-        if self.route53_enabled:
-            self.get_route53_records()
-
-        for region in self.regions:
-            self.get_instances_by_region(region)
-            if self.rds_enabled:
-                self.get_rds_instances_by_region(region)
-            if self.elasticache_enabled:
-                self.get_elasticache_clusters_by_region(region)
-                self.get_elasticache_replication_groups_by_region(region)
-
-        self.write_to_cache(self.inventory, self.cache_path_cache)
-        self.write_to_cache(self.index, self.cache_path_index)
-
-    def connect(self, region):
-        ''' create connection to api server'''
-        if self.eucalyptus:
-            conn = boto.connect_euca(host=self.eucalyptus_host)
-            conn.APIVersion = '2010-08-31'
-        else:
-            conn = self.connect_to_aws(ec2, region)
-        return conn
-
-    def boto_fix_security_token_in_profile(self, connect_args):
-        ''' monkey patch for boto issue boto/boto#2100 '''
-        profile = 'profile ' + self.boto_profile
-        if boto.config.has_option(profile, 'aws_security_token'):
-            connect_args['security_token'] = boto.config.get(profile, 'aws_security_token')
-        return connect_args
-
-    def connect_to_aws(self, module, region):
-        connect_args = {}
-
-        # only pass the profile name if it's set (as it is not supported by older boto versions)
-        if self.boto_profile:
-            connect_args['profile_name'] = self.boto_profile
-            self.boto_fix_security_token_in_profile(connect_args)
-
-        conn = module.connect_to_region(region, **connect_args)
-        # connect_to_region will fail "silently" by returning None if the region name is wrong or not supported
-        if conn is None:
-            self.fail_with_error("region name: %s likely not supported, or AWS is down.  connection to region failed." % region)
-        return conn
-
-    def get_instances_by_region(self, region):
-        ''' Makes an AWS EC2 API call to the list of instances in a particular
-        region '''
-
-        try:
-            conn = self.connect(region)
-            reservations = []
-            if self.ec2_instance_filters:
-                for filter_key, filter_values in self.ec2_instance_filters.items():
-                    reservations.extend(conn.get_all_instances(filters = { filter_key : filter_values }))
-            else:
-                reservations = conn.get_all_instances()
-
-            for reservation in reservations:
-                for instance in reservation.instances:
-                    self.add_instance(instance, region)
-
-        except boto.exception.BotoServerError as e:
-            if e.error_code == 'AuthFailure':
-                error = self.get_auth_error_message()
-            else:
-                backend = 'Eucalyptus' if self.eucalyptus else 'AWS'
-                error = "Error connecting to %s backend.\n%s" % (backend, e.message)
-            self.fail_with_error(error, 'getting EC2 instances')
-
-    def get_rds_instances_by_region(self, region):
-        ''' Makes an AWS API call to the list of RDS instances in a particular
-        region '''
-
-        try:
-            conn = self.connect_to_aws(rds, region)
-            if conn:
-                marker = None
-                while True:
-                    instances = conn.get_all_dbinstances(marker=marker)
-                    marker = instances.marker
-                    for instance in instances:
-                        self.add_rds_instance(instance, region)
-                    if not marker:
-                        break
-        except boto.exception.BotoServerError as e:
-            error = e.reason
-
-            if e.error_code == 'AuthFailure':
-                error = self.get_auth_error_message()
-            if not e.reason == "Forbidden":
-                error = "Looks like AWS RDS is down:\n%s" % e.message
-            self.fail_with_error(error, 'getting RDS instances')
-
-    def get_elasticache_clusters_by_region(self, region):
-        ''' Makes an AWS API call to the list of ElastiCache clusters (with
-        nodes' info) in a particular region.'''
-
-        # ElastiCache boto module doesn't provide a get_all_intances method,
-        # that's why we need to call describe directly (it would be called by
-        # the shorthand method anyway...)
-        try:
-            conn = self.connect_to_aws(elasticache, region)
-            if conn:
-                # show_cache_node_info = True
-                # because we also want nodes' information
-                response = conn.describe_cache_clusters(None, None, None, True)
-
-        except boto.exception.BotoServerError as e:
-            error = e.reason
-
-            if e.error_code == 'AuthFailure':
-                error = self.get_auth_error_message()
-            if not e.reason == "Forbidden":
-                error = "Looks like AWS ElastiCache is down:\n%s" % e.message
-            self.fail_with_error(error, 'getting ElastiCache clusters')
-
-        try:
-            # Boto also doesn't provide wrapper classes to CacheClusters or
-            # CacheNodes. Because of that wo can't make use of the get_list
-            # method in the AWSQueryConnection. Let's do the work manually
-            clusters = response['DescribeCacheClustersResponse']['DescribeCacheClustersResult']['CacheClusters']
-
-        except KeyError as e:
-            error = "ElastiCache query to AWS failed (unexpected format)."
-            self.fail_with_error(error, 'getting ElastiCache clusters')
-
-        for cluster in clusters:
-            self.add_elasticache_cluster(cluster, region)
-
-    def get_elasticache_replication_groups_by_region(self, region):
-        ''' Makes an AWS API call to the list of ElastiCache replication groups
-        in a particular region.'''
-
-        # ElastiCache boto module doesn't provide a get_all_intances method,
-        # that's why we need to call describe directly (it would be called by
-        # the shorthand method anyway...)
-        try:
-            conn = self.connect_to_aws(elasticache, region)
-            if conn:
-                response = conn.describe_replication_groups()
-
-        except boto.exception.BotoServerError as e:
-            error = e.reason
-
-            if e.error_code == 'AuthFailure':
-                error = self.get_auth_error_message()
-            if not e.reason == "Forbidden":
-                error = "Looks like AWS ElastiCache [Replication Groups] is down:\n%s" % e.message
-            self.fail_with_error(error, 'getting ElastiCache clusters')
-
-        try:
-            # Boto also doesn't provide wrapper classes to ReplicationGroups
-            # Because of that wo can't make use of the get_list method in the
-            # AWSQueryConnection. Let's do the work manually
-            replication_groups = response['DescribeReplicationGroupsResponse']['DescribeReplicationGroupsResult']['ReplicationGroups']
-
-        except KeyError as e:
-            error = "ElastiCache [Replication Groups] query to AWS failed (unexpected format)."
-            self.fail_with_error(error, 'getting ElastiCache clusters')
-
-        for replication_group in replication_groups:
-            self.add_elasticache_replication_group(replication_group, region)
-
-    def get_auth_error_message(self):
-        ''' create an informative error message if there is an issue authenticating'''
-        errors = ["Authentication error retrieving ec2 inventory."]
-        if None in [os.environ.get('AWS_ACCESS_KEY_ID'), os.environ.get('AWS_SECRET_ACCESS_KEY')]:
-            errors.append(' - No AWS_ACCESS_KEY_ID or AWS_SECRET_ACCESS_KEY environment vars found')
-        else:
-            errors.append(' - AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY environment vars found but may not be correct')
-
-        boto_paths = ['/etc/boto.cfg', '~/.boto', '~/.aws/credentials']
-        boto_config_found = list(p for p in boto_paths if os.path.isfile(os.path.expanduser(p)))
-        if len(boto_config_found) > 0:
-            errors.append(" - Boto configs found at '%s', but the credentials contained may not be correct" % ', '.join(boto_config_found))
-        else:
-            errors.append(" - No Boto config found at any expected location '%s'" % ', '.join(boto_paths))
-
-        return '\n'.join(errors)
-
-    def fail_with_error(self, err_msg, err_operation=None):
-        '''log an error to std err for ansible-playbook to consume and exit'''
-        if err_operation:
-            err_msg = 'ERROR: "{err_msg}", while: {err_operation}'.format(
-                    err_msg=err_msg, err_operation=err_operation)
-        sys.stderr.write(err_msg)
-        sys.exit(1)
-
-    def get_instance(self, region, instance_id):
-        conn = self.connect(region)
-
-        reservations = conn.get_all_instances([instance_id])
-        for reservation in reservations:
-            for instance in reservation.instances:
-                return instance
-
-    def add_instance(self, instance, region):
-        ''' Adds an instance to the inventory and index, as long as it is
-        addressable '''
-
-        # Only return instances with desired instance states
-        if instance.state not in self.ec2_instance_states:
-            return
-
-        # Select the best destination address
-        if self.destination_format and self.destination_format_tags:
-            dest = self.destination_format.format(*[ getattr(instance, 'tags').get(tag, '') for tag in self.destination_format_tags ])
-        elif instance.subnet_id:
-            dest = getattr(instance, self.vpc_destination_variable, None)
-            if dest is None:
-                dest = getattr(instance, 'tags').get(self.vpc_destination_variable, None)
-        else:
-            dest = getattr(instance, self.destination_variable, None)
-            if dest is None:
-                dest = getattr(instance, 'tags').get(self.destination_variable, None)
-
-        if not dest:
-            # Skip instances we cannot address (e.g. private VPC subnet)
-            return
-
-        # Set the inventory name
-        hostname = None
-        if self.hostname_variable:
-            if self.hostname_variable.startswith('tag_'):
-                hostname = instance.tags.get(self.hostname_variable[4:], None)
-            else:
-                hostname = getattr(instance, self.hostname_variable)
-
-        # If we can't get a nice hostname, use the destination address
-        if not hostname:
-            hostname = dest
-        else:
-            hostname = self.to_safe(hostname).lower()
-
-        # if we only want to include hosts that match a pattern, skip those that don't
-        if self.pattern_include and not self.pattern_include.match(hostname):
-            return
-
-        # if we need to exclude hosts that match a pattern, skip those
-        if self.pattern_exclude and self.pattern_exclude.match(hostname):
-            return
-
-        # Add to index
-        self.index[hostname] = [region, instance.id]
-
-        # Inventory: Group by instance ID (always a group of 1)
-        if self.group_by_instance_id:
-            self.inventory[instance.id] = [hostname]
-            if self.nested_groups:
-                self.push_group(self.inventory, 'instances', instance.id)
-
-        # Inventory: Group by region
-        if self.group_by_region:
-            self.push(self.inventory, region, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'regions', region)
-
-        # Inventory: Group by availability zone
-        if self.group_by_availability_zone:
-            self.push(self.inventory, instance.placement, hostname)
-            if self.nested_groups:
-                if self.group_by_region:
-                    self.push_group(self.inventory, region, instance.placement)
-                self.push_group(self.inventory, 'zones', instance.placement)
-
-        # Inventory: Group by Amazon Machine Image (AMI) ID
-        if self.group_by_ami_id:
-            ami_id = self.to_safe(instance.image_id)
-            self.push(self.inventory, ami_id, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'images', ami_id)
-
-        # Inventory: Group by instance type
-        if self.group_by_instance_type:
-            type_name = self.to_safe('type_' + instance.instance_type)
-            self.push(self.inventory, type_name, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'types', type_name)
-
-        # Inventory: Group by key pair
-        if self.group_by_key_pair and instance.key_name:
-            key_name = self.to_safe('key_' + instance.key_name)
-            self.push(self.inventory, key_name, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'keys', key_name)
-
-        # Inventory: Group by VPC
-        if self.group_by_vpc_id and instance.vpc_id:
-            vpc_id_name = self.to_safe('vpc_id_' + instance.vpc_id)
-            self.push(self.inventory, vpc_id_name, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'vpcs', vpc_id_name)
-
-        # Inventory: Group by security group
-        if self.group_by_security_group:
-            try:
-                for group in instance.groups:
-                    key = self.to_safe("security_group_" + group.name)
-                    self.push(self.inventory, key, hostname)
-                    if self.nested_groups:
-                        self.push_group(self.inventory, 'security_groups', key)
-            except AttributeError:
-                self.fail_with_error('\n'.join(['Package boto seems a bit older.',
-                                                'Please upgrade boto >= 2.3.0.']))
-
-        # Inventory: Group by tag keys
-        if self.group_by_tag_keys:
-            for k, v in instance.tags.items():
-                if self.expand_csv_tags and v and ',' in v:
-                    values = map(lambda x: x.strip(), v.split(','))
-                else:
-                    values = [v]
-
-                for v in values:
-                    if v:
-                        key = self.to_safe("tag_" + k + "=" + v)
-                    else:
-                        key = self.to_safe("tag_" + k)
-                    self.push(self.inventory, key, hostname)
-                    if self.nested_groups:
-                        self.push_group(self.inventory, 'tags', self.to_safe("tag_" + k))
-                        if v:
-                            self.push_group(self.inventory, self.to_safe("tag_" + k), key)
-
-        # Inventory: Group by Route53 domain names if enabled
-        if self.route53_enabled and self.group_by_route53_names:
-            route53_names = self.get_instance_route53_names(instance)
-            for name in route53_names:
-                self.push(self.inventory, name, hostname)
-                if self.nested_groups:
-                    self.push_group(self.inventory, 'route53', name)
-
-        # Global Tag: instances without tags
-        if self.group_by_tag_none and len(instance.tags) == 0:
-            self.push(self.inventory, 'tag_none', hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'tags', 'tag_none')
-
-        # Global Tag: tag all EC2 instances
-        self.push(self.inventory, 'ec2', hostname)
-
-        self.inventory["_meta"]["hostvars"][hostname] = self.get_host_info_dict_from_instance(instance)
-        self.inventory["_meta"]["hostvars"][hostname]['ansible_ssh_host'] = dest
-
-
-    def add_rds_instance(self, instance, region):
-        ''' Adds an RDS instance to the inventory and index, as long as it is
-        addressable '''
-
-        # Only want available instances unless all_rds_instances is True
-        if not self.all_rds_instances and instance.status != 'available':
-            return
-
-        # Select the best destination address
-        dest = instance.endpoint[0]
-
-        if not dest:
-            # Skip instances we cannot address (e.g. private VPC subnet)
-            return
-
-        # Set the inventory name
-        hostname = None
-        if self.hostname_variable:
-            if self.hostname_variable.startswith('tag_'):
-                hostname = instance.tags.get(self.hostname_variable[4:], None)
-            else:
-                hostname = getattr(instance, self.hostname_variable)
-
-        # If we can't get a nice hostname, use the destination address
-        if not hostname:
-            hostname = dest
-
-        hostname = self.to_safe(hostname).lower()
-
-        # Add to index
-        self.index[hostname] = [region, instance.id]
-
-        # Inventory: Group by instance ID (always a group of 1)
-        if self.group_by_instance_id:
-            self.inventory[instance.id] = [hostname]
-            if self.nested_groups:
-                self.push_group(self.inventory, 'instances', instance.id)
-
-        # Inventory: Group by region
-        if self.group_by_region:
-            self.push(self.inventory, region, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'regions', region)
-
-        # Inventory: Group by availability zone
-        if self.group_by_availability_zone:
-            self.push(self.inventory, instance.availability_zone, hostname)
-            if self.nested_groups:
-                if self.group_by_region:
-                    self.push_group(self.inventory, region, instance.availability_zone)
-                self.push_group(self.inventory, 'zones', instance.availability_zone)
-
-        # Inventory: Group by instance type
-        if self.group_by_instance_type:
-            type_name = self.to_safe('type_' + instance.instance_class)
-            self.push(self.inventory, type_name, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'types', type_name)
-
-        # Inventory: Group by VPC
-        if self.group_by_vpc_id and instance.subnet_group and instance.subnet_group.vpc_id:
-            vpc_id_name = self.to_safe('vpc_id_' + instance.subnet_group.vpc_id)
-            self.push(self.inventory, vpc_id_name, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'vpcs', vpc_id_name)
-
-        # Inventory: Group by security group
-        if self.group_by_security_group:
-            try:
-                if instance.security_group:
-                    key = self.to_safe("security_group_" + instance.security_group.name)
-                    self.push(self.inventory, key, hostname)
-                    if self.nested_groups:
-                        self.push_group(self.inventory, 'security_groups', key)
-
-            except AttributeError:
-                self.fail_with_error('\n'.join(['Package boto seems a bit older.',
-                                                'Please upgrade boto >= 2.3.0.']))
-
-
-        # Inventory: Group by engine
-        if self.group_by_rds_engine:
-            self.push(self.inventory, self.to_safe("rds_" + instance.engine), hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'rds_engines', self.to_safe("rds_" + instance.engine))
-
-        # Inventory: Group by parameter group
-        if self.group_by_rds_parameter_group:
-            self.push(self.inventory, self.to_safe("rds_parameter_group_" + instance.parameter_group.name), hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'rds_parameter_groups', self.to_safe("rds_parameter_group_" + instance.parameter_group.name))
-
-        # Global Tag: all RDS instances
-        self.push(self.inventory, 'rds', hostname)
-
-        self.inventory["_meta"]["hostvars"][hostname] = self.get_host_info_dict_from_instance(instance)
-        self.inventory["_meta"]["hostvars"][hostname]['ansible_ssh_host'] = dest
-
-    def add_elasticache_cluster(self, cluster, region):
-        ''' Adds an ElastiCache cluster to the inventory and index, as long as
-        it's nodes are addressable '''
-
-        # Only want available clusters unless all_elasticache_clusters is True
-        if not self.all_elasticache_clusters and cluster['CacheClusterStatus'] != 'available':
-            return
-
-        # Select the best destination address
-        if 'ConfigurationEndpoint' in cluster and cluster['ConfigurationEndpoint']:
-            # Memcached cluster
-            dest = cluster['ConfigurationEndpoint']['Address']
-            is_redis = False
-        else:
-            # Redis sigle node cluster
-            # Because all Redis clusters are single nodes, we'll merge the
-            # info from the cluster with info about the node
-            dest = cluster['CacheNodes'][0]['Endpoint']['Address']
-            is_redis = True
-
-        if not dest:
-            # Skip clusters we cannot address (e.g. private VPC subnet)
-            return
-
-        # Add to index
-        self.index[dest] = [region, cluster['CacheClusterId']]
-
-        # Inventory: Group by instance ID (always a group of 1)
-        if self.group_by_instance_id:
-            self.inventory[cluster['CacheClusterId']] = [dest]
-            if self.nested_groups:
-                self.push_group(self.inventory, 'instances', cluster['CacheClusterId'])
-
-        # Inventory: Group by region
-        if self.group_by_region and not is_redis:
-            self.push(self.inventory, region, dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'regions', region)
-
-        # Inventory: Group by availability zone
-        if self.group_by_availability_zone and not is_redis:
-            self.push(self.inventory, cluster['PreferredAvailabilityZone'], dest)
-            if self.nested_groups:
-                if self.group_by_region:
-                    self.push_group(self.inventory, region, cluster['PreferredAvailabilityZone'])
-                self.push_group(self.inventory, 'zones', cluster['PreferredAvailabilityZone'])
-
-        # Inventory: Group by node type
-        if self.group_by_instance_type and not is_redis:
-            type_name = self.to_safe('type_' + cluster['CacheNodeType'])
-            self.push(self.inventory, type_name, dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'types', type_name)
-
-        # Inventory: Group by VPC (information not available in the current
-        # AWS API version for ElastiCache)
-
-        # Inventory: Group by security group
-        if self.group_by_security_group and not is_redis:
-
-            # Check for the existence of the 'SecurityGroups' key and also if
-            # this key has some value. When the cluster is not placed in a SG
-            # the query can return None here and cause an error.
-            if 'SecurityGroups' in cluster and cluster['SecurityGroups'] is not None:
-                for security_group in cluster['SecurityGroups']:
-                    key = self.to_safe("security_group_" + security_group['SecurityGroupId'])
-                    self.push(self.inventory, key, dest)
-                    if self.nested_groups:
-                        self.push_group(self.inventory, 'security_groups', key)
-
-        # Inventory: Group by engine
-        if self.group_by_elasticache_engine and not is_redis:
-            self.push(self.inventory, self.to_safe("elasticache_" + cluster['Engine']), dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'elasticache_engines', self.to_safe(cluster['Engine']))
-
-        # Inventory: Group by parameter group
-        if self.group_by_elasticache_parameter_group:
-            self.push(self.inventory, self.to_safe("elasticache_parameter_group_" + cluster['CacheParameterGroup']['CacheParameterGroupName']), dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'elasticache_parameter_groups', self.to_safe(cluster['CacheParameterGroup']['CacheParameterGroupName']))
-
-        # Inventory: Group by replication group
-        if self.group_by_elasticache_replication_group and 'ReplicationGroupId' in cluster and cluster['ReplicationGroupId']:
-            self.push(self.inventory, self.to_safe("elasticache_replication_group_" + cluster['ReplicationGroupId']), dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'elasticache_replication_groups', self.to_safe(cluster['ReplicationGroupId']))
-
-        # Global Tag: all ElastiCache clusters
-        self.push(self.inventory, 'elasticache_clusters', cluster['CacheClusterId'])
-
-        host_info = self.get_host_info_dict_from_describe_dict(cluster)
-
-        self.inventory["_meta"]["hostvars"][dest] = host_info
-
-        # Add the nodes
-        for node in cluster['CacheNodes']:
-            self.add_elasticache_node(node, cluster, region)
-
-    def add_elasticache_node(self, node, cluster, region):
-        ''' Adds an ElastiCache node to the inventory and index, as long as
-        it is addressable '''
-
-        # Only want available nodes unless all_elasticache_nodes is True
-        if not self.all_elasticache_nodes and node['CacheNodeStatus'] != 'available':
-            return
-
-        # Select the best destination address
-        dest = node['Endpoint']['Address']
-
-        if not dest:
-            # Skip nodes we cannot address (e.g. private VPC subnet)
-            return
-
-        node_id = self.to_safe(cluster['CacheClusterId'] + '_' + node['CacheNodeId'])
-
-        # Add to index
-        self.index[dest] = [region, node_id]
-
-        # Inventory: Group by node ID (always a group of 1)
-        if self.group_by_instance_id:
-            self.inventory[node_id] = [dest]
-            if self.nested_groups:
-                self.push_group(self.inventory, 'instances', node_id)
-
-        # Inventory: Group by region
-        if self.group_by_region:
-            self.push(self.inventory, region, dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'regions', region)
-
-        # Inventory: Group by availability zone
-        if self.group_by_availability_zone:
-            self.push(self.inventory, cluster['PreferredAvailabilityZone'], dest)
-            if self.nested_groups:
-                if self.group_by_region:
-                    self.push_group(self.inventory, region, cluster['PreferredAvailabilityZone'])
-                self.push_group(self.inventory, 'zones', cluster['PreferredAvailabilityZone'])
-
-        # Inventory: Group by node type
-        if self.group_by_instance_type:
-            type_name = self.to_safe('type_' + cluster['CacheNodeType'])
-            self.push(self.inventory, type_name, dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'types', type_name)
-
-        # Inventory: Group by VPC (information not available in the current
-        # AWS API version for ElastiCache)
-
-        # Inventory: Group by security group
-        if self.group_by_security_group:
-
-            # Check for the existence of the 'SecurityGroups' key and also if
-            # this key has some value. When the cluster is not placed in a SG
-            # the query can return None here and cause an error.
-            if 'SecurityGroups' in cluster and cluster['SecurityGroups'] is not None:
-                for security_group in cluster['SecurityGroups']:
-                    key = self.to_safe("security_group_" + security_group['SecurityGroupId'])
-                    self.push(self.inventory, key, dest)
-                    if self.nested_groups:
-                        self.push_group(self.inventory, 'security_groups', key)
-
-        # Inventory: Group by engine
-        if self.group_by_elasticache_engine:
-            self.push(self.inventory, self.to_safe("elasticache_" + cluster['Engine']), dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'elasticache_engines', self.to_safe("elasticache_" + cluster['Engine']))
-
-        # Inventory: Group by parameter group (done at cluster level)
-
-        # Inventory: Group by replication group (done at cluster level)
-
-        # Inventory: Group by ElastiCache Cluster
-        if self.group_by_elasticache_cluster:
-            self.push(self.inventory, self.to_safe("elasticache_cluster_" + cluster['CacheClusterId']), dest)
-
-        # Global Tag: all ElastiCache nodes
-        self.push(self.inventory, 'elasticache_nodes', dest)
-
-        host_info = self.get_host_info_dict_from_describe_dict(node)
-
-        if dest in self.inventory["_meta"]["hostvars"]:
-            self.inventory["_meta"]["hostvars"][dest].update(host_info)
-        else:
-            self.inventory["_meta"]["hostvars"][dest] = host_info
-
-    def add_elasticache_replication_group(self, replication_group, region):
-        ''' Adds an ElastiCache replication group to the inventory and index '''
-
-        # Only want available clusters unless all_elasticache_replication_groups is True
-        if not self.all_elasticache_replication_groups and replication_group['Status'] != 'available':
-            return
-
-        # Select the best destination address (PrimaryEndpoint)
-        dest = replication_group['NodeGroups'][0]['PrimaryEndpoint']['Address']
-
-        if not dest:
-            # Skip clusters we cannot address (e.g. private VPC subnet)
-            return
-
-        # Add to index
-        self.index[dest] = [region, replication_group['ReplicationGroupId']]
-
-        # Inventory: Group by ID (always a group of 1)
-        if self.group_by_instance_id:
-            self.inventory[replication_group['ReplicationGroupId']] = [dest]
-            if self.nested_groups:
-                self.push_group(self.inventory, 'instances', replication_group['ReplicationGroupId'])
-
-        # Inventory: Group by region
-        if self.group_by_region:
-            self.push(self.inventory, region, dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'regions', region)
-
-        # Inventory: Group by availability zone (doesn't apply to replication groups)
-
-        # Inventory: Group by node type (doesn't apply to replication groups)
-
-        # Inventory: Group by VPC (information not available in the current
-        # AWS API version for replication groups
-
-        # Inventory: Group by security group (doesn't apply to replication groups)
-        # Check this value in cluster level
-
-        # Inventory: Group by engine (replication groups are always Redis)
-        if self.group_by_elasticache_engine:
-            self.push(self.inventory, 'elasticache_redis', dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'elasticache_engines', 'redis')
-
-        # Global Tag: all ElastiCache clusters
-        self.push(self.inventory, 'elasticache_replication_groups', replication_group['ReplicationGroupId'])
-
-        host_info = self.get_host_info_dict_from_describe_dict(replication_group)
-
-        self.inventory["_meta"]["hostvars"][dest] = host_info
-
-    def get_route53_records(self):
-        ''' Get and store the map of resource records to domain names that
-        point to them. '''
-
-        r53_conn = route53.Route53Connection()
-        all_zones = r53_conn.get_zones()
-
-        route53_zones = [ zone for zone in all_zones if zone.name[:-1]
-                          not in self.route53_excluded_zones ]
-
-        self.route53_records = {}
-
-        for zone in route53_zones:
-            rrsets = r53_conn.get_all_rrsets(zone.id)
-
-            for record_set in rrsets:
-                record_name = record_set.name
-
-                if record_name.endswith('.'):
-                    record_name = record_name[:-1]
-
-                for resource in record_set.resource_records:
-                    self.route53_records.setdefault(resource, set())
-                    self.route53_records[resource].add(record_name)
-
-
-    def get_instance_route53_names(self, instance):
-        ''' Check if an instance is referenced in the records we have from
-        Route53. If it is, return the list of domain names pointing to said
-        instance. If nothing points to it, return an empty list. '''
-
-        instance_attributes = [ 'public_dns_name', 'private_dns_name',
-                                'ip_address', 'private_ip_address' ]
-
-        name_list = set()
-
-        for attrib in instance_attributes:
-            try:
-                value = getattr(instance, attrib)
-            except AttributeError:
-                continue
-
-            if value in self.route53_records:
-                name_list.update(self.route53_records[value])
-
-        return list(name_list)
-
-    def get_host_info_dict_from_instance(self, instance):
-        instance_vars = {}
-        for key in vars(instance):
-            value = getattr(instance, key)
-            key = self.to_safe('ec2_' + key)
-
-            # Handle complex types
-            # state/previous_state changed to properties in boto in https://github.com/boto/boto/commit/a23c379837f698212252720d2af8dec0325c9518
-            if key == 'ec2__state':
-                instance_vars['ec2_state'] = instance.state or ''
-                instance_vars['ec2_state_code'] = instance.state_code
-            elif key == 'ec2__previous_state':
-                instance_vars['ec2_previous_state'] = instance.previous_state or ''
-                instance_vars['ec2_previous_state_code'] = instance.previous_state_code
-            elif type(value) in [int, bool]:
-                instance_vars[key] = value
-            elif isinstance(value, six.string_types):
-                instance_vars[key] = value.strip()
-            elif type(value) == type(None):
-                instance_vars[key] = ''
-            elif key == 'ec2_region':
-                instance_vars[key] = value.name
-            elif key == 'ec2__placement':
-                instance_vars['ec2_placement'] = value.zone
-            elif key == 'ec2_tags':
-                for k, v in value.items():
-                    if self.expand_csv_tags and ',' in v:
-                        v = map(lambda x: x.strip(), v.split(','))
-                    key = self.to_safe('ec2_tag_' + k)
-                    instance_vars[key] = v
-            elif key == 'ec2_groups':
-                group_ids = []
-                group_names = []
-                for group in value:
-                    group_ids.append(group.id)
-                    group_names.append(group.name)
-                instance_vars["ec2_security_group_ids"] = ','.join([str(i) for i in group_ids])
-                instance_vars["ec2_security_group_names"] = ','.join([str(i) for i in group_names])
-            else:
-                pass
-                # TODO Product codes if someone finds them useful
-                #print key
-                #print type(value)
-                #print value
-
-        return instance_vars
-
-    def get_host_info_dict_from_describe_dict(self, describe_dict):
-        ''' Parses the dictionary returned by the API call into a flat list
-            of parameters. This method should be used only when 'describe' is
-            used directly because Boto doesn't provide specific classes. '''
-
-        # I really don't agree with prefixing everything with 'ec2'
-        # because EC2, RDS and ElastiCache are different services.
-        # I'm just following the pattern used until now to not break any
-        # compatibility.
-
-        host_info = {}
-        for key in describe_dict:
-            value = describe_dict[key]
-            key = self.to_safe('ec2_' + self.uncammelize(key))
-
-            # Handle complex types
-
-            # Target: Memcached Cache Clusters
-            if key == 'ec2_configuration_endpoint' and value:
-                host_info['ec2_configuration_endpoint_address'] = value['Address']
-                host_info['ec2_configuration_endpoint_port'] = value['Port']
-
-            # Target: Cache Nodes and Redis Cache Clusters (single node)
-            if key == 'ec2_endpoint' and value:
-                host_info['ec2_endpoint_address'] = value['Address']
-                host_info['ec2_endpoint_port'] = value['Port']
-
-            # Target: Redis Replication Groups
-            if key == 'ec2_node_groups' and value:
-                host_info['ec2_endpoint_address'] = value[0]['PrimaryEndpoint']['Address']
-                host_info['ec2_endpoint_port'] = value[0]['PrimaryEndpoint']['Port']
-                replica_count = 0
-                for node in value[0]['NodeGroupMembers']:
-                    if node['CurrentRole'] == 'primary':
-                        host_info['ec2_primary_cluster_address'] = node['ReadEndpoint']['Address']
-                        host_info['ec2_primary_cluster_port'] = node['ReadEndpoint']['Port']
-                        host_info['ec2_primary_cluster_id'] = node['CacheClusterId']
-                    elif node['CurrentRole'] == 'replica':
-                        host_info['ec2_replica_cluster_address_'+ str(replica_count)] = node['ReadEndpoint']['Address']
-                        host_info['ec2_replica_cluster_port_'+ str(replica_count)] = node['ReadEndpoint']['Port']
-                        host_info['ec2_replica_cluster_id_'+ str(replica_count)] = node['CacheClusterId']
-                        replica_count += 1
-
-            # Target: Redis Replication Groups
-            if key == 'ec2_member_clusters' and value:
-                host_info['ec2_member_clusters'] = ','.join([str(i) for i in value])
-
-            # Target: All Cache Clusters
-            elif key == 'ec2_cache_parameter_group':
-                host_info["ec2_cache_node_ids_to_reboot"] = ','.join([str(i) for i in value['CacheNodeIdsToReboot']])
-                host_info['ec2_cache_parameter_group_name'] = value['CacheParameterGroupName']
-                host_info['ec2_cache_parameter_apply_status'] = value['ParameterApplyStatus']
-
-            # Target: Almost everything
-            elif key == 'ec2_security_groups':
-
-                # Skip if SecurityGroups is None
-                # (it is possible to have the key defined but no value in it).
-                if value is not None:
-                    sg_ids = []
-                    for sg in value:
-                        sg_ids.append(sg['SecurityGroupId'])
-                    host_info["ec2_security_group_ids"] = ','.join([str(i) for i in sg_ids])
-
-            # Target: Everything
-            # Preserve booleans and integers
-            elif type(value) in [int, bool]:
-                host_info[key] = value
-
-            # Target: Everything
-            # Sanitize string values
-            elif isinstance(value, six.string_types):
-                host_info[key] = value.strip()
-
-            # Target: Everything
-            # Replace None by an empty string
-            elif type(value) == type(None):
-                host_info[key] = ''
-
-            else:
-                # Remove non-processed complex types
-                pass
-
-        return host_info
-
-    def get_host_info(self):
-        ''' Get variables about a specific host '''
-
-        if len(self.index) == 0:
-            # Need to load index from cache
-            self.load_index_from_cache()
-
-        if not self.args.host in self.index:
-            # try updating the cache
-            self.do_api_calls_update_cache()
-            if not self.args.host in self.index:
-                # host might not exist anymore
-                return self.json_format_dict({}, True)
-
-        (region, instance_id) = self.index[self.args.host]
-
-        instance = self.get_instance(region, instance_id)
-        return self.json_format_dict(self.get_host_info_dict_from_instance(instance), True)
-
-    def push(self, my_dict, key, element):
-        ''' Push an element onto an array that may not have been defined in
-        the dict '''
-        group_info = my_dict.setdefault(key, [])
-        if isinstance(group_info, dict):
-            host_list = group_info.setdefault('hosts', [])
-            host_list.append(element)
-        else:
-            group_info.append(element)
-
-    def push_group(self, my_dict, key, element):
-        ''' Push a group as a child of another group. '''
-        parent_group = my_dict.setdefault(key, {})
-        if not isinstance(parent_group, dict):
-            parent_group = my_dict[key] = {'hosts': parent_group}
-        child_groups = parent_group.setdefault('children', [])
-        if element not in child_groups:
-            child_groups.append(element)
-
-    def get_inventory_from_cache(self):
-        ''' Reads the inventory from the cache file and returns it as a JSON
-        object '''
-
-        cache = open(self.cache_path_cache, 'r')
-        json_inventory = cache.read()
-        return json_inventory
-
-
-    def load_index_from_cache(self):
-        ''' Reads the index from the cache file sets self.index '''
-
-        cache = open(self.cache_path_index, 'r')
-        json_index = cache.read()
-        self.index = json.loads(json_index)
-
-
-    def write_to_cache(self, data, filename):
-        ''' Writes data in JSON format to a file '''
-
-        json_data = self.json_format_dict(data, True)
-        cache = open(filename, 'w')
-        cache.write(json_data)
-        cache.close()
-
-    def uncammelize(self, key):
-        temp = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', key)
-        return re.sub('([a-z0-9])([A-Z])', r'\1_\2', temp).lower()
-
-    def to_safe(self, word):
-        ''' Converts 'bad' characters in a string to underscores so they can be used as Ansible groups '''
-        regex = "[^A-Za-z0-9\_"
-        if not self.replace_dash_in_groups:
-            regex += "\-"
-        return re.sub(regex + "]", "_", word)
-
-    def json_format_dict(self, data, pretty=False):
-        ''' Converts a dict to a JSON object and dumps it as a formatted
-        string '''
-
-        if pretty:
-            return json.dumps(data, sort_keys=True, indent=2)
-        else:
-            return json.dumps(data)
-
-
-# Run the script
-Ec2Inventory()
diff --git a/edge-baas-portal-1701-dc7/inventory-dc7-baas b/edge-baas-portal-1701-dc7/inventory-dc7-baas
deleted file mode 100644
index d2ae03e..0000000
--- a/edge-baas-portal-1701-dc7/inventory-dc7-baas
+++ /dev/null
@@ -1,55 +0,0 @@
-[tag_Name_dc7_n11]
-[tag_Name_dc7_n12]
-[tag_Name_dc7_n13]
-[tag_Name_dc7_n14]
-[tag_Name_dc7_n15]
-[tag_Name_dc7_n16]
-[tag_Name_dc7_n17]
-[tag_Name_dc7_n18]
-[tag_Name_dc7_n19]
-[tag_Name_dc7_n20]
-
-[planet:children]
-dc-1
-
-[dc-1:children]
-tag_Name_dc7_n11
-tag_Name_dc7_n12
-tag_Name_dc7_n13
-tag_Name_dc7_n14
-tag_Name_dc7_n15
-tag_Name_dc7_n16
-tag_Name_dc7_n17
-tag_Name_dc7_n18
-tag_Name_dc7_n19
-tag_Name_dc7_n20
-
-[elastic:children]
-dc-1-elastic
-
-[dc-1-elastic:children]
-tag_Name_dc7_n11
-tag_Name_dc7_n12
-tag_Name_dc7_n13
-
-[baas:children]
-dc-1-baas
-
-[dc-1-baas:children]
-tag_Name_dc7_n14
-tag_Name_dc7_n15
-tag_Name_dc7_n16
-
-[portal:children]
-dc-1-portal
-
-[dc-1-portal:children]
-tag_Name_dc7_n17
-
-[cassandra:children]
-dc-1-cassandra
-
-[dc-1-cassandra:children]
-tag_Name_dc7_n18
-tag_Name_dc7_n19
-tag_Name_dc7_n20
diff --git a/edge-baas-portal-1701-dc7/inventory-dc7-edge b/edge-baas-portal-1701-dc7/inventory-dc7-edge
deleted file mode 100644
index 21862f9..0000000
--- a/edge-baas-portal-1701-dc7/inventory-dc7-edge
+++ /dev/null
@@ -1,84 +0,0 @@
-[tag_Name_dc7_n1]
-[tag_Name_dc7_n2]
-[tag_Name_dc7_n3]
-[tag_Name_dc7_n4]
-[tag_Name_dc7_n5]
-[tag_Name_dc7_n6]
-[tag_Name_dc7_n7]
-[tag_Name_dc7_n8]
-[tag_Name_dc7_n9]
-[tag_Name_dc7_n10]
-
-[planet:children]
-dc-1
-
-[dc-1:children]
-tag_Name_dc7_n1
-tag_Name_dc7_n2
-tag_Name_dc7_n3
-tag_Name_dc7_n4
-tag_Name_dc7_n5
-tag_Name_dc7_n6
-tag_Name_dc7_n7
-tag_Name_dc7_n8
-tag_Name_dc7_n9
-tag_Name_dc7_n10
-
-[ds:children]
-dc-1-ds
-
-[dc-1-ds:children]
-tag_Name_dc7_n1
-tag_Name_dc7_n2
-tag_Name_dc7_n3
-
-[ms:children]
-dc-1-ms
-
-[dc-1-ms:children]
-tag_Name_dc7_n4
-
-[ui:children]
-dc-1-ui
-
-[dc-1-ui:children]
-tag_Name_dc7_n4
-
-[ldap:children]
-dc-1-ldap
-
-[dc-1-ldap:children]
-tag_Name_dc7_n4
-
-[rmp:children]
-dc-1-rmp
-
-[dc-1-rmp:children]
-tag_Name_dc7_n5
-tag_Name_dc7_n6
-
-[qpid:children]
-dc-1-qpid
-
-[dc-1-qpid:children]
-tag_Name_dc7_n7
-tag_Name_dc7_n8
-
-[pg:children]
-dc-1-pg
-
-[dc-1-pg:children]
-dc-1-pgmaster
-dc-1-pgstandby
-
-[pgmaster:children]
-dc-1-pgmaster
-
-[dc-1-pgmaster:children]
-tag_Name_dc7_n9
-
-[pgstandby:children]
-dc-1-pgstandby
-
-[dc-1-pgstandby:children]
-tag_Name_dc7_n10
diff --git a/edge-baas-portal-1701-dc7/inventory-dc7-portal b/edge-baas-portal-1701-dc7/inventory-dc7-portal
deleted file mode 100644
index a0e784c..0000000
--- a/edge-baas-portal-1701-dc7/inventory-dc7-portal
+++ /dev/null
@@ -1,13 +0,0 @@
-[tag_Name_dc7_n21]
-
-[planet:children]
-dc-1
-
-[dc-1:children]
-tag_Name_dc7_n21
-
-[devportal:children]
-dc-1-devportal
-
-[dc-1-devportal:children]
-tag_Name_dc7_n21
diff --git a/edge-ops-lab-1701-expansion/inventory-dc1 b/edge-ops-lab-1701-expansion/inventory-dc1
deleted file mode 120000
index 9fbca33..0000000
--- a/edge-ops-lab-1701-expansion/inventory-dc1
+++ /dev/null
@@ -1 +0,0 @@
-/Users/friasc/.ansible/inventory/edge-ops-lab-1701/inventory-dc1
\ No newline at end of file
diff --git a/edge-ops-lab-1701/inventory-dc1 b/edge-ops-lab-1701/inventory-dc1
deleted file mode 100644
index d309119..0000000
--- a/edge-ops-lab-1701/inventory-dc1
+++ /dev/null
@@ -1,58 +0,0 @@
-[dc-1-ds]
-10.142.0.14
-10.142.0.[8:9]
-
-[dc-1-ms]
-10.142.0.5
-
-[dc-1-ui]
-10.142.0.5
-
-[dc-1-ldap]
-10.142.0.5
-
-[dc-1-rmp]
-10.142.0.[10:11]
-
-[dc-1-qpid]
-10.142.0.13
-10.142.0.7
-
-[dc-1-pg:children]
-dc-1-pgmaster
-
-[dc-1-pgmaster]
-10.142.0.15
-
-[planet:children]
-dc-1
-
-[dc-1:children]
-dc-1-ds
-dc-1-ms
-dc-1-ui
-dc-1-ldap
-dc-1-rmp
-dc-1-qpid
-dc-1-pg
-
-[ds:children]
-dc-1-ds
-
-[ms:children]
-dc-1-ms
-
-[ui:children]
-dc-1-ui
-
-[ldap:children]
-dc-1-ldap
-
-[rmp:children]
-dc-1-rmp
-
-[qpid:children]
-dc-1-qpid
-
-[pg:children]
-dc-1-pg
diff --git a/edgemicro-1601-dc1/ec2.ini b/edgemicro-1601-dc1/ec2.ini
deleted file mode 100644
index 36b3921..0000000
--- a/edgemicro-1601-dc1/ec2.ini
+++ /dev/null
@@ -1,200 +0,0 @@
-# Ansible EC2 external inventory script settings
-#
-
-[ec2]
-
-# to talk to a private eucalyptus instance uncomment these lines
-# and edit edit eucalyptus_host to be the host name of your cloud controller
-#eucalyptus = True
-#eucalyptus_host = clc.cloud.domain.org
-
-# AWS regions to make calls to. Set this to 'all' to make request to all regions
-# in AWS and merge the results together. Alternatively, set this to a comma
-# separated list of regions. E.g. 'us-east-1,us-west-1,us-west-2'
-regions = all
-regions_exclude = us-gov-west-1,cn-north-1
-
-# When generating inventory, Ansible needs to know how to address a server.
-# Each EC2 instance has a lot of variables associated with it. Here is the list:
-#   http://docs.pythonboto.org/en/latest/ref/ec2.html#module-boto.ec2.instance
-# Below are 2 variables that are used as the address of a server:
-#   - destination_variable
-#   - vpc_destination_variable
-
-# This is the normal destination variable to use. If you are running Ansible
-# from outside EC2, then 'public_dns_name' makes the most sense. If you are
-# running Ansible from within EC2, then perhaps you want to use the internal
-# address, and should set this to 'private_dns_name'. The key of an EC2 tag
-# may optionally be used; however the boto instance variables hold precedence
-# in the event of a collision.
-destination_variable = public_dns_name
-
-# This allows you to override the inventory_name with an ec2 variable, instead
-# of using the destination_variable above. Addressing (aka ansible_ssh_host)
-# will still use destination_variable. Tags should be written as 'tag_TAGNAME'.
-#hostname_variable = tag_Name
-
-# For server inside a VPC, using DNS names may not make sense. When an instance
-# has 'subnet_id' set, this variable is used. If the subnet is public, setting
-# this to 'ip_address' will return the public IP address. For instances in a
-# private subnet, this should be set to 'private_ip_address', and Ansible must
-# be run from within EC2. The key of an EC2 tag may optionally be used; however
-# the boto instance variables hold precedence in the event of a collision.
-# WARNING: - instances that are in the private vpc, _without_ public ip address
-# will not be listed in the inventory until You set:
-# vpc_destination_variable = private_ip_address
-vpc_destination_variable = ip_address
-
-# The following two settings allow flexible ansible host naming based on a
-# python format string and a comma-separated list of ec2 tags.  Note that:
-#
-# 1) If the tags referenced are not present for some instances, empty strings
-#    will be substituted in the format string.
-# 2) This overrides both destination_variable and vpc_destination_variable.
-#
-#destination_format = {0}.{1}.example.com
-#destination_format_tags = Name,environment
-
-# To tag instances on EC2 with the resource records that point to them from
-# Route53, uncomment and set 'route53' to True.
-route53 = False
-
-# To exclude RDS instances from the inventory, uncomment and set to False.
-rds = False
-
-# To exclude ElastiCache instances from the inventory, uncomment and set to False.
-elasticache = False
-
-# Additionally, you can specify the list of zones to exclude looking up in
-# 'route53_excluded_zones' as a comma-separated list.
-# route53_excluded_zones = samplezone1.com, samplezone2.com
-
-# By default, only EC2 instances in the 'running' state are returned. Set
-# 'all_instances' to True to return all instances regardless of state.
-all_instances = True
-
-# By default, only EC2 instances in the 'running' state are returned. Specify
-# EC2 instance states to return as a comma-separated list. This
-# option is overriden when 'all_instances' is True.
-# instance_states = pending, running, shutting-down, terminated, stopping, stopped
-
-# By default, only RDS instances in the 'available' state are returned.  Set
-# 'all_rds_instances' to True return all RDS instances regardless of state.
-all_rds_instances = False
-
-# By default, only ElastiCache clusters and nodes in the 'available' state
-# are returned. Set 'all_elasticache_clusters' and/or 'all_elastic_nodes'
-# to True return all ElastiCache clusters and nodes, regardless of state.
-#
-# Note that all_elasticache_nodes only applies to listed clusters. That means
-# if you set all_elastic_clusters to false, no node will be return from
-# unavailable clusters, regardless of the state and to what you set for
-# all_elasticache_nodes.
-all_elasticache_replication_groups = False
-all_elasticache_clusters = False
-all_elasticache_nodes = False
-
-# API calls to EC2 are slow. For this reason, we cache the results of an API
-# call. Set this to the path you want cache files to be written to. Two files
-# will be written to this directory:
-#   - ansible-ec2.cache
-#   - ansible-ec2.index
-cache_path = ~/.ansible/tmp
-
-# The number of seconds a cache file is considered valid. After this many
-# seconds, a new API call will be made, and the cache file will be updated.
-# To disable the cache, set this value to 0
-cache_max_age = 300
-
-# Organize groups into a nested/hierarchy instead of a flat namespace.
-nested_groups = False
-
-# Replace - tags when creating groups to avoid issues with ansible
-replace_dash_in_groups = True
-
-# If set to true, any tag of the form "a,b,c" is expanded into a list
-# and the results are used to create additional tag_* inventory groups.
-expand_csv_tags = False
-
-# The EC2 inventory output can become very large. To manage its size,
-# configure which groups should be created.
-group_by_instance_id = True
-group_by_region = True
-group_by_availability_zone = True
-group_by_ami_id = True
-group_by_instance_type = True
-group_by_key_pair = True
-group_by_vpc_id = True
-group_by_security_group = True
-group_by_tag_keys = True
-group_by_tag_none = True
-group_by_route53_names = True
-group_by_rds_engine = False
-group_by_rds_parameter_group = False
-group_by_elasticache_engine = True
-group_by_elasticache_cluster = True
-group_by_elasticache_parameter_group = True
-group_by_elasticache_replication_group = True
-
-# If you only want to include hosts that match a certain regular expression
-# pattern_include = staging-*
-
-# If you want to exclude any hosts that match a certain regular expression
-# pattern_exclude = staging-*
-# Ansible EC2 external inventory script settings
-#
-
-##[ec2]
-##
-### to talk to a private eucalyptus instance uncomment these lines
-### and edit edit eucalyptus_host to be the host name of your cloud controller
-###eucalyptus = True
-###eucalyptus_host = clc.cloud.domain.org
-##
-### AWS regions to make calls to. Set this to 'all' to make request to all regions
-##
-### in AWS and merge the results together. Alternatively, set this to a comma
-### separated list of regions. E.g. 'us-east-1,us-west-1,us-west-2'
-##regions = all
-##regions_exclude = us-gov-west-1,cn-north-1
-##
-### When generating inventory, Ansible needs to know how to address a server.
-### Each EC2 instance has a lot of variables associated with it. Here is the list:
-###   http://docs.pythonboto.org/en/latest/ref/ec2.html#module-boto.ec2.instance
-### Below are 2 variables that are used as the address of a server:
-###   - destination_variable
-###   - vpc_destination_variable
-##
-### This is the normal destination variable to use. If you are running Ansible
-### from outside EC2, then 'public_dns_name' makes the most sense. If you are
-### running Ansible from within EC2, then perhaps you want to use the internal
-### address, and should set this to 'private_dns_name'. The key of an EC2 tag
-##...skipping...
-### pattern_include = staging-*
-##
-### If you want to exclude any hosts that match a certain regular expression
-### pattern_exclude = staging-*
-
-# Instance filters can be used to control which instances are retrieved for
-# inventory. For the full list of possible filters, please read the EC2 API
-# docs: http://docs.aws.amazon.com/AWSEC2/latest/APIReference/ApiReference-query-DescribeInstances.html#query-DescribeInstances-filters
-# Filters are key/value pairs separated by '=', to list multiple filters use
-# a list separated by commas. See examples below.
-
-# Retrieve only instances with (key=value) env=staging tag
-# instance_filters = tag:env=staging
-
-# Retrieve only instances with role=webservers OR role=dbservers tag
-# instance_filters = tag:role=webservers,tag:role=dbservers
-
-# Retrieve only t1.micro instances OR instances with tag env=staging
-# instance_filters = instance-type=t1.micro,tag:env=staging
-
-# You can use wildcards in filter values also. Below will list instances which
-# tag Name value matches webservers1*
-# (ex. webservers15, webservers1a, webservers123 etc)
-# instance_filters = tag:Name=webservers1*
-
-# A boto configuration profile may be used to separate out credentials
-# see http://boto.readthedocs.org/en/latest/boto_config_tut.html
-# boto_profile = some-boto-profile-name
diff --git a/edgemicro-1601-dc1/ec2.py b/edgemicro-1601-dc1/ec2.py
deleted file mode 100755
index f30958a..0000000
--- a/edgemicro-1601-dc1/ec2.py
+++ /dev/null
@@ -1,1385 +0,0 @@
-#!/usr/bin/env python
-
-'''
-EC2 external inventory script
-=================================
-
-Generates inventory that Ansible can understand by making API request to
-AWS EC2 using the Boto library.
-
-NOTE: This script assumes Ansible is being executed where the environment
-variables needed for Boto have already been set:
-    export AWS_ACCESS_KEY_ID='AK123'
-    export AWS_SECRET_ACCESS_KEY='abc123'
-
-This script also assumes there is an ec2.ini file alongside it.  To specify a
-different path to ec2.ini, define the EC2_INI_PATH environment variable:
-
-    export EC2_INI_PATH=/path/to/my_ec2.ini
-
-If you're using eucalyptus you need to set the above variables and
-you need to define:
-
-    export EC2_URL=http://hostname_of_your_cc:port/services/Eucalyptus
-
-If you're using boto profiles (requires boto>=2.24.0) you can choose a profile
-using the --boto-profile command line argument (e.g. ec2.py --boto-profile prod) or using
-the AWS_PROFILE variable:
-
-    AWS_PROFILE=prod ansible-playbook -i ec2.py myplaybook.yml
-
-For more details, see: http://docs.pythonboto.org/en/latest/boto_config_tut.html
-
-When run against a specific host, this script returns the following variables:
- - ec2_ami_launch_index
- - ec2_architecture
- - ec2_association
- - ec2_attachTime
- - ec2_attachment
- - ec2_attachmentId
- - ec2_client_token
- - ec2_deleteOnTermination
- - ec2_description
- - ec2_deviceIndex
- - ec2_dns_name
- - ec2_eventsSet
- - ec2_group_name
- - ec2_hypervisor
- - ec2_id
- - ec2_image_id
- - ec2_instanceState
- - ec2_instance_type
- - ec2_ipOwnerId
- - ec2_ip_address
- - ec2_item
- - ec2_kernel
- - ec2_key_name
- - ec2_launch_time
- - ec2_monitored
- - ec2_monitoring
- - ec2_networkInterfaceId
- - ec2_ownerId
- - ec2_persistent
- - ec2_placement
- - ec2_platform
- - ec2_previous_state
- - ec2_private_dns_name
- - ec2_private_ip_address
- - ec2_publicIp
- - ec2_public_dns_name
- - ec2_ramdisk
- - ec2_reason
- - ec2_region
- - ec2_requester_id
- - ec2_root_device_name
- - ec2_root_device_type
- - ec2_security_group_ids
- - ec2_security_group_names
- - ec2_shutdown_state
- - ec2_sourceDestCheck
- - ec2_spot_instance_request_id
- - ec2_state
- - ec2_state_code
- - ec2_state_reason
- - ec2_status
- - ec2_subnet_id
- - ec2_tenancy
- - ec2_virtualization_type
- - ec2_vpc_id
-
-These variables are pulled out of a boto.ec2.instance object. There is a lack of
-consistency with variable spellings (camelCase and underscores) since this
-just loops through all variables the object exposes. It is preferred to use the
-ones with underscores when multiple exist.
-
-In addition, if an instance has AWS Tags associated with it, each tag is a new
-variable named:
- - ec2_tag_[Key] = [Value]
-
-Security groups are comma-separated in 'ec2_security_group_ids' and
-'ec2_security_group_names'.
-'''
-
-# (c) 2012, Peter Sankauskas
-#
-# This file is part of Ansible,
-#
-# Ansible is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# Ansible is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with Ansible.  If not, see <http://www.gnu.org/licenses/>.
-
-######################################################################
-
-import sys
-import os
-import argparse
-import re
-from time import time
-import boto
-from boto import ec2
-from boto import rds
-from boto import elasticache
-from boto import route53
-import six
-
-from six.moves import configparser
-from collections import defaultdict
-
-try:
-    import json
-except ImportError:
-    import simplejson as json
-
-
-class Ec2Inventory(object):
-
-    def _empty_inventory(self):
-        return {"_meta" : {"hostvars" : {}}}
-
-    def __init__(self):
-        ''' Main execution path '''
-
-        # Inventory grouped by instance IDs, tags, security groups, regions,
-        # and availability zones
-        self.inventory = self._empty_inventory()
-
-        # Index of hostname (address) to instance ID
-        self.index = {}
-
-        # Boto profile to use (if any)
-        self.boto_profile = None
-
-        # Read settings and parse CLI arguments
-        self.parse_cli_args()
-        self.read_settings()
-
-        # Make sure that profile_name is not passed at all if not set
-        # as pre 2.24 boto will fall over otherwise
-        if self.boto_profile:
-            if not hasattr(boto.ec2.EC2Connection, 'profile_name'):
-                self.fail_with_error("boto version must be >= 2.24 to use profile")
-
-        # Cache
-        if self.args.refresh_cache:
-            self.do_api_calls_update_cache()
-        elif not self.is_cache_valid():
-            self.do_api_calls_update_cache()
-
-        # Data to print
-        if self.args.host:
-            data_to_print = self.get_host_info()
-
-        elif self.args.list:
-            # Display list of instances for inventory
-            if self.inventory == self._empty_inventory():
-                data_to_print = self.get_inventory_from_cache()
-            else:
-                data_to_print = self.json_format_dict(self.inventory, True)
-
-        print(data_to_print)
-
-
-    def is_cache_valid(self):
-        ''' Determines if the cache files have expired, or if it is still valid '''
-
-        if os.path.isfile(self.cache_path_cache):
-            mod_time = os.path.getmtime(self.cache_path_cache)
-            current_time = time()
-            if (mod_time + self.cache_max_age) > current_time:
-                if os.path.isfile(self.cache_path_index):
-                    return True
-
-        return False
-
-
-    def read_settings(self):
-        ''' Reads the settings from the ec2.ini file '''
-        if six.PY3:
-            config = configparser.ConfigParser()
-        else:
-            config = configparser.SafeConfigParser()
-        ec2_default_ini_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'ec2.ini')
-        ec2_ini_path = os.path.expanduser(os.path.expandvars(os.environ.get('EC2_INI_PATH', ec2_default_ini_path)))
-        config.read(ec2_ini_path)
-
-        # is eucalyptus?
-        self.eucalyptus_host = None
-        self.eucalyptus = False
-        if config.has_option('ec2', 'eucalyptus'):
-            self.eucalyptus = config.getboolean('ec2', 'eucalyptus')
-        if self.eucalyptus and config.has_option('ec2', 'eucalyptus_host'):
-            self.eucalyptus_host = config.get('ec2', 'eucalyptus_host')
-
-        # Regions
-        self.regions = []
-        configRegions = config.get('ec2', 'regions')
-        configRegions_exclude = config.get('ec2', 'regions_exclude')
-        if (configRegions == 'all'):
-            if self.eucalyptus_host:
-                self.regions.append(boto.connect_euca(host=self.eucalyptus_host).region.name)
-            else:
-                for regionInfo in ec2.regions():
-                    if regionInfo.name not in configRegions_exclude:
-                        self.regions.append(regionInfo.name)
-        else:
-            self.regions = configRegions.split(",")
-
-        # Destination addresses
-        self.destination_variable = config.get('ec2', 'destination_variable')
-        self.vpc_destination_variable = config.get('ec2', 'vpc_destination_variable')
-
-        if config.has_option('ec2', 'hostname_variable'):
-            self.hostname_variable = config.get('ec2', 'hostname_variable')
-        else:
-            self.hostname_variable = None
-
-        if config.has_option('ec2', 'destination_format') and \
-                config.has_option('ec2', 'destination_format_tags'):
-            self.destination_format = config.get('ec2', 'destination_format')
-            self.destination_format_tags = config.get('ec2', 'destination_format_tags').split(',')
-        else:
-            self.destination_format = None
-            self.destination_format_tags = None
-
-        # Route53
-        self.route53_enabled = config.getboolean('ec2', 'route53')
-        self.route53_excluded_zones = []
-        if config.has_option('ec2', 'route53_excluded_zones'):
-            self.route53_excluded_zones.extend(
-                    config.get('ec2', 'route53_excluded_zones', '').split(','))
-
-        # Include RDS instances?
-        self.rds_enabled = True
-        if config.has_option('ec2', 'rds'):
-            self.rds_enabled = config.getboolean('ec2', 'rds')
-
-        # Include ElastiCache instances?
-        self.elasticache_enabled = True
-        if config.has_option('ec2', 'elasticache'):
-            self.elasticache_enabled = config.getboolean('ec2', 'elasticache')
-
-        # Return all EC2 instances?
-        if config.has_option('ec2', 'all_instances'):
-            self.all_instances = config.getboolean('ec2', 'all_instances')
-        else:
-            self.all_instances = False
-
-        # Instance states to be gathered in inventory. Default is 'running'.
-        # Setting 'all_instances' to 'yes' overrides this option.
-        ec2_valid_instance_states = [
-            'pending',
-            'running',
-            'shutting-down',
-            'terminated',
-            'stopping',
-            'stopped'
-        ]
-        self.ec2_instance_states = []
-        if self.all_instances:
-            self.ec2_instance_states = ec2_valid_instance_states
-        elif config.has_option('ec2', 'instance_states'):
-            for instance_state in config.get('ec2', 'instance_states').split(','):
-                instance_state = instance_state.strip()
-                if instance_state not in ec2_valid_instance_states:
-                    continue
-                self.ec2_instance_states.append(instance_state)
-        else:
-            self.ec2_instance_states = ['running']
-
-        # Return all RDS instances? (if RDS is enabled)
-        if config.has_option('ec2', 'all_rds_instances') and self.rds_enabled:
-            self.all_rds_instances = config.getboolean('ec2', 'all_rds_instances')
-        else:
-            self.all_rds_instances = False
-
-        # Return all ElastiCache replication groups? (if ElastiCache is enabled)
-        if config.has_option('ec2', 'all_elasticache_replication_groups') and self.elasticache_enabled:
-            self.all_elasticache_replication_groups = config.getboolean('ec2', 'all_elasticache_replication_groups')
-        else:
-            self.all_elasticache_replication_groups = False
-
-        # Return all ElastiCache clusters? (if ElastiCache is enabled)
-        if config.has_option('ec2', 'all_elasticache_clusters') and self.elasticache_enabled:
-            self.all_elasticache_clusters = config.getboolean('ec2', 'all_elasticache_clusters')
-        else:
-            self.all_elasticache_clusters = False
-
-        # Return all ElastiCache nodes? (if ElastiCache is enabled)
-        if config.has_option('ec2', 'all_elasticache_nodes') and self.elasticache_enabled:
-            self.all_elasticache_nodes = config.getboolean('ec2', 'all_elasticache_nodes')
-        else:
-            self.all_elasticache_nodes = False
-
-        # boto configuration profile (prefer CLI argument)
-        self.boto_profile = self.args.boto_profile
-        if config.has_option('ec2', 'boto_profile') and not self.boto_profile:
-            self.boto_profile = config.get('ec2', 'boto_profile')
-
-        # Cache related
-        cache_dir = os.path.expanduser(config.get('ec2', 'cache_path'))
-        if self.boto_profile:
-            cache_dir = os.path.join(cache_dir, 'profile_' + self.boto_profile)
-        if not os.path.exists(cache_dir):
-            os.makedirs(cache_dir)
-
-        cache_name = 'ansible-ec2'
-        aws_profile = lambda: (self.boto_profile or
-                               os.environ.get('AWS_PROFILE') or
-                               os.environ.get('AWS_ACCESS_KEY_ID'))
-        if aws_profile():
-            cache_name = '%s-%s' % (cache_name, aws_profile())
-        self.cache_path_cache = cache_dir + "/%s.cache" % cache_name
-        self.cache_path_index = cache_dir + "/%s.index" % cache_name
-        self.cache_max_age = config.getint('ec2', 'cache_max_age')
-
-        if config.has_option('ec2', 'expand_csv_tags'):
-            self.expand_csv_tags = config.getboolean('ec2', 'expand_csv_tags')
-        else:
-            self.expand_csv_tags = False
-
-        # Configure nested groups instead of flat namespace.
-        if config.has_option('ec2', 'nested_groups'):
-            self.nested_groups = config.getboolean('ec2', 'nested_groups')
-        else:
-            self.nested_groups = False
-
-        # Replace dash or not in group names
-        if config.has_option('ec2', 'replace_dash_in_groups'):
-            self.replace_dash_in_groups = config.getboolean('ec2', 'replace_dash_in_groups')
-        else:
-            self.replace_dash_in_groups = True
-
-        # Configure which groups should be created.
-        group_by_options = [
-            'group_by_instance_id',
-            'group_by_region',
-            'group_by_availability_zone',
-            'group_by_ami_id',
-            'group_by_instance_type',
-            'group_by_key_pair',
-            'group_by_vpc_id',
-            'group_by_security_group',
-            'group_by_tag_keys',
-            'group_by_tag_none',
-            'group_by_route53_names',
-            'group_by_rds_engine',
-            'group_by_rds_parameter_group',
-            'group_by_elasticache_engine',
-            'group_by_elasticache_cluster',
-            'group_by_elasticache_parameter_group',
-            'group_by_elasticache_replication_group',
-        ]
-        for option in group_by_options:
-            if config.has_option('ec2', option):
-                setattr(self, option, config.getboolean('ec2', option))
-            else:
-                setattr(self, option, True)
-
-        # Do we need to just include hosts that match a pattern?
-        try:
-            pattern_include = config.get('ec2', 'pattern_include')
-            if pattern_include and len(pattern_include) > 0:
-                self.pattern_include = re.compile(pattern_include)
-            else:
-                self.pattern_include = None
-        except configparser.NoOptionError:
-            self.pattern_include = None
-
-        # Do we need to exclude hosts that match a pattern?
-        try:
-            pattern_exclude = config.get('ec2', 'pattern_exclude');
-            if pattern_exclude and len(pattern_exclude) > 0:
-                self.pattern_exclude = re.compile(pattern_exclude)
-            else:
-                self.pattern_exclude = None
-        except configparser.NoOptionError:
-            self.pattern_exclude = None
-
-        # Instance filters (see boto and EC2 API docs). Ignore invalid filters.
-        self.ec2_instance_filters = defaultdict(list)
-        if config.has_option('ec2', 'instance_filters'):
-
-            filters = [f for f in config.get('ec2', 'instance_filters').split(',') if f]
-
-            for instance_filter in filters:
-                instance_filter = instance_filter.strip()
-                if not instance_filter or '=' not in instance_filter:
-                    continue
-                filter_key, filter_value = [x.strip() for x in instance_filter.split('=', 1)]
-                if not filter_key:
-                    continue
-                self.ec2_instance_filters[filter_key].append(filter_value)
-
-    def parse_cli_args(self):
-        ''' Command line argument processing '''
-
-        parser = argparse.ArgumentParser(description='Produce an Ansible Inventory file based on EC2')
-        parser.add_argument('--list', action='store_true', default=True,
-                            help='List instances (default: True)')
-        parser.add_argument('--host', action='store',
-                            help='Get all the variables about a specific instance')
-        parser.add_argument('--refresh-cache', action='store_true', default=False,
-                            help='Force refresh of cache by making API requests to EC2 (default: False - use cache files)')
-        parser.add_argument('--profile', '--boto-profile', action='store', dest='boto_profile',
-                            help='Use boto profile for connections to EC2')
-        self.args = parser.parse_args()
-
-
-    def do_api_calls_update_cache(self):
-        ''' Do API calls to each region, and save data in cache files '''
-
-        if self.route53_enabled:
-            self.get_route53_records()
-
-        for region in self.regions:
-            self.get_instances_by_region(region)
-            if self.rds_enabled:
-                self.get_rds_instances_by_region(region)
-            if self.elasticache_enabled:
-                self.get_elasticache_clusters_by_region(region)
-                self.get_elasticache_replication_groups_by_region(region)
-
-        self.write_to_cache(self.inventory, self.cache_path_cache)
-        self.write_to_cache(self.index, self.cache_path_index)
-
-    def connect(self, region):
-        ''' create connection to api server'''
-        if self.eucalyptus:
-            conn = boto.connect_euca(host=self.eucalyptus_host)
-            conn.APIVersion = '2010-08-31'
-        else:
-            conn = self.connect_to_aws(ec2, region)
-        return conn
-
-    def boto_fix_security_token_in_profile(self, connect_args):
-        ''' monkey patch for boto issue boto/boto#2100 '''
-        profile = 'profile ' + self.boto_profile
-        if boto.config.has_option(profile, 'aws_security_token'):
-            connect_args['security_token'] = boto.config.get(profile, 'aws_security_token')
-        return connect_args
-
-    def connect_to_aws(self, module, region):
-        connect_args = {}
-
-        # only pass the profile name if it's set (as it is not supported by older boto versions)
-        if self.boto_profile:
-            connect_args['profile_name'] = self.boto_profile
-            self.boto_fix_security_token_in_profile(connect_args)
-
-        conn = module.connect_to_region(region, **connect_args)
-        # connect_to_region will fail "silently" by returning None if the region name is wrong or not supported
-        if conn is None:
-            self.fail_with_error("region name: %s likely not supported, or AWS is down.  connection to region failed." % region)
-        return conn
-
-    def get_instances_by_region(self, region):
-        ''' Makes an AWS EC2 API call to the list of instances in a particular
-        region '''
-
-        try:
-            conn = self.connect(region)
-            reservations = []
-            if self.ec2_instance_filters:
-                for filter_key, filter_values in self.ec2_instance_filters.items():
-                    reservations.extend(conn.get_all_instances(filters = { filter_key : filter_values }))
-            else:
-                reservations = conn.get_all_instances()
-
-            for reservation in reservations:
-                for instance in reservation.instances:
-                    self.add_instance(instance, region)
-
-        except boto.exception.BotoServerError as e:
-            if e.error_code == 'AuthFailure':
-                error = self.get_auth_error_message()
-            else:
-                backend = 'Eucalyptus' if self.eucalyptus else 'AWS'
-                error = "Error connecting to %s backend.\n%s" % (backend, e.message)
-            self.fail_with_error(error, 'getting EC2 instances')
-
-    def get_rds_instances_by_region(self, region):
-        ''' Makes an AWS API call to the list of RDS instances in a particular
-        region '''
-
-        try:
-            conn = self.connect_to_aws(rds, region)
-            if conn:
-                marker = None
-                while True:
-                    instances = conn.get_all_dbinstances(marker=marker)
-                    marker = instances.marker
-                    for instance in instances:
-                        self.add_rds_instance(instance, region)
-                    if not marker:
-                        break
-        except boto.exception.BotoServerError as e:
-            error = e.reason
-
-            if e.error_code == 'AuthFailure':
-                error = self.get_auth_error_message()
-            if not e.reason == "Forbidden":
-                error = "Looks like AWS RDS is down:\n%s" % e.message
-            self.fail_with_error(error, 'getting RDS instances')
-
-    def get_elasticache_clusters_by_region(self, region):
-        ''' Makes an AWS API call to the list of ElastiCache clusters (with
-        nodes' info) in a particular region.'''
-
-        # ElastiCache boto module doesn't provide a get_all_intances method,
-        # that's why we need to call describe directly (it would be called by
-        # the shorthand method anyway...)
-        try:
-            conn = self.connect_to_aws(elasticache, region)
-            if conn:
-                # show_cache_node_info = True
-                # because we also want nodes' information
-                response = conn.describe_cache_clusters(None, None, None, True)
-
-        except boto.exception.BotoServerError as e:
-            error = e.reason
-
-            if e.error_code == 'AuthFailure':
-                error = self.get_auth_error_message()
-            if not e.reason == "Forbidden":
-                error = "Looks like AWS ElastiCache is down:\n%s" % e.message
-            self.fail_with_error(error, 'getting ElastiCache clusters')
-
-        try:
-            # Boto also doesn't provide wrapper classes to CacheClusters or
-            # CacheNodes. Because of that wo can't make use of the get_list
-            # method in the AWSQueryConnection. Let's do the work manually
-            clusters = response['DescribeCacheClustersResponse']['DescribeCacheClustersResult']['CacheClusters']
-
-        except KeyError as e:
-            error = "ElastiCache query to AWS failed (unexpected format)."
-            self.fail_with_error(error, 'getting ElastiCache clusters')
-
-        for cluster in clusters:
-            self.add_elasticache_cluster(cluster, region)
-
-    def get_elasticache_replication_groups_by_region(self, region):
-        ''' Makes an AWS API call to the list of ElastiCache replication groups
-        in a particular region.'''
-
-        # ElastiCache boto module doesn't provide a get_all_intances method,
-        # that's why we need to call describe directly (it would be called by
-        # the shorthand method anyway...)
-        try:
-            conn = self.connect_to_aws(elasticache, region)
-            if conn:
-                response = conn.describe_replication_groups()
-
-        except boto.exception.BotoServerError as e:
-            error = e.reason
-
-            if e.error_code == 'AuthFailure':
-                error = self.get_auth_error_message()
-            if not e.reason == "Forbidden":
-                error = "Looks like AWS ElastiCache [Replication Groups] is down:\n%s" % e.message
-            self.fail_with_error(error, 'getting ElastiCache clusters')
-
-        try:
-            # Boto also doesn't provide wrapper classes to ReplicationGroups
-            # Because of that wo can't make use of the get_list method in the
-            # AWSQueryConnection. Let's do the work manually
-            replication_groups = response['DescribeReplicationGroupsResponse']['DescribeReplicationGroupsResult']['ReplicationGroups']
-
-        except KeyError as e:
-            error = "ElastiCache [Replication Groups] query to AWS failed (unexpected format)."
-            self.fail_with_error(error, 'getting ElastiCache clusters')
-
-        for replication_group in replication_groups:
-            self.add_elasticache_replication_group(replication_group, region)
-
-    def get_auth_error_message(self):
-        ''' create an informative error message if there is an issue authenticating'''
-        errors = ["Authentication error retrieving ec2 inventory."]
-        if None in [os.environ.get('AWS_ACCESS_KEY_ID'), os.environ.get('AWS_SECRET_ACCESS_KEY')]:
-            errors.append(' - No AWS_ACCESS_KEY_ID or AWS_SECRET_ACCESS_KEY environment vars found')
-        else:
-            errors.append(' - AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY environment vars found but may not be correct')
-
-        boto_paths = ['/etc/boto.cfg', '~/.boto', '~/.aws/credentials']
-        boto_config_found = list(p for p in boto_paths if os.path.isfile(os.path.expanduser(p)))
-        if len(boto_config_found) > 0:
-            errors.append(" - Boto configs found at '%s', but the credentials contained may not be correct" % ', '.join(boto_config_found))
-        else:
-            errors.append(" - No Boto config found at any expected location '%s'" % ', '.join(boto_paths))
-
-        return '\n'.join(errors)
-
-    def fail_with_error(self, err_msg, err_operation=None):
-        '''log an error to std err for ansible-playbook to consume and exit'''
-        if err_operation:
-            err_msg = 'ERROR: "{err_msg}", while: {err_operation}'.format(
-                    err_msg=err_msg, err_operation=err_operation)
-        sys.stderr.write(err_msg)
-        sys.exit(1)
-
-    def get_instance(self, region, instance_id):
-        conn = self.connect(region)
-
-        reservations = conn.get_all_instances([instance_id])
-        for reservation in reservations:
-            for instance in reservation.instances:
-                return instance
-
-    def add_instance(self, instance, region):
-        ''' Adds an instance to the inventory and index, as long as it is
-        addressable '''
-
-        # Only return instances with desired instance states
-        if instance.state not in self.ec2_instance_states:
-            return
-
-        # Select the best destination address
-        if self.destination_format and self.destination_format_tags:
-            dest = self.destination_format.format(*[ getattr(instance, 'tags').get(tag, '') for tag in self.destination_format_tags ])
-        elif instance.subnet_id:
-            dest = getattr(instance, self.vpc_destination_variable, None)
-            if dest is None:
-                dest = getattr(instance, 'tags').get(self.vpc_destination_variable, None)
-        else:
-            dest = getattr(instance, self.destination_variable, None)
-            if dest is None:
-                dest = getattr(instance, 'tags').get(self.destination_variable, None)
-
-        if not dest:
-            # Skip instances we cannot address (e.g. private VPC subnet)
-            return
-
-        # Set the inventory name
-        hostname = None
-        if self.hostname_variable:
-            if self.hostname_variable.startswith('tag_'):
-                hostname = instance.tags.get(self.hostname_variable[4:], None)
-            else:
-                hostname = getattr(instance, self.hostname_variable)
-
-        # If we can't get a nice hostname, use the destination address
-        if not hostname:
-            hostname = dest
-        else:
-            hostname = self.to_safe(hostname).lower()
-
-        # if we only want to include hosts that match a pattern, skip those that don't
-        if self.pattern_include and not self.pattern_include.match(hostname):
-            return
-
-        # if we need to exclude hosts that match a pattern, skip those
-        if self.pattern_exclude and self.pattern_exclude.match(hostname):
-            return
-
-        # Add to index
-        self.index[hostname] = [region, instance.id]
-
-        # Inventory: Group by instance ID (always a group of 1)
-        if self.group_by_instance_id:
-            self.inventory[instance.id] = [hostname]
-            if self.nested_groups:
-                self.push_group(self.inventory, 'instances', instance.id)
-
-        # Inventory: Group by region
-        if self.group_by_region:
-            self.push(self.inventory, region, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'regions', region)
-
-        # Inventory: Group by availability zone
-        if self.group_by_availability_zone:
-            self.push(self.inventory, instance.placement, hostname)
-            if self.nested_groups:
-                if self.group_by_region:
-                    self.push_group(self.inventory, region, instance.placement)
-                self.push_group(self.inventory, 'zones', instance.placement)
-
-        # Inventory: Group by Amazon Machine Image (AMI) ID
-        if self.group_by_ami_id:
-            ami_id = self.to_safe(instance.image_id)
-            self.push(self.inventory, ami_id, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'images', ami_id)
-
-        # Inventory: Group by instance type
-        if self.group_by_instance_type:
-            type_name = self.to_safe('type_' + instance.instance_type)
-            self.push(self.inventory, type_name, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'types', type_name)
-
-        # Inventory: Group by key pair
-        if self.group_by_key_pair and instance.key_name:
-            key_name = self.to_safe('key_' + instance.key_name)
-            self.push(self.inventory, key_name, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'keys', key_name)
-
-        # Inventory: Group by VPC
-        if self.group_by_vpc_id and instance.vpc_id:
-            vpc_id_name = self.to_safe('vpc_id_' + instance.vpc_id)
-            self.push(self.inventory, vpc_id_name, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'vpcs', vpc_id_name)
-
-        # Inventory: Group by security group
-        if self.group_by_security_group:
-            try:
-                for group in instance.groups:
-                    key = self.to_safe("security_group_" + group.name)
-                    self.push(self.inventory, key, hostname)
-                    if self.nested_groups:
-                        self.push_group(self.inventory, 'security_groups', key)
-            except AttributeError:
-                self.fail_with_error('\n'.join(['Package boto seems a bit older.',
-                                                'Please upgrade boto >= 2.3.0.']))
-
-        # Inventory: Group by tag keys
-        if self.group_by_tag_keys:
-            for k, v in instance.tags.items():
-                if self.expand_csv_tags and v and ',' in v:
-                    values = map(lambda x: x.strip(), v.split(','))
-                else:
-                    values = [v]
-
-                for v in values:
-                    if v:
-                        key = self.to_safe("tag_" + k + "=" + v)
-                    else:
-                        key = self.to_safe("tag_" + k)
-                    self.push(self.inventory, key, hostname)
-                    if self.nested_groups:
-                        self.push_group(self.inventory, 'tags', self.to_safe("tag_" + k))
-                        if v:
-                            self.push_group(self.inventory, self.to_safe("tag_" + k), key)
-
-        # Inventory: Group by Route53 domain names if enabled
-        if self.route53_enabled and self.group_by_route53_names:
-            route53_names = self.get_instance_route53_names(instance)
-            for name in route53_names:
-                self.push(self.inventory, name, hostname)
-                if self.nested_groups:
-                    self.push_group(self.inventory, 'route53', name)
-
-        # Global Tag: instances without tags
-        if self.group_by_tag_none and len(instance.tags) == 0:
-            self.push(self.inventory, 'tag_none', hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'tags', 'tag_none')
-
-        # Global Tag: tag all EC2 instances
-        self.push(self.inventory, 'ec2', hostname)
-
-        self.inventory["_meta"]["hostvars"][hostname] = self.get_host_info_dict_from_instance(instance)
-        self.inventory["_meta"]["hostvars"][hostname]['ansible_ssh_host'] = dest
-
-
-    def add_rds_instance(self, instance, region):
-        ''' Adds an RDS instance to the inventory and index, as long as it is
-        addressable '''
-
-        # Only want available instances unless all_rds_instances is True
-        if not self.all_rds_instances and instance.status != 'available':
-            return
-
-        # Select the best destination address
-        dest = instance.endpoint[0]
-
-        if not dest:
-            # Skip instances we cannot address (e.g. private VPC subnet)
-            return
-
-        # Set the inventory name
-        hostname = None
-        if self.hostname_variable:
-            if self.hostname_variable.startswith('tag_'):
-                hostname = instance.tags.get(self.hostname_variable[4:], None)
-            else:
-                hostname = getattr(instance, self.hostname_variable)
-
-        # If we can't get a nice hostname, use the destination address
-        if not hostname:
-            hostname = dest
-
-        hostname = self.to_safe(hostname).lower()
-
-        # Add to index
-        self.index[hostname] = [region, instance.id]
-
-        # Inventory: Group by instance ID (always a group of 1)
-        if self.group_by_instance_id:
-            self.inventory[instance.id] = [hostname]
-            if self.nested_groups:
-                self.push_group(self.inventory, 'instances', instance.id)
-
-        # Inventory: Group by region
-        if self.group_by_region:
-            self.push(self.inventory, region, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'regions', region)
-
-        # Inventory: Group by availability zone
-        if self.group_by_availability_zone:
-            self.push(self.inventory, instance.availability_zone, hostname)
-            if self.nested_groups:
-                if self.group_by_region:
-                    self.push_group(self.inventory, region, instance.availability_zone)
-                self.push_group(self.inventory, 'zones', instance.availability_zone)
-
-        # Inventory: Group by instance type
-        if self.group_by_instance_type:
-            type_name = self.to_safe('type_' + instance.instance_class)
-            self.push(self.inventory, type_name, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'types', type_name)
-
-        # Inventory: Group by VPC
-        if self.group_by_vpc_id and instance.subnet_group and instance.subnet_group.vpc_id:
-            vpc_id_name = self.to_safe('vpc_id_' + instance.subnet_group.vpc_id)
-            self.push(self.inventory, vpc_id_name, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'vpcs', vpc_id_name)
-
-        # Inventory: Group by security group
-        if self.group_by_security_group:
-            try:
-                if instance.security_group:
-                    key = self.to_safe("security_group_" + instance.security_group.name)
-                    self.push(self.inventory, key, hostname)
-                    if self.nested_groups:
-                        self.push_group(self.inventory, 'security_groups', key)
-
-            except AttributeError:
-                self.fail_with_error('\n'.join(['Package boto seems a bit older.',
-                                                'Please upgrade boto >= 2.3.0.']))
-
-
-        # Inventory: Group by engine
-        if self.group_by_rds_engine:
-            self.push(self.inventory, self.to_safe("rds_" + instance.engine), hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'rds_engines', self.to_safe("rds_" + instance.engine))
-
-        # Inventory: Group by parameter group
-        if self.group_by_rds_parameter_group:
-            self.push(self.inventory, self.to_safe("rds_parameter_group_" + instance.parameter_group.name), hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'rds_parameter_groups', self.to_safe("rds_parameter_group_" + instance.parameter_group.name))
-
-        # Global Tag: all RDS instances
-        self.push(self.inventory, 'rds', hostname)
-
-        self.inventory["_meta"]["hostvars"][hostname] = self.get_host_info_dict_from_instance(instance)
-        self.inventory["_meta"]["hostvars"][hostname]['ansible_ssh_host'] = dest
-
-    def add_elasticache_cluster(self, cluster, region):
-        ''' Adds an ElastiCache cluster to the inventory and index, as long as
-        it's nodes are addressable '''
-
-        # Only want available clusters unless all_elasticache_clusters is True
-        if not self.all_elasticache_clusters and cluster['CacheClusterStatus'] != 'available':
-            return
-
-        # Select the best destination address
-        if 'ConfigurationEndpoint' in cluster and cluster['ConfigurationEndpoint']:
-            # Memcached cluster
-            dest = cluster['ConfigurationEndpoint']['Address']
-            is_redis = False
-        else:
-            # Redis sigle node cluster
-            # Because all Redis clusters are single nodes, we'll merge the
-            # info from the cluster with info about the node
-            dest = cluster['CacheNodes'][0]['Endpoint']['Address']
-            is_redis = True
-
-        if not dest:
-            # Skip clusters we cannot address (e.g. private VPC subnet)
-            return
-
-        # Add to index
-        self.index[dest] = [region, cluster['CacheClusterId']]
-
-        # Inventory: Group by instance ID (always a group of 1)
-        if self.group_by_instance_id:
-            self.inventory[cluster['CacheClusterId']] = [dest]
-            if self.nested_groups:
-                self.push_group(self.inventory, 'instances', cluster['CacheClusterId'])
-
-        # Inventory: Group by region
-        if self.group_by_region and not is_redis:
-            self.push(self.inventory, region, dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'regions', region)
-
-        # Inventory: Group by availability zone
-        if self.group_by_availability_zone and not is_redis:
-            self.push(self.inventory, cluster['PreferredAvailabilityZone'], dest)
-            if self.nested_groups:
-                if self.group_by_region:
-                    self.push_group(self.inventory, region, cluster['PreferredAvailabilityZone'])
-                self.push_group(self.inventory, 'zones', cluster['PreferredAvailabilityZone'])
-
-        # Inventory: Group by node type
-        if self.group_by_instance_type and not is_redis:
-            type_name = self.to_safe('type_' + cluster['CacheNodeType'])
-            self.push(self.inventory, type_name, dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'types', type_name)
-
-        # Inventory: Group by VPC (information not available in the current
-        # AWS API version for ElastiCache)
-
-        # Inventory: Group by security group
-        if self.group_by_security_group and not is_redis:
-
-            # Check for the existence of the 'SecurityGroups' key and also if
-            # this key has some value. When the cluster is not placed in a SG
-            # the query can return None here and cause an error.
-            if 'SecurityGroups' in cluster and cluster['SecurityGroups'] is not None:
-                for security_group in cluster['SecurityGroups']:
-                    key = self.to_safe("security_group_" + security_group['SecurityGroupId'])
-                    self.push(self.inventory, key, dest)
-                    if self.nested_groups:
-                        self.push_group(self.inventory, 'security_groups', key)
-
-        # Inventory: Group by engine
-        if self.group_by_elasticache_engine and not is_redis:
-            self.push(self.inventory, self.to_safe("elasticache_" + cluster['Engine']), dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'elasticache_engines', self.to_safe(cluster['Engine']))
-
-        # Inventory: Group by parameter group
-        if self.group_by_elasticache_parameter_group:
-            self.push(self.inventory, self.to_safe("elasticache_parameter_group_" + cluster['CacheParameterGroup']['CacheParameterGroupName']), dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'elasticache_parameter_groups', self.to_safe(cluster['CacheParameterGroup']['CacheParameterGroupName']))
-
-        # Inventory: Group by replication group
-        if self.group_by_elasticache_replication_group and 'ReplicationGroupId' in cluster and cluster['ReplicationGroupId']:
-            self.push(self.inventory, self.to_safe("elasticache_replication_group_" + cluster['ReplicationGroupId']), dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'elasticache_replication_groups', self.to_safe(cluster['ReplicationGroupId']))
-
-        # Global Tag: all ElastiCache clusters
-        self.push(self.inventory, 'elasticache_clusters', cluster['CacheClusterId'])
-
-        host_info = self.get_host_info_dict_from_describe_dict(cluster)
-
-        self.inventory["_meta"]["hostvars"][dest] = host_info
-
-        # Add the nodes
-        for node in cluster['CacheNodes']:
-            self.add_elasticache_node(node, cluster, region)
-
-    def add_elasticache_node(self, node, cluster, region):
-        ''' Adds an ElastiCache node to the inventory and index, as long as
-        it is addressable '''
-
-        # Only want available nodes unless all_elasticache_nodes is True
-        if not self.all_elasticache_nodes and node['CacheNodeStatus'] != 'available':
-            return
-
-        # Select the best destination address
-        dest = node['Endpoint']['Address']
-
-        if not dest:
-            # Skip nodes we cannot address (e.g. private VPC subnet)
-            return
-
-        node_id = self.to_safe(cluster['CacheClusterId'] + '_' + node['CacheNodeId'])
-
-        # Add to index
-        self.index[dest] = [region, node_id]
-
-        # Inventory: Group by node ID (always a group of 1)
-        if self.group_by_instance_id:
-            self.inventory[node_id] = [dest]
-            if self.nested_groups:
-                self.push_group(self.inventory, 'instances', node_id)
-
-        # Inventory: Group by region
-        if self.group_by_region:
-            self.push(self.inventory, region, dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'regions', region)
-
-        # Inventory: Group by availability zone
-        if self.group_by_availability_zone:
-            self.push(self.inventory, cluster['PreferredAvailabilityZone'], dest)
-            if self.nested_groups:
-                if self.group_by_region:
-                    self.push_group(self.inventory, region, cluster['PreferredAvailabilityZone'])
-                self.push_group(self.inventory, 'zones', cluster['PreferredAvailabilityZone'])
-
-        # Inventory: Group by node type
-        if self.group_by_instance_type:
-            type_name = self.to_safe('type_' + cluster['CacheNodeType'])
-            self.push(self.inventory, type_name, dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'types', type_name)
-
-        # Inventory: Group by VPC (information not available in the current
-        # AWS API version for ElastiCache)
-
-        # Inventory: Group by security group
-        if self.group_by_security_group:
-
-            # Check for the existence of the 'SecurityGroups' key and also if
-            # this key has some value. When the cluster is not placed in a SG
-            # the query can return None here and cause an error.
-            if 'SecurityGroups' in cluster and cluster['SecurityGroups'] is not None:
-                for security_group in cluster['SecurityGroups']:
-                    key = self.to_safe("security_group_" + security_group['SecurityGroupId'])
-                    self.push(self.inventory, key, dest)
-                    if self.nested_groups:
-                        self.push_group(self.inventory, 'security_groups', key)
-
-        # Inventory: Group by engine
-        if self.group_by_elasticache_engine:
-            self.push(self.inventory, self.to_safe("elasticache_" + cluster['Engine']), dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'elasticache_engines', self.to_safe("elasticache_" + cluster['Engine']))
-
-        # Inventory: Group by parameter group (done at cluster level)
-
-        # Inventory: Group by replication group (done at cluster level)
-
-        # Inventory: Group by ElastiCache Cluster
-        if self.group_by_elasticache_cluster:
-            self.push(self.inventory, self.to_safe("elasticache_cluster_" + cluster['CacheClusterId']), dest)
-
-        # Global Tag: all ElastiCache nodes
-        self.push(self.inventory, 'elasticache_nodes', dest)
-
-        host_info = self.get_host_info_dict_from_describe_dict(node)
-
-        if dest in self.inventory["_meta"]["hostvars"]:
-            self.inventory["_meta"]["hostvars"][dest].update(host_info)
-        else:
-            self.inventory["_meta"]["hostvars"][dest] = host_info
-
-    def add_elasticache_replication_group(self, replication_group, region):
-        ''' Adds an ElastiCache replication group to the inventory and index '''
-
-        # Only want available clusters unless all_elasticache_replication_groups is True
-        if not self.all_elasticache_replication_groups and replication_group['Status'] != 'available':
-            return
-
-        # Select the best destination address (PrimaryEndpoint)
-        dest = replication_group['NodeGroups'][0]['PrimaryEndpoint']['Address']
-
-        if not dest:
-            # Skip clusters we cannot address (e.g. private VPC subnet)
-            return
-
-        # Add to index
-        self.index[dest] = [region, replication_group['ReplicationGroupId']]
-
-        # Inventory: Group by ID (always a group of 1)
-        if self.group_by_instance_id:
-            self.inventory[replication_group['ReplicationGroupId']] = [dest]
-            if self.nested_groups:
-                self.push_group(self.inventory, 'instances', replication_group['ReplicationGroupId'])
-
-        # Inventory: Group by region
-        if self.group_by_region:
-            self.push(self.inventory, region, dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'regions', region)
-
-        # Inventory: Group by availability zone (doesn't apply to replication groups)
-
-        # Inventory: Group by node type (doesn't apply to replication groups)
-
-        # Inventory: Group by VPC (information not available in the current
-        # AWS API version for replication groups
-
-        # Inventory: Group by security group (doesn't apply to replication groups)
-        # Check this value in cluster level
-
-        # Inventory: Group by engine (replication groups are always Redis)
-        if self.group_by_elasticache_engine:
-            self.push(self.inventory, 'elasticache_redis', dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'elasticache_engines', 'redis')
-
-        # Global Tag: all ElastiCache clusters
-        self.push(self.inventory, 'elasticache_replication_groups', replication_group['ReplicationGroupId'])
-
-        host_info = self.get_host_info_dict_from_describe_dict(replication_group)
-
-        self.inventory["_meta"]["hostvars"][dest] = host_info
-
-    def get_route53_records(self):
-        ''' Get and store the map of resource records to domain names that
-        point to them. '''
-
-        r53_conn = route53.Route53Connection()
-        all_zones = r53_conn.get_zones()
-
-        route53_zones = [ zone for zone in all_zones if zone.name[:-1]
-                          not in self.route53_excluded_zones ]
-
-        self.route53_records = {}
-
-        for zone in route53_zones:
-            rrsets = r53_conn.get_all_rrsets(zone.id)
-
-            for record_set in rrsets:
-                record_name = record_set.name
-
-                if record_name.endswith('.'):
-                    record_name = record_name[:-1]
-
-                for resource in record_set.resource_records:
-                    self.route53_records.setdefault(resource, set())
-                    self.route53_records[resource].add(record_name)
-
-
-    def get_instance_route53_names(self, instance):
-        ''' Check if an instance is referenced in the records we have from
-        Route53. If it is, return the list of domain names pointing to said
-        instance. If nothing points to it, return an empty list. '''
-
-        instance_attributes = [ 'public_dns_name', 'private_dns_name',
-                                'ip_address', 'private_ip_address' ]
-
-        name_list = set()
-
-        for attrib in instance_attributes:
-            try:
-                value = getattr(instance, attrib)
-            except AttributeError:
-                continue
-
-            if value in self.route53_records:
-                name_list.update(self.route53_records[value])
-
-        return list(name_list)
-
-    def get_host_info_dict_from_instance(self, instance):
-        instance_vars = {}
-        for key in vars(instance):
-            value = getattr(instance, key)
-            key = self.to_safe('ec2_' + key)
-
-            # Handle complex types
-            # state/previous_state changed to properties in boto in https://github.com/boto/boto/commit/a23c379837f698212252720d2af8dec0325c9518
-            if key == 'ec2__state':
-                instance_vars['ec2_state'] = instance.state or ''
-                instance_vars['ec2_state_code'] = instance.state_code
-            elif key == 'ec2__previous_state':
-                instance_vars['ec2_previous_state'] = instance.previous_state or ''
-                instance_vars['ec2_previous_state_code'] = instance.previous_state_code
-            elif type(value) in [int, bool]:
-                instance_vars[key] = value
-            elif isinstance(value, six.string_types):
-                instance_vars[key] = value.strip()
-            elif type(value) == type(None):
-                instance_vars[key] = ''
-            elif key == 'ec2_region':
-                instance_vars[key] = value.name
-            elif key == 'ec2__placement':
-                instance_vars['ec2_placement'] = value.zone
-            elif key == 'ec2_tags':
-                for k, v in value.items():
-                    if self.expand_csv_tags and ',' in v:
-                        v = map(lambda x: x.strip(), v.split(','))
-                    key = self.to_safe('ec2_tag_' + k)
-                    instance_vars[key] = v
-            elif key == 'ec2_groups':
-                group_ids = []
-                group_names = []
-                for group in value:
-                    group_ids.append(group.id)
-                    group_names.append(group.name)
-                instance_vars["ec2_security_group_ids"] = ','.join([str(i) for i in group_ids])
-                instance_vars["ec2_security_group_names"] = ','.join([str(i) for i in group_names])
-            else:
-                pass
-                # TODO Product codes if someone finds them useful
-                #print key
-                #print type(value)
-                #print value
-
-        return instance_vars
-
-    def get_host_info_dict_from_describe_dict(self, describe_dict):
-        ''' Parses the dictionary returned by the API call into a flat list
-            of parameters. This method should be used only when 'describe' is
-            used directly because Boto doesn't provide specific classes. '''
-
-        # I really don't agree with prefixing everything with 'ec2'
-        # because EC2, RDS and ElastiCache are different services.
-        # I'm just following the pattern used until now to not break any
-        # compatibility.
-
-        host_info = {}
-        for key in describe_dict:
-            value = describe_dict[key]
-            key = self.to_safe('ec2_' + self.uncammelize(key))
-
-            # Handle complex types
-
-            # Target: Memcached Cache Clusters
-            if key == 'ec2_configuration_endpoint' and value:
-                host_info['ec2_configuration_endpoint_address'] = value['Address']
-                host_info['ec2_configuration_endpoint_port'] = value['Port']
-
-            # Target: Cache Nodes and Redis Cache Clusters (single node)
-            if key == 'ec2_endpoint' and value:
-                host_info['ec2_endpoint_address'] = value['Address']
-                host_info['ec2_endpoint_port'] = value['Port']
-
-            # Target: Redis Replication Groups
-            if key == 'ec2_node_groups' and value:
-                host_info['ec2_endpoint_address'] = value[0]['PrimaryEndpoint']['Address']
-                host_info['ec2_endpoint_port'] = value[0]['PrimaryEndpoint']['Port']
-                replica_count = 0
-                for node in value[0]['NodeGroupMembers']:
-                    if node['CurrentRole'] == 'primary':
-                        host_info['ec2_primary_cluster_address'] = node['ReadEndpoint']['Address']
-                        host_info['ec2_primary_cluster_port'] = node['ReadEndpoint']['Port']
-                        host_info['ec2_primary_cluster_id'] = node['CacheClusterId']
-                    elif node['CurrentRole'] == 'replica':
-                        host_info['ec2_replica_cluster_address_'+ str(replica_count)] = node['ReadEndpoint']['Address']
-                        host_info['ec2_replica_cluster_port_'+ str(replica_count)] = node['ReadEndpoint']['Port']
-                        host_info['ec2_replica_cluster_id_'+ str(replica_count)] = node['CacheClusterId']
-                        replica_count += 1
-
-            # Target: Redis Replication Groups
-            if key == 'ec2_member_clusters' and value:
-                host_info['ec2_member_clusters'] = ','.join([str(i) for i in value])
-
-            # Target: All Cache Clusters
-            elif key == 'ec2_cache_parameter_group':
-                host_info["ec2_cache_node_ids_to_reboot"] = ','.join([str(i) for i in value['CacheNodeIdsToReboot']])
-                host_info['ec2_cache_parameter_group_name'] = value['CacheParameterGroupName']
-                host_info['ec2_cache_parameter_apply_status'] = value['ParameterApplyStatus']
-
-            # Target: Almost everything
-            elif key == 'ec2_security_groups':
-
-                # Skip if SecurityGroups is None
-                # (it is possible to have the key defined but no value in it).
-                if value is not None:
-                    sg_ids = []
-                    for sg in value:
-                        sg_ids.append(sg['SecurityGroupId'])
-                    host_info["ec2_security_group_ids"] = ','.join([str(i) for i in sg_ids])
-
-            # Target: Everything
-            # Preserve booleans and integers
-            elif type(value) in [int, bool]:
-                host_info[key] = value
-
-            # Target: Everything
-            # Sanitize string values
-            elif isinstance(value, six.string_types):
-                host_info[key] = value.strip()
-
-            # Target: Everything
-            # Replace None by an empty string
-            elif type(value) == type(None):
-                host_info[key] = ''
-
-            else:
-                # Remove non-processed complex types
-                pass
-
-        return host_info
-
-    def get_host_info(self):
-        ''' Get variables about a specific host '''
-
-        if len(self.index) == 0:
-            # Need to load index from cache
-            self.load_index_from_cache()
-
-        if not self.args.host in self.index:
-            # try updating the cache
-            self.do_api_calls_update_cache()
-            if not self.args.host in self.index:
-                # host might not exist anymore
-                return self.json_format_dict({}, True)
-
-        (region, instance_id) = self.index[self.args.host]
-
-        instance = self.get_instance(region, instance_id)
-        return self.json_format_dict(self.get_host_info_dict_from_instance(instance), True)
-
-    def push(self, my_dict, key, element):
-        ''' Push an element onto an array that may not have been defined in
-        the dict '''
-        group_info = my_dict.setdefault(key, [])
-        if isinstance(group_info, dict):
-            host_list = group_info.setdefault('hosts', [])
-            host_list.append(element)
-        else:
-            group_info.append(element)
-
-    def push_group(self, my_dict, key, element):
-        ''' Push a group as a child of another group. '''
-        parent_group = my_dict.setdefault(key, {})
-        if not isinstance(parent_group, dict):
-            parent_group = my_dict[key] = {'hosts': parent_group}
-        child_groups = parent_group.setdefault('children', [])
-        if element not in child_groups:
-            child_groups.append(element)
-
-    def get_inventory_from_cache(self):
-        ''' Reads the inventory from the cache file and returns it as a JSON
-        object '''
-
-        cache = open(self.cache_path_cache, 'r')
-        json_inventory = cache.read()
-        return json_inventory
-
-
-    def load_index_from_cache(self):
-        ''' Reads the index from the cache file sets self.index '''
-
-        cache = open(self.cache_path_index, 'r')
-        json_index = cache.read()
-        self.index = json.loads(json_index)
-
-
-    def write_to_cache(self, data, filename):
-        ''' Writes data in JSON format to a file '''
-
-        json_data = self.json_format_dict(data, True)
-        cache = open(filename, 'w')
-        cache.write(json_data)
-        cache.close()
-
-    def uncammelize(self, key):
-        temp = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', key)
-        return re.sub('([a-z0-9])([A-Z])', r'\1_\2', temp).lower()
-
-    def to_safe(self, word):
-        ''' Converts 'bad' characters in a string to underscores so they can be used as Ansible groups '''
-        regex = "[^A-Za-z0-9\_"
-        if not self.replace_dash_in_groups:
-            regex += "\-"
-        return re.sub(regex + "]", "_", word)
-
-    def json_format_dict(self, data, pretty=False):
-        ''' Converts a dict to a JSON object and dumps it as a formatted
-        string '''
-
-        if pretty:
-            return json.dumps(data, sort_keys=True, indent=2)
-        else:
-            return json.dumps(data)
-
-
-# Run the script
-Ec2Inventory()
diff --git a/edgemicro-1601-dc1/inventory-dc2 b/edgemicro-1601-dc1/inventory-dc2
deleted file mode 100644
index 96e9880..0000000
--- a/edgemicro-1601-dc1/inventory-dc2
+++ /dev/null
@@ -1,78 +0,0 @@
-[tag_Name_dc2_n1]
-[tag_Name_dc2_n2]
-[tag_Name_dc2_n3]
-[tag_Name_dc2_n4]
-[tag_Name_dc2_n5]
-
-[tag_Name_dc2_n3:vars]
-zk_observer=true
-
-[planet:children]
-dc-1
-
-[dc-1:children]
-tag_Name_dc2_n1
-tag_Name_dc2_n2
-tag_Name_dc2_n3
-tag_Name_dc2_n4
-tag_Name_dc2_n5
-
-[ds:children]
-dc-1-ds
-
-[dc-1-ds:children]
-tag_Name_dc2_n1
-tag_Name_dc2_n2
-tag_Name_dc2_n3
-
-[ms:children]
-dc-1-ms
-
-[dc-1-ms:children]
-tag_Name_dc2_n1
-
-[ui:children]
-dc-1-ui
-
-[dc-1-ui:children]
-tag_Name_dc2_n1
-
-[ldap:children]
-dc-1-ldap
-
-[dc-1-ldap:children]
-tag_Name_dc2_n1
-
-[rmp:children]
-dc-1-rmp
-
-[dc-1-rmp:children]
-tag_Name_dc2_n2
-tag_Name_dc2_n3
-
-[qpid:children]
-dc-1-qpid
-
-[dc-1-qpid:children]
-tag_Name_dc2_n4
-tag_Name_dc2_n5
-
-[pg:children]
-dc-1-pg
-
-[dc-1-pg:children]
-dc-1-pgmaster
-dc-1-pgstandby
-
-[pgmaster:children]
-dc-1-pgmaster
-
-[dc-1-pgmaster:children]
-tag_Name_dc2_n4
-
-[pgstandby:children]
-dc-1-pgstandby
-
-[dc-1-pgstandby:children]
-tag_Name_dc2_n5
-
diff --git a/gcp-sample-inventory/gce.py b/gcp-sample-inventory/gce.py
deleted file mode 100644
index ae6b502..0000000
--- a/gcp-sample-inventory/gce.py
+++ /dev/null
@@ -1,336 +0,0 @@
-#!/usr/bin/env python
-# Copyright 2013 Google Inc.
-#
-# This file is part of Ansible
-#
-# Ansible is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# Ansible is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with Ansible.  If not, see <http://www.gnu.org/licenses/>.
-
-'''
-GCE external inventory script
-=================================
-
-Generates inventory that Ansible can understand by making API requests
-Google Compute Engine via the libcloud library.  Full install/configuration
-instructions for the gce* modules can be found in the comments of
-ansible/test/gce_tests.py.
-
-When run against a specific host, this script returns the following variables
-based on the data obtained from the libcloud Node object:
- - gce_uuid
- - gce_id
- - gce_image
- - gce_machine_type
- - gce_private_ip
- - gce_public_ip
- - gce_name
- - gce_description
- - gce_status
- - gce_zone
- - gce_tags
- - gce_metadata
- - gce_network
-
-When run in --list mode, instances are grouped by the following categories:
- - zone:
-   zone group name examples are us-central1-b, europe-west1-a, etc.
- - instance tags:
-   An entry is created for each tag.  For example, if you have two instances
-   with a common tag called 'foo', they will both be grouped together under
-   the 'tag_foo' name.
- - network name:
-   the name of the network is appended to 'network_' (e.g. the 'default'
-   network will result in a group named 'network_default')
- - machine type
-   types follow a pattern like n1-standard-4, g1-small, etc.
- - running status:
-   group name prefixed with 'status_' (e.g. status_running, status_stopped,..)
- - image:
-   when using an ephemeral/scratch disk, this will be set to the image name
-   used when creating the instance (e.g. debian-7-wheezy-v20130816).  when
-   your instance was created with a root persistent disk it will be set to
-   'persistent_disk' since there is no current way to determine the image.
-
-Examples:
-  Execute uname on all instances in the us-central1-a zone
-  $ ansible -i gce.py us-central1-a -m shell -a "/bin/uname -a"
-
-  Use the GCE inventory script to print out instance specific information
-  $ contrib/inventory/gce.py --host my_instance
-
-Author: Eric Johnson <erjohnso@google.com>
-Contributors: Matt Hite <mhite@hotmail.com>
-Version: 0.0.2
-'''
-
-__requires__ = ['pycrypto>=2.6']
-try:
-    import pkg_resources
-except ImportError:
-    # Use pkg_resources to find the correct versions of libraries and set
-    # sys.path appropriately when there are multiversion installs.  We don't
-    # fail here as there is code that better expresses the errors where the
-    # library is used.
-    pass
-
-USER_AGENT_PRODUCT="Ansible-gce_inventory_plugin"
-USER_AGENT_VERSION="v2"
-
-import sys
-import os
-import argparse
-import ConfigParser
-
-import logging
-logging.getLogger('libcloud.common.google').addHandler(logging.NullHandler())
-
-try:
-    import json
-except ImportError:
-    import simplejson as json
-
-try:
-    from libcloud.compute.types import Provider
-    from libcloud.compute.providers import get_driver
-    _ = Provider.GCE
-except:
-    print("GCE inventory script requires libcloud >= 0.13")
-    sys.exit(1)
-
-
-class GceInventory(object):
-    def __init__(self):
-        # Read settings and parse CLI arguments
-        self.parse_cli_args()
-        self.config = self.get_config()
-        self.driver = self.get_gce_driver()
-        self.ip_type = self.get_inventory_options()
-        if self.ip_type:
-            self.ip_type = self.ip_type.lower()
-
-        # Just display data for specific host
-        if self.args.host:
-            print(self.json_format_dict(self.node_to_dict(
-                self.get_instance(self.args.host)),
-                pretty=self.args.pretty))
-            sys.exit(0)
-
-        # Otherwise, assume user wants all instances grouped
-        print(self.json_format_dict(self.group_instances(),
-                                    pretty=self.args.pretty))
-        sys.exit(0)
-
-    def get_config(self):
-        """
-        Populates a SafeConfigParser object with defaults and
-        attempts to read an .ini-style configuration from the filename
-        specified in GCE_INI_PATH. If the environment variable is
-        not present, the filename defaults to gce.ini in the current
-        working directory.
-        """
-        gce_ini_default_path = os.path.join(
-            os.path.dirname(os.path.realpath(__file__)), "gce.ini")
-        gce_ini_path = os.environ.get('GCE_INI_PATH', gce_ini_default_path)
-
-        # Create a ConfigParser.
-        # This provides empty defaults to each key, so that environment
-        # variable configuration (as opposed to INI configuration) is able
-        # to work.
-        config = ConfigParser.SafeConfigParser(defaults={
-            'gce_service_account_email_address': '',
-            'gce_service_account_pem_file_path': '',
-            'gce_project_id': '',
-            'libcloud_secrets': '',
-            'inventory_ip_type': '',
-        })
-        if 'gce' not in config.sections():
-            config.add_section('gce')
-        if 'inventory' not in config.sections():
-            config.add_section('inventory')
-
-        config.read(gce_ini_path)
-        return config
-
-    def get_inventory_options(self):
-        """Determine inventory options. Environment variables always
-        take precedence over configuration files."""
-        ip_type = self.config.get('inventory', 'inventory_ip_type')
-        # If the appropriate environment variables are set, they override
-        # other configuration
-        ip_type = os.environ.get('INVENTORY_IP_TYPE', ip_type)
-        return ip_type
-
-    def get_gce_driver(self):
-        """Determine the GCE authorization settings and return a
-        libcloud driver.
-        """
-        # Attempt to get GCE params from a configuration file, if one
-        # exists.
-        secrets_path = self.config.get('gce', 'libcloud_secrets')
-        secrets_found = False
-        try:
-            import secrets
-            args = list(getattr(secrets, 'GCE_PARAMS', []))
-            kwargs = getattr(secrets, 'GCE_KEYWORD_PARAMS', {})
-            secrets_found = True
-        except:
-            pass
-
-        if not secrets_found and secrets_path:
-            if not secrets_path.endswith('secrets.py'):
-                err = "Must specify libcloud secrets file as "
-                err += "/absolute/path/to/secrets.py"
-                print(err)
-                sys.exit(1)
-            sys.path.append(os.path.dirname(secrets_path))
-            try:
-                import secrets
-                args = list(getattr(secrets, 'GCE_PARAMS', []))
-                kwargs = getattr(secrets, 'GCE_KEYWORD_PARAMS', {})
-                secrets_found = True
-            except:
-                pass
-        if not secrets_found:
-            args = [
-                self.config.get('gce','gce_service_account_email_address'),
-                self.config.get('gce','gce_service_account_pem_file_path')
-            ]
-            kwargs = {'project': self.config.get('gce', 'gce_project_id')}
-
-        # If the appropriate environment variables are set, they override
-        # other configuration; process those into our args and kwargs.
-        args[0] = os.environ.get('GCE_EMAIL', args[0])
-        args[1] = os.environ.get('GCE_PEM_FILE_PATH', args[1])
-        kwargs['project'] = os.environ.get('GCE_PROJECT', kwargs['project'])
-
-        # Retrieve and return the GCE driver.
-        gce = get_driver(Provider.GCE)(*args, **kwargs)
-        gce.connection.user_agent_append(
-            '%s/%s' % (USER_AGENT_PRODUCT, USER_AGENT_VERSION),
-            )
-        return gce
-
-    def parse_cli_args(self):
-        ''' Command line argument processing '''
-
-        parser = argparse.ArgumentParser(
-            description='Produce an Ansible Inventory file based on GCE')
-        parser.add_argument('--list', action='store_true', default=True,
-                            help='List instances (default: True)')
-        parser.add_argument('--host', action='store',
-                            help='Get all information about an instance')
-        parser.add_argument('--pretty', action='store_true', default=False,
-                            help='Pretty format (default: False)')
-        self.args = parser.parse_args()
-
-
-    def node_to_dict(self, inst):
-        md = {}
-
-        if inst is None:
-            return {}
-
-        if inst.extra['metadata'].has_key('items'):
-            for entry in inst.extra['metadata']['items']:
-                md[entry['key']] = entry['value']
-
-        net = inst.extra['networkInterfaces'][0]['network'].split('/')[-1]
-        # default to exernal IP unless user has specified they prefer internal
-        if self.ip_type == 'internal':
-            ssh_host = inst.private_ips[0]
-        else:
-            ssh_host = inst.public_ips[0] if len(inst.public_ips) >= 1 else inst.private_ips[0]
-
-        return {
-            'gce_uuid': inst.uuid,
-            'gce_id': inst.id,
-            'gce_image': inst.image,
-            'gce_machine_type': inst.size,
-            'gce_private_ip': inst.private_ips[0],
-            'gce_public_ip': inst.public_ips[0] if len(inst.public_ips) >= 1 else None,
-            'gce_name': inst.name,
-            'gce_description': inst.extra['description'],
-            'gce_status': inst.extra['status'],
-            'gce_zone': inst.extra['zone'].name,
-            'gce_tags': inst.extra['tags'],
-            'gce_metadata': md,
-            'gce_network': net,
-            # Hosts don't have a public name, so we add an IP
-            'ansible_ssh_host': ssh_host
-        }
-
-    def get_instance(self, instance_name):
-        '''Gets details about a specific instance '''
-        try:
-            return self.driver.ex_get_node(instance_name)
-        except Exception as e:
-            return None
-
-    def group_instances(self):
-        '''Group all instances'''
-        groups = {}
-        meta = {}
-        meta["hostvars"] = {}
-
-        for node in self.driver.list_nodes():
-            name = node.name
-
-            meta["hostvars"][name] = self.node_to_dict(node)
-
-            zone = node.extra['zone'].name
-            if groups.has_key(zone): groups[zone].append(name)
-            else: groups[zone] = [name]
-
-            tags = node.extra['tags']
-            for t in tags:
-                if t.startswith('group-'):
-                    tag = t[6:]
-                else:
-                    tag = 'tag_%s' % t
-                if groups.has_key(tag): groups[tag].append(name)
-                else: groups[tag] = [name]
-
-            net = node.extra['networkInterfaces'][0]['network'].split('/')[-1]
-            net = 'network_%s' % net
-            if groups.has_key(net): groups[net].append(name)
-            else: groups[net] = [name]
-
-            machine_type = node.size
-            if groups.has_key(machine_type): groups[machine_type].append(name)
-            else: groups[machine_type] = [name]
-
-            image = node.image and node.image or 'persistent_disk'
-            if groups.has_key(image): groups[image].append(name)
-            else: groups[image] = [name]
-
-            status = node.extra['status']
-            stat = 'status_%s' % status.lower()
-            if groups.has_key(stat): groups[stat].append(name)
-            else: groups[stat] = [name]
-
-        groups["_meta"] = meta
-
-        return groups
-
-    def json_format_dict(self, data, pretty=False):
-        ''' Converts a dict to a JSON object and dumps it as a formatted
-        string '''
-
-        if pretty:
-            return json.dumps(data, sort_keys=True, indent=2)
-        else:
-            return json.dumps(data)
-
-
-# Run the script
-GceInventory()
\ No newline at end of file
diff --git a/portal-1701-dc7/ec2.ini b/portal-1701-dc7/ec2.ini
deleted file mode 100644
index 36b3921..0000000
--- a/portal-1701-dc7/ec2.ini
+++ /dev/null
@@ -1,200 +0,0 @@
-# Ansible EC2 external inventory script settings
-#
-
-[ec2]
-
-# to talk to a private eucalyptus instance uncomment these lines
-# and edit edit eucalyptus_host to be the host name of your cloud controller
-#eucalyptus = True
-#eucalyptus_host = clc.cloud.domain.org
-
-# AWS regions to make calls to. Set this to 'all' to make request to all regions
-# in AWS and merge the results together. Alternatively, set this to a comma
-# separated list of regions. E.g. 'us-east-1,us-west-1,us-west-2'
-regions = all
-regions_exclude = us-gov-west-1,cn-north-1
-
-# When generating inventory, Ansible needs to know how to address a server.
-# Each EC2 instance has a lot of variables associated with it. Here is the list:
-#   http://docs.pythonboto.org/en/latest/ref/ec2.html#module-boto.ec2.instance
-# Below are 2 variables that are used as the address of a server:
-#   - destination_variable
-#   - vpc_destination_variable
-
-# This is the normal destination variable to use. If you are running Ansible
-# from outside EC2, then 'public_dns_name' makes the most sense. If you are
-# running Ansible from within EC2, then perhaps you want to use the internal
-# address, and should set this to 'private_dns_name'. The key of an EC2 tag
-# may optionally be used; however the boto instance variables hold precedence
-# in the event of a collision.
-destination_variable = public_dns_name
-
-# This allows you to override the inventory_name with an ec2 variable, instead
-# of using the destination_variable above. Addressing (aka ansible_ssh_host)
-# will still use destination_variable. Tags should be written as 'tag_TAGNAME'.
-#hostname_variable = tag_Name
-
-# For server inside a VPC, using DNS names may not make sense. When an instance
-# has 'subnet_id' set, this variable is used. If the subnet is public, setting
-# this to 'ip_address' will return the public IP address. For instances in a
-# private subnet, this should be set to 'private_ip_address', and Ansible must
-# be run from within EC2. The key of an EC2 tag may optionally be used; however
-# the boto instance variables hold precedence in the event of a collision.
-# WARNING: - instances that are in the private vpc, _without_ public ip address
-# will not be listed in the inventory until You set:
-# vpc_destination_variable = private_ip_address
-vpc_destination_variable = ip_address
-
-# The following two settings allow flexible ansible host naming based on a
-# python format string and a comma-separated list of ec2 tags.  Note that:
-#
-# 1) If the tags referenced are not present for some instances, empty strings
-#    will be substituted in the format string.
-# 2) This overrides both destination_variable and vpc_destination_variable.
-#
-#destination_format = {0}.{1}.example.com
-#destination_format_tags = Name,environment
-
-# To tag instances on EC2 with the resource records that point to them from
-# Route53, uncomment and set 'route53' to True.
-route53 = False
-
-# To exclude RDS instances from the inventory, uncomment and set to False.
-rds = False
-
-# To exclude ElastiCache instances from the inventory, uncomment and set to False.
-elasticache = False
-
-# Additionally, you can specify the list of zones to exclude looking up in
-# 'route53_excluded_zones' as a comma-separated list.
-# route53_excluded_zones = samplezone1.com, samplezone2.com
-
-# By default, only EC2 instances in the 'running' state are returned. Set
-# 'all_instances' to True to return all instances regardless of state.
-all_instances = True
-
-# By default, only EC2 instances in the 'running' state are returned. Specify
-# EC2 instance states to return as a comma-separated list. This
-# option is overriden when 'all_instances' is True.
-# instance_states = pending, running, shutting-down, terminated, stopping, stopped
-
-# By default, only RDS instances in the 'available' state are returned.  Set
-# 'all_rds_instances' to True return all RDS instances regardless of state.
-all_rds_instances = False
-
-# By default, only ElastiCache clusters and nodes in the 'available' state
-# are returned. Set 'all_elasticache_clusters' and/or 'all_elastic_nodes'
-# to True return all ElastiCache clusters and nodes, regardless of state.
-#
-# Note that all_elasticache_nodes only applies to listed clusters. That means
-# if you set all_elastic_clusters to false, no node will be return from
-# unavailable clusters, regardless of the state and to what you set for
-# all_elasticache_nodes.
-all_elasticache_replication_groups = False
-all_elasticache_clusters = False
-all_elasticache_nodes = False
-
-# API calls to EC2 are slow. For this reason, we cache the results of an API
-# call. Set this to the path you want cache files to be written to. Two files
-# will be written to this directory:
-#   - ansible-ec2.cache
-#   - ansible-ec2.index
-cache_path = ~/.ansible/tmp
-
-# The number of seconds a cache file is considered valid. After this many
-# seconds, a new API call will be made, and the cache file will be updated.
-# To disable the cache, set this value to 0
-cache_max_age = 300
-
-# Organize groups into a nested/hierarchy instead of a flat namespace.
-nested_groups = False
-
-# Replace - tags when creating groups to avoid issues with ansible
-replace_dash_in_groups = True
-
-# If set to true, any tag of the form "a,b,c" is expanded into a list
-# and the results are used to create additional tag_* inventory groups.
-expand_csv_tags = False
-
-# The EC2 inventory output can become very large. To manage its size,
-# configure which groups should be created.
-group_by_instance_id = True
-group_by_region = True
-group_by_availability_zone = True
-group_by_ami_id = True
-group_by_instance_type = True
-group_by_key_pair = True
-group_by_vpc_id = True
-group_by_security_group = True
-group_by_tag_keys = True
-group_by_tag_none = True
-group_by_route53_names = True
-group_by_rds_engine = False
-group_by_rds_parameter_group = False
-group_by_elasticache_engine = True
-group_by_elasticache_cluster = True
-group_by_elasticache_parameter_group = True
-group_by_elasticache_replication_group = True
-
-# If you only want to include hosts that match a certain regular expression
-# pattern_include = staging-*
-
-# If you want to exclude any hosts that match a certain regular expression
-# pattern_exclude = staging-*
-# Ansible EC2 external inventory script settings
-#
-
-##[ec2]
-##
-### to talk to a private eucalyptus instance uncomment these lines
-### and edit edit eucalyptus_host to be the host name of your cloud controller
-###eucalyptus = True
-###eucalyptus_host = clc.cloud.domain.org
-##
-### AWS regions to make calls to. Set this to 'all' to make request to all regions
-##
-### in AWS and merge the results together. Alternatively, set this to a comma
-### separated list of regions. E.g. 'us-east-1,us-west-1,us-west-2'
-##regions = all
-##regions_exclude = us-gov-west-1,cn-north-1
-##
-### When generating inventory, Ansible needs to know how to address a server.
-### Each EC2 instance has a lot of variables associated with it. Here is the list:
-###   http://docs.pythonboto.org/en/latest/ref/ec2.html#module-boto.ec2.instance
-### Below are 2 variables that are used as the address of a server:
-###   - destination_variable
-###   - vpc_destination_variable
-##
-### This is the normal destination variable to use. If you are running Ansible
-### from outside EC2, then 'public_dns_name' makes the most sense. If you are
-### running Ansible from within EC2, then perhaps you want to use the internal
-### address, and should set this to 'private_dns_name'. The key of an EC2 tag
-##...skipping...
-### pattern_include = staging-*
-##
-### If you want to exclude any hosts that match a certain regular expression
-### pattern_exclude = staging-*
-
-# Instance filters can be used to control which instances are retrieved for
-# inventory. For the full list of possible filters, please read the EC2 API
-# docs: http://docs.aws.amazon.com/AWSEC2/latest/APIReference/ApiReference-query-DescribeInstances.html#query-DescribeInstances-filters
-# Filters are key/value pairs separated by '=', to list multiple filters use
-# a list separated by commas. See examples below.
-
-# Retrieve only instances with (key=value) env=staging tag
-# instance_filters = tag:env=staging
-
-# Retrieve only instances with role=webservers OR role=dbservers tag
-# instance_filters = tag:role=webservers,tag:role=dbservers
-
-# Retrieve only t1.micro instances OR instances with tag env=staging
-# instance_filters = instance-type=t1.micro,tag:env=staging
-
-# You can use wildcards in filter values also. Below will list instances which
-# tag Name value matches webservers1*
-# (ex. webservers15, webservers1a, webservers123 etc)
-# instance_filters = tag:Name=webservers1*
-
-# A boto configuration profile may be used to separate out credentials
-# see http://boto.readthedocs.org/en/latest/boto_config_tut.html
-# boto_profile = some-boto-profile-name
diff --git a/portal-1701-dc7/ec2.py b/portal-1701-dc7/ec2.py
deleted file mode 100755
index f30958a..0000000
--- a/portal-1701-dc7/ec2.py
+++ /dev/null
@@ -1,1385 +0,0 @@
-#!/usr/bin/env python
-
-'''
-EC2 external inventory script
-=================================
-
-Generates inventory that Ansible can understand by making API request to
-AWS EC2 using the Boto library.
-
-NOTE: This script assumes Ansible is being executed where the environment
-variables needed for Boto have already been set:
-    export AWS_ACCESS_KEY_ID='AK123'
-    export AWS_SECRET_ACCESS_KEY='abc123'
-
-This script also assumes there is an ec2.ini file alongside it.  To specify a
-different path to ec2.ini, define the EC2_INI_PATH environment variable:
-
-    export EC2_INI_PATH=/path/to/my_ec2.ini
-
-If you're using eucalyptus you need to set the above variables and
-you need to define:
-
-    export EC2_URL=http://hostname_of_your_cc:port/services/Eucalyptus
-
-If you're using boto profiles (requires boto>=2.24.0) you can choose a profile
-using the --boto-profile command line argument (e.g. ec2.py --boto-profile prod) or using
-the AWS_PROFILE variable:
-
-    AWS_PROFILE=prod ansible-playbook -i ec2.py myplaybook.yml
-
-For more details, see: http://docs.pythonboto.org/en/latest/boto_config_tut.html
-
-When run against a specific host, this script returns the following variables:
- - ec2_ami_launch_index
- - ec2_architecture
- - ec2_association
- - ec2_attachTime
- - ec2_attachment
- - ec2_attachmentId
- - ec2_client_token
- - ec2_deleteOnTermination
- - ec2_description
- - ec2_deviceIndex
- - ec2_dns_name
- - ec2_eventsSet
- - ec2_group_name
- - ec2_hypervisor
- - ec2_id
- - ec2_image_id
- - ec2_instanceState
- - ec2_instance_type
- - ec2_ipOwnerId
- - ec2_ip_address
- - ec2_item
- - ec2_kernel
- - ec2_key_name
- - ec2_launch_time
- - ec2_monitored
- - ec2_monitoring
- - ec2_networkInterfaceId
- - ec2_ownerId
- - ec2_persistent
- - ec2_placement
- - ec2_platform
- - ec2_previous_state
- - ec2_private_dns_name
- - ec2_private_ip_address
- - ec2_publicIp
- - ec2_public_dns_name
- - ec2_ramdisk
- - ec2_reason
- - ec2_region
- - ec2_requester_id
- - ec2_root_device_name
- - ec2_root_device_type
- - ec2_security_group_ids
- - ec2_security_group_names
- - ec2_shutdown_state
- - ec2_sourceDestCheck
- - ec2_spot_instance_request_id
- - ec2_state
- - ec2_state_code
- - ec2_state_reason
- - ec2_status
- - ec2_subnet_id
- - ec2_tenancy
- - ec2_virtualization_type
- - ec2_vpc_id
-
-These variables are pulled out of a boto.ec2.instance object. There is a lack of
-consistency with variable spellings (camelCase and underscores) since this
-just loops through all variables the object exposes. It is preferred to use the
-ones with underscores when multiple exist.
-
-In addition, if an instance has AWS Tags associated with it, each tag is a new
-variable named:
- - ec2_tag_[Key] = [Value]
-
-Security groups are comma-separated in 'ec2_security_group_ids' and
-'ec2_security_group_names'.
-'''
-
-# (c) 2012, Peter Sankauskas
-#
-# This file is part of Ansible,
-#
-# Ansible is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# Ansible is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with Ansible.  If not, see <http://www.gnu.org/licenses/>.
-
-######################################################################
-
-import sys
-import os
-import argparse
-import re
-from time import time
-import boto
-from boto import ec2
-from boto import rds
-from boto import elasticache
-from boto import route53
-import six
-
-from six.moves import configparser
-from collections import defaultdict
-
-try:
-    import json
-except ImportError:
-    import simplejson as json
-
-
-class Ec2Inventory(object):
-
-    def _empty_inventory(self):
-        return {"_meta" : {"hostvars" : {}}}
-
-    def __init__(self):
-        ''' Main execution path '''
-
-        # Inventory grouped by instance IDs, tags, security groups, regions,
-        # and availability zones
-        self.inventory = self._empty_inventory()
-
-        # Index of hostname (address) to instance ID
-        self.index = {}
-
-        # Boto profile to use (if any)
-        self.boto_profile = None
-
-        # Read settings and parse CLI arguments
-        self.parse_cli_args()
-        self.read_settings()
-
-        # Make sure that profile_name is not passed at all if not set
-        # as pre 2.24 boto will fall over otherwise
-        if self.boto_profile:
-            if not hasattr(boto.ec2.EC2Connection, 'profile_name'):
-                self.fail_with_error("boto version must be >= 2.24 to use profile")
-
-        # Cache
-        if self.args.refresh_cache:
-            self.do_api_calls_update_cache()
-        elif not self.is_cache_valid():
-            self.do_api_calls_update_cache()
-
-        # Data to print
-        if self.args.host:
-            data_to_print = self.get_host_info()
-
-        elif self.args.list:
-            # Display list of instances for inventory
-            if self.inventory == self._empty_inventory():
-                data_to_print = self.get_inventory_from_cache()
-            else:
-                data_to_print = self.json_format_dict(self.inventory, True)
-
-        print(data_to_print)
-
-
-    def is_cache_valid(self):
-        ''' Determines if the cache files have expired, or if it is still valid '''
-
-        if os.path.isfile(self.cache_path_cache):
-            mod_time = os.path.getmtime(self.cache_path_cache)
-            current_time = time()
-            if (mod_time + self.cache_max_age) > current_time:
-                if os.path.isfile(self.cache_path_index):
-                    return True
-
-        return False
-
-
-    def read_settings(self):
-        ''' Reads the settings from the ec2.ini file '''
-        if six.PY3:
-            config = configparser.ConfigParser()
-        else:
-            config = configparser.SafeConfigParser()
-        ec2_default_ini_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'ec2.ini')
-        ec2_ini_path = os.path.expanduser(os.path.expandvars(os.environ.get('EC2_INI_PATH', ec2_default_ini_path)))
-        config.read(ec2_ini_path)
-
-        # is eucalyptus?
-        self.eucalyptus_host = None
-        self.eucalyptus = False
-        if config.has_option('ec2', 'eucalyptus'):
-            self.eucalyptus = config.getboolean('ec2', 'eucalyptus')
-        if self.eucalyptus and config.has_option('ec2', 'eucalyptus_host'):
-            self.eucalyptus_host = config.get('ec2', 'eucalyptus_host')
-
-        # Regions
-        self.regions = []
-        configRegions = config.get('ec2', 'regions')
-        configRegions_exclude = config.get('ec2', 'regions_exclude')
-        if (configRegions == 'all'):
-            if self.eucalyptus_host:
-                self.regions.append(boto.connect_euca(host=self.eucalyptus_host).region.name)
-            else:
-                for regionInfo in ec2.regions():
-                    if regionInfo.name not in configRegions_exclude:
-                        self.regions.append(regionInfo.name)
-        else:
-            self.regions = configRegions.split(",")
-
-        # Destination addresses
-        self.destination_variable = config.get('ec2', 'destination_variable')
-        self.vpc_destination_variable = config.get('ec2', 'vpc_destination_variable')
-
-        if config.has_option('ec2', 'hostname_variable'):
-            self.hostname_variable = config.get('ec2', 'hostname_variable')
-        else:
-            self.hostname_variable = None
-
-        if config.has_option('ec2', 'destination_format') and \
-                config.has_option('ec2', 'destination_format_tags'):
-            self.destination_format = config.get('ec2', 'destination_format')
-            self.destination_format_tags = config.get('ec2', 'destination_format_tags').split(',')
-        else:
-            self.destination_format = None
-            self.destination_format_tags = None
-
-        # Route53
-        self.route53_enabled = config.getboolean('ec2', 'route53')
-        self.route53_excluded_zones = []
-        if config.has_option('ec2', 'route53_excluded_zones'):
-            self.route53_excluded_zones.extend(
-                    config.get('ec2', 'route53_excluded_zones', '').split(','))
-
-        # Include RDS instances?
-        self.rds_enabled = True
-        if config.has_option('ec2', 'rds'):
-            self.rds_enabled = config.getboolean('ec2', 'rds')
-
-        # Include ElastiCache instances?
-        self.elasticache_enabled = True
-        if config.has_option('ec2', 'elasticache'):
-            self.elasticache_enabled = config.getboolean('ec2', 'elasticache')
-
-        # Return all EC2 instances?
-        if config.has_option('ec2', 'all_instances'):
-            self.all_instances = config.getboolean('ec2', 'all_instances')
-        else:
-            self.all_instances = False
-
-        # Instance states to be gathered in inventory. Default is 'running'.
-        # Setting 'all_instances' to 'yes' overrides this option.
-        ec2_valid_instance_states = [
-            'pending',
-            'running',
-            'shutting-down',
-            'terminated',
-            'stopping',
-            'stopped'
-        ]
-        self.ec2_instance_states = []
-        if self.all_instances:
-            self.ec2_instance_states = ec2_valid_instance_states
-        elif config.has_option('ec2', 'instance_states'):
-            for instance_state in config.get('ec2', 'instance_states').split(','):
-                instance_state = instance_state.strip()
-                if instance_state not in ec2_valid_instance_states:
-                    continue
-                self.ec2_instance_states.append(instance_state)
-        else:
-            self.ec2_instance_states = ['running']
-
-        # Return all RDS instances? (if RDS is enabled)
-        if config.has_option('ec2', 'all_rds_instances') and self.rds_enabled:
-            self.all_rds_instances = config.getboolean('ec2', 'all_rds_instances')
-        else:
-            self.all_rds_instances = False
-
-        # Return all ElastiCache replication groups? (if ElastiCache is enabled)
-        if config.has_option('ec2', 'all_elasticache_replication_groups') and self.elasticache_enabled:
-            self.all_elasticache_replication_groups = config.getboolean('ec2', 'all_elasticache_replication_groups')
-        else:
-            self.all_elasticache_replication_groups = False
-
-        # Return all ElastiCache clusters? (if ElastiCache is enabled)
-        if config.has_option('ec2', 'all_elasticache_clusters') and self.elasticache_enabled:
-            self.all_elasticache_clusters = config.getboolean('ec2', 'all_elasticache_clusters')
-        else:
-            self.all_elasticache_clusters = False
-
-        # Return all ElastiCache nodes? (if ElastiCache is enabled)
-        if config.has_option('ec2', 'all_elasticache_nodes') and self.elasticache_enabled:
-            self.all_elasticache_nodes = config.getboolean('ec2', 'all_elasticache_nodes')
-        else:
-            self.all_elasticache_nodes = False
-
-        # boto configuration profile (prefer CLI argument)
-        self.boto_profile = self.args.boto_profile
-        if config.has_option('ec2', 'boto_profile') and not self.boto_profile:
-            self.boto_profile = config.get('ec2', 'boto_profile')
-
-        # Cache related
-        cache_dir = os.path.expanduser(config.get('ec2', 'cache_path'))
-        if self.boto_profile:
-            cache_dir = os.path.join(cache_dir, 'profile_' + self.boto_profile)
-        if not os.path.exists(cache_dir):
-            os.makedirs(cache_dir)
-
-        cache_name = 'ansible-ec2'
-        aws_profile = lambda: (self.boto_profile or
-                               os.environ.get('AWS_PROFILE') or
-                               os.environ.get('AWS_ACCESS_KEY_ID'))
-        if aws_profile():
-            cache_name = '%s-%s' % (cache_name, aws_profile())
-        self.cache_path_cache = cache_dir + "/%s.cache" % cache_name
-        self.cache_path_index = cache_dir + "/%s.index" % cache_name
-        self.cache_max_age = config.getint('ec2', 'cache_max_age')
-
-        if config.has_option('ec2', 'expand_csv_tags'):
-            self.expand_csv_tags = config.getboolean('ec2', 'expand_csv_tags')
-        else:
-            self.expand_csv_tags = False
-
-        # Configure nested groups instead of flat namespace.
-        if config.has_option('ec2', 'nested_groups'):
-            self.nested_groups = config.getboolean('ec2', 'nested_groups')
-        else:
-            self.nested_groups = False
-
-        # Replace dash or not in group names
-        if config.has_option('ec2', 'replace_dash_in_groups'):
-            self.replace_dash_in_groups = config.getboolean('ec2', 'replace_dash_in_groups')
-        else:
-            self.replace_dash_in_groups = True
-
-        # Configure which groups should be created.
-        group_by_options = [
-            'group_by_instance_id',
-            'group_by_region',
-            'group_by_availability_zone',
-            'group_by_ami_id',
-            'group_by_instance_type',
-            'group_by_key_pair',
-            'group_by_vpc_id',
-            'group_by_security_group',
-            'group_by_tag_keys',
-            'group_by_tag_none',
-            'group_by_route53_names',
-            'group_by_rds_engine',
-            'group_by_rds_parameter_group',
-            'group_by_elasticache_engine',
-            'group_by_elasticache_cluster',
-            'group_by_elasticache_parameter_group',
-            'group_by_elasticache_replication_group',
-        ]
-        for option in group_by_options:
-            if config.has_option('ec2', option):
-                setattr(self, option, config.getboolean('ec2', option))
-            else:
-                setattr(self, option, True)
-
-        # Do we need to just include hosts that match a pattern?
-        try:
-            pattern_include = config.get('ec2', 'pattern_include')
-            if pattern_include and len(pattern_include) > 0:
-                self.pattern_include = re.compile(pattern_include)
-            else:
-                self.pattern_include = None
-        except configparser.NoOptionError:
-            self.pattern_include = None
-
-        # Do we need to exclude hosts that match a pattern?
-        try:
-            pattern_exclude = config.get('ec2', 'pattern_exclude');
-            if pattern_exclude and len(pattern_exclude) > 0:
-                self.pattern_exclude = re.compile(pattern_exclude)
-            else:
-                self.pattern_exclude = None
-        except configparser.NoOptionError:
-            self.pattern_exclude = None
-
-        # Instance filters (see boto and EC2 API docs). Ignore invalid filters.
-        self.ec2_instance_filters = defaultdict(list)
-        if config.has_option('ec2', 'instance_filters'):
-
-            filters = [f for f in config.get('ec2', 'instance_filters').split(',') if f]
-
-            for instance_filter in filters:
-                instance_filter = instance_filter.strip()
-                if not instance_filter or '=' not in instance_filter:
-                    continue
-                filter_key, filter_value = [x.strip() for x in instance_filter.split('=', 1)]
-                if not filter_key:
-                    continue
-                self.ec2_instance_filters[filter_key].append(filter_value)
-
-    def parse_cli_args(self):
-        ''' Command line argument processing '''
-
-        parser = argparse.ArgumentParser(description='Produce an Ansible Inventory file based on EC2')
-        parser.add_argument('--list', action='store_true', default=True,
-                            help='List instances (default: True)')
-        parser.add_argument('--host', action='store',
-                            help='Get all the variables about a specific instance')
-        parser.add_argument('--refresh-cache', action='store_true', default=False,
-                            help='Force refresh of cache by making API requests to EC2 (default: False - use cache files)')
-        parser.add_argument('--profile', '--boto-profile', action='store', dest='boto_profile',
-                            help='Use boto profile for connections to EC2')
-        self.args = parser.parse_args()
-
-
-    def do_api_calls_update_cache(self):
-        ''' Do API calls to each region, and save data in cache files '''
-
-        if self.route53_enabled:
-            self.get_route53_records()
-
-        for region in self.regions:
-            self.get_instances_by_region(region)
-            if self.rds_enabled:
-                self.get_rds_instances_by_region(region)
-            if self.elasticache_enabled:
-                self.get_elasticache_clusters_by_region(region)
-                self.get_elasticache_replication_groups_by_region(region)
-
-        self.write_to_cache(self.inventory, self.cache_path_cache)
-        self.write_to_cache(self.index, self.cache_path_index)
-
-    def connect(self, region):
-        ''' create connection to api server'''
-        if self.eucalyptus:
-            conn = boto.connect_euca(host=self.eucalyptus_host)
-            conn.APIVersion = '2010-08-31'
-        else:
-            conn = self.connect_to_aws(ec2, region)
-        return conn
-
-    def boto_fix_security_token_in_profile(self, connect_args):
-        ''' monkey patch for boto issue boto/boto#2100 '''
-        profile = 'profile ' + self.boto_profile
-        if boto.config.has_option(profile, 'aws_security_token'):
-            connect_args['security_token'] = boto.config.get(profile, 'aws_security_token')
-        return connect_args
-
-    def connect_to_aws(self, module, region):
-        connect_args = {}
-
-        # only pass the profile name if it's set (as it is not supported by older boto versions)
-        if self.boto_profile:
-            connect_args['profile_name'] = self.boto_profile
-            self.boto_fix_security_token_in_profile(connect_args)
-
-        conn = module.connect_to_region(region, **connect_args)
-        # connect_to_region will fail "silently" by returning None if the region name is wrong or not supported
-        if conn is None:
-            self.fail_with_error("region name: %s likely not supported, or AWS is down.  connection to region failed." % region)
-        return conn
-
-    def get_instances_by_region(self, region):
-        ''' Makes an AWS EC2 API call to the list of instances in a particular
-        region '''
-
-        try:
-            conn = self.connect(region)
-            reservations = []
-            if self.ec2_instance_filters:
-                for filter_key, filter_values in self.ec2_instance_filters.items():
-                    reservations.extend(conn.get_all_instances(filters = { filter_key : filter_values }))
-            else:
-                reservations = conn.get_all_instances()
-
-            for reservation in reservations:
-                for instance in reservation.instances:
-                    self.add_instance(instance, region)
-
-        except boto.exception.BotoServerError as e:
-            if e.error_code == 'AuthFailure':
-                error = self.get_auth_error_message()
-            else:
-                backend = 'Eucalyptus' if self.eucalyptus else 'AWS'
-                error = "Error connecting to %s backend.\n%s" % (backend, e.message)
-            self.fail_with_error(error, 'getting EC2 instances')
-
-    def get_rds_instances_by_region(self, region):
-        ''' Makes an AWS API call to the list of RDS instances in a particular
-        region '''
-
-        try:
-            conn = self.connect_to_aws(rds, region)
-            if conn:
-                marker = None
-                while True:
-                    instances = conn.get_all_dbinstances(marker=marker)
-                    marker = instances.marker
-                    for instance in instances:
-                        self.add_rds_instance(instance, region)
-                    if not marker:
-                        break
-        except boto.exception.BotoServerError as e:
-            error = e.reason
-
-            if e.error_code == 'AuthFailure':
-                error = self.get_auth_error_message()
-            if not e.reason == "Forbidden":
-                error = "Looks like AWS RDS is down:\n%s" % e.message
-            self.fail_with_error(error, 'getting RDS instances')
-
-    def get_elasticache_clusters_by_region(self, region):
-        ''' Makes an AWS API call to the list of ElastiCache clusters (with
-        nodes' info) in a particular region.'''
-
-        # ElastiCache boto module doesn't provide a get_all_intances method,
-        # that's why we need to call describe directly (it would be called by
-        # the shorthand method anyway...)
-        try:
-            conn = self.connect_to_aws(elasticache, region)
-            if conn:
-                # show_cache_node_info = True
-                # because we also want nodes' information
-                response = conn.describe_cache_clusters(None, None, None, True)
-
-        except boto.exception.BotoServerError as e:
-            error = e.reason
-
-            if e.error_code == 'AuthFailure':
-                error = self.get_auth_error_message()
-            if not e.reason == "Forbidden":
-                error = "Looks like AWS ElastiCache is down:\n%s" % e.message
-            self.fail_with_error(error, 'getting ElastiCache clusters')
-
-        try:
-            # Boto also doesn't provide wrapper classes to CacheClusters or
-            # CacheNodes. Because of that wo can't make use of the get_list
-            # method in the AWSQueryConnection. Let's do the work manually
-            clusters = response['DescribeCacheClustersResponse']['DescribeCacheClustersResult']['CacheClusters']
-
-        except KeyError as e:
-            error = "ElastiCache query to AWS failed (unexpected format)."
-            self.fail_with_error(error, 'getting ElastiCache clusters')
-
-        for cluster in clusters:
-            self.add_elasticache_cluster(cluster, region)
-
-    def get_elasticache_replication_groups_by_region(self, region):
-        ''' Makes an AWS API call to the list of ElastiCache replication groups
-        in a particular region.'''
-
-        # ElastiCache boto module doesn't provide a get_all_intances method,
-        # that's why we need to call describe directly (it would be called by
-        # the shorthand method anyway...)
-        try:
-            conn = self.connect_to_aws(elasticache, region)
-            if conn:
-                response = conn.describe_replication_groups()
-
-        except boto.exception.BotoServerError as e:
-            error = e.reason
-
-            if e.error_code == 'AuthFailure':
-                error = self.get_auth_error_message()
-            if not e.reason == "Forbidden":
-                error = "Looks like AWS ElastiCache [Replication Groups] is down:\n%s" % e.message
-            self.fail_with_error(error, 'getting ElastiCache clusters')
-
-        try:
-            # Boto also doesn't provide wrapper classes to ReplicationGroups
-            # Because of that wo can't make use of the get_list method in the
-            # AWSQueryConnection. Let's do the work manually
-            replication_groups = response['DescribeReplicationGroupsResponse']['DescribeReplicationGroupsResult']['ReplicationGroups']
-
-        except KeyError as e:
-            error = "ElastiCache [Replication Groups] query to AWS failed (unexpected format)."
-            self.fail_with_error(error, 'getting ElastiCache clusters')
-
-        for replication_group in replication_groups:
-            self.add_elasticache_replication_group(replication_group, region)
-
-    def get_auth_error_message(self):
-        ''' create an informative error message if there is an issue authenticating'''
-        errors = ["Authentication error retrieving ec2 inventory."]
-        if None in [os.environ.get('AWS_ACCESS_KEY_ID'), os.environ.get('AWS_SECRET_ACCESS_KEY')]:
-            errors.append(' - No AWS_ACCESS_KEY_ID or AWS_SECRET_ACCESS_KEY environment vars found')
-        else:
-            errors.append(' - AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY environment vars found but may not be correct')
-
-        boto_paths = ['/etc/boto.cfg', '~/.boto', '~/.aws/credentials']
-        boto_config_found = list(p for p in boto_paths if os.path.isfile(os.path.expanduser(p)))
-        if len(boto_config_found) > 0:
-            errors.append(" - Boto configs found at '%s', but the credentials contained may not be correct" % ', '.join(boto_config_found))
-        else:
-            errors.append(" - No Boto config found at any expected location '%s'" % ', '.join(boto_paths))
-
-        return '\n'.join(errors)
-
-    def fail_with_error(self, err_msg, err_operation=None):
-        '''log an error to std err for ansible-playbook to consume and exit'''
-        if err_operation:
-            err_msg = 'ERROR: "{err_msg}", while: {err_operation}'.format(
-                    err_msg=err_msg, err_operation=err_operation)
-        sys.stderr.write(err_msg)
-        sys.exit(1)
-
-    def get_instance(self, region, instance_id):
-        conn = self.connect(region)
-
-        reservations = conn.get_all_instances([instance_id])
-        for reservation in reservations:
-            for instance in reservation.instances:
-                return instance
-
-    def add_instance(self, instance, region):
-        ''' Adds an instance to the inventory and index, as long as it is
-        addressable '''
-
-        # Only return instances with desired instance states
-        if instance.state not in self.ec2_instance_states:
-            return
-
-        # Select the best destination address
-        if self.destination_format and self.destination_format_tags:
-            dest = self.destination_format.format(*[ getattr(instance, 'tags').get(tag, '') for tag in self.destination_format_tags ])
-        elif instance.subnet_id:
-            dest = getattr(instance, self.vpc_destination_variable, None)
-            if dest is None:
-                dest = getattr(instance, 'tags').get(self.vpc_destination_variable, None)
-        else:
-            dest = getattr(instance, self.destination_variable, None)
-            if dest is None:
-                dest = getattr(instance, 'tags').get(self.destination_variable, None)
-
-        if not dest:
-            # Skip instances we cannot address (e.g. private VPC subnet)
-            return
-
-        # Set the inventory name
-        hostname = None
-        if self.hostname_variable:
-            if self.hostname_variable.startswith('tag_'):
-                hostname = instance.tags.get(self.hostname_variable[4:], None)
-            else:
-                hostname = getattr(instance, self.hostname_variable)
-
-        # If we can't get a nice hostname, use the destination address
-        if not hostname:
-            hostname = dest
-        else:
-            hostname = self.to_safe(hostname).lower()
-
-        # if we only want to include hosts that match a pattern, skip those that don't
-        if self.pattern_include and not self.pattern_include.match(hostname):
-            return
-
-        # if we need to exclude hosts that match a pattern, skip those
-        if self.pattern_exclude and self.pattern_exclude.match(hostname):
-            return
-
-        # Add to index
-        self.index[hostname] = [region, instance.id]
-
-        # Inventory: Group by instance ID (always a group of 1)
-        if self.group_by_instance_id:
-            self.inventory[instance.id] = [hostname]
-            if self.nested_groups:
-                self.push_group(self.inventory, 'instances', instance.id)
-
-        # Inventory: Group by region
-        if self.group_by_region:
-            self.push(self.inventory, region, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'regions', region)
-
-        # Inventory: Group by availability zone
-        if self.group_by_availability_zone:
-            self.push(self.inventory, instance.placement, hostname)
-            if self.nested_groups:
-                if self.group_by_region:
-                    self.push_group(self.inventory, region, instance.placement)
-                self.push_group(self.inventory, 'zones', instance.placement)
-
-        # Inventory: Group by Amazon Machine Image (AMI) ID
-        if self.group_by_ami_id:
-            ami_id = self.to_safe(instance.image_id)
-            self.push(self.inventory, ami_id, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'images', ami_id)
-
-        # Inventory: Group by instance type
-        if self.group_by_instance_type:
-            type_name = self.to_safe('type_' + instance.instance_type)
-            self.push(self.inventory, type_name, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'types', type_name)
-
-        # Inventory: Group by key pair
-        if self.group_by_key_pair and instance.key_name:
-            key_name = self.to_safe('key_' + instance.key_name)
-            self.push(self.inventory, key_name, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'keys', key_name)
-
-        # Inventory: Group by VPC
-        if self.group_by_vpc_id and instance.vpc_id:
-            vpc_id_name = self.to_safe('vpc_id_' + instance.vpc_id)
-            self.push(self.inventory, vpc_id_name, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'vpcs', vpc_id_name)
-
-        # Inventory: Group by security group
-        if self.group_by_security_group:
-            try:
-                for group in instance.groups:
-                    key = self.to_safe("security_group_" + group.name)
-                    self.push(self.inventory, key, hostname)
-                    if self.nested_groups:
-                        self.push_group(self.inventory, 'security_groups', key)
-            except AttributeError:
-                self.fail_with_error('\n'.join(['Package boto seems a bit older.',
-                                                'Please upgrade boto >= 2.3.0.']))
-
-        # Inventory: Group by tag keys
-        if self.group_by_tag_keys:
-            for k, v in instance.tags.items():
-                if self.expand_csv_tags and v and ',' in v:
-                    values = map(lambda x: x.strip(), v.split(','))
-                else:
-                    values = [v]
-
-                for v in values:
-                    if v:
-                        key = self.to_safe("tag_" + k + "=" + v)
-                    else:
-                        key = self.to_safe("tag_" + k)
-                    self.push(self.inventory, key, hostname)
-                    if self.nested_groups:
-                        self.push_group(self.inventory, 'tags', self.to_safe("tag_" + k))
-                        if v:
-                            self.push_group(self.inventory, self.to_safe("tag_" + k), key)
-
-        # Inventory: Group by Route53 domain names if enabled
-        if self.route53_enabled and self.group_by_route53_names:
-            route53_names = self.get_instance_route53_names(instance)
-            for name in route53_names:
-                self.push(self.inventory, name, hostname)
-                if self.nested_groups:
-                    self.push_group(self.inventory, 'route53', name)
-
-        # Global Tag: instances without tags
-        if self.group_by_tag_none and len(instance.tags) == 0:
-            self.push(self.inventory, 'tag_none', hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'tags', 'tag_none')
-
-        # Global Tag: tag all EC2 instances
-        self.push(self.inventory, 'ec2', hostname)
-
-        self.inventory["_meta"]["hostvars"][hostname] = self.get_host_info_dict_from_instance(instance)
-        self.inventory["_meta"]["hostvars"][hostname]['ansible_ssh_host'] = dest
-
-
-    def add_rds_instance(self, instance, region):
-        ''' Adds an RDS instance to the inventory and index, as long as it is
-        addressable '''
-
-        # Only want available instances unless all_rds_instances is True
-        if not self.all_rds_instances and instance.status != 'available':
-            return
-
-        # Select the best destination address
-        dest = instance.endpoint[0]
-
-        if not dest:
-            # Skip instances we cannot address (e.g. private VPC subnet)
-            return
-
-        # Set the inventory name
-        hostname = None
-        if self.hostname_variable:
-            if self.hostname_variable.startswith('tag_'):
-                hostname = instance.tags.get(self.hostname_variable[4:], None)
-            else:
-                hostname = getattr(instance, self.hostname_variable)
-
-        # If we can't get a nice hostname, use the destination address
-        if not hostname:
-            hostname = dest
-
-        hostname = self.to_safe(hostname).lower()
-
-        # Add to index
-        self.index[hostname] = [region, instance.id]
-
-        # Inventory: Group by instance ID (always a group of 1)
-        if self.group_by_instance_id:
-            self.inventory[instance.id] = [hostname]
-            if self.nested_groups:
-                self.push_group(self.inventory, 'instances', instance.id)
-
-        # Inventory: Group by region
-        if self.group_by_region:
-            self.push(self.inventory, region, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'regions', region)
-
-        # Inventory: Group by availability zone
-        if self.group_by_availability_zone:
-            self.push(self.inventory, instance.availability_zone, hostname)
-            if self.nested_groups:
-                if self.group_by_region:
-                    self.push_group(self.inventory, region, instance.availability_zone)
-                self.push_group(self.inventory, 'zones', instance.availability_zone)
-
-        # Inventory: Group by instance type
-        if self.group_by_instance_type:
-            type_name = self.to_safe('type_' + instance.instance_class)
-            self.push(self.inventory, type_name, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'types', type_name)
-
-        # Inventory: Group by VPC
-        if self.group_by_vpc_id and instance.subnet_group and instance.subnet_group.vpc_id:
-            vpc_id_name = self.to_safe('vpc_id_' + instance.subnet_group.vpc_id)
-            self.push(self.inventory, vpc_id_name, hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'vpcs', vpc_id_name)
-
-        # Inventory: Group by security group
-        if self.group_by_security_group:
-            try:
-                if instance.security_group:
-                    key = self.to_safe("security_group_" + instance.security_group.name)
-                    self.push(self.inventory, key, hostname)
-                    if self.nested_groups:
-                        self.push_group(self.inventory, 'security_groups', key)
-
-            except AttributeError:
-                self.fail_with_error('\n'.join(['Package boto seems a bit older.',
-                                                'Please upgrade boto >= 2.3.0.']))
-
-
-        # Inventory: Group by engine
-        if self.group_by_rds_engine:
-            self.push(self.inventory, self.to_safe("rds_" + instance.engine), hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'rds_engines', self.to_safe("rds_" + instance.engine))
-
-        # Inventory: Group by parameter group
-        if self.group_by_rds_parameter_group:
-            self.push(self.inventory, self.to_safe("rds_parameter_group_" + instance.parameter_group.name), hostname)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'rds_parameter_groups', self.to_safe("rds_parameter_group_" + instance.parameter_group.name))
-
-        # Global Tag: all RDS instances
-        self.push(self.inventory, 'rds', hostname)
-
-        self.inventory["_meta"]["hostvars"][hostname] = self.get_host_info_dict_from_instance(instance)
-        self.inventory["_meta"]["hostvars"][hostname]['ansible_ssh_host'] = dest
-
-    def add_elasticache_cluster(self, cluster, region):
-        ''' Adds an ElastiCache cluster to the inventory and index, as long as
-        it's nodes are addressable '''
-
-        # Only want available clusters unless all_elasticache_clusters is True
-        if not self.all_elasticache_clusters and cluster['CacheClusterStatus'] != 'available':
-            return
-
-        # Select the best destination address
-        if 'ConfigurationEndpoint' in cluster and cluster['ConfigurationEndpoint']:
-            # Memcached cluster
-            dest = cluster['ConfigurationEndpoint']['Address']
-            is_redis = False
-        else:
-            # Redis sigle node cluster
-            # Because all Redis clusters are single nodes, we'll merge the
-            # info from the cluster with info about the node
-            dest = cluster['CacheNodes'][0]['Endpoint']['Address']
-            is_redis = True
-
-        if not dest:
-            # Skip clusters we cannot address (e.g. private VPC subnet)
-            return
-
-        # Add to index
-        self.index[dest] = [region, cluster['CacheClusterId']]
-
-        # Inventory: Group by instance ID (always a group of 1)
-        if self.group_by_instance_id:
-            self.inventory[cluster['CacheClusterId']] = [dest]
-            if self.nested_groups:
-                self.push_group(self.inventory, 'instances', cluster['CacheClusterId'])
-
-        # Inventory: Group by region
-        if self.group_by_region and not is_redis:
-            self.push(self.inventory, region, dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'regions', region)
-
-        # Inventory: Group by availability zone
-        if self.group_by_availability_zone and not is_redis:
-            self.push(self.inventory, cluster['PreferredAvailabilityZone'], dest)
-            if self.nested_groups:
-                if self.group_by_region:
-                    self.push_group(self.inventory, region, cluster['PreferredAvailabilityZone'])
-                self.push_group(self.inventory, 'zones', cluster['PreferredAvailabilityZone'])
-
-        # Inventory: Group by node type
-        if self.group_by_instance_type and not is_redis:
-            type_name = self.to_safe('type_' + cluster['CacheNodeType'])
-            self.push(self.inventory, type_name, dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'types', type_name)
-
-        # Inventory: Group by VPC (information not available in the current
-        # AWS API version for ElastiCache)
-
-        # Inventory: Group by security group
-        if self.group_by_security_group and not is_redis:
-
-            # Check for the existence of the 'SecurityGroups' key and also if
-            # this key has some value. When the cluster is not placed in a SG
-            # the query can return None here and cause an error.
-            if 'SecurityGroups' in cluster and cluster['SecurityGroups'] is not None:
-                for security_group in cluster['SecurityGroups']:
-                    key = self.to_safe("security_group_" + security_group['SecurityGroupId'])
-                    self.push(self.inventory, key, dest)
-                    if self.nested_groups:
-                        self.push_group(self.inventory, 'security_groups', key)
-
-        # Inventory: Group by engine
-        if self.group_by_elasticache_engine and not is_redis:
-            self.push(self.inventory, self.to_safe("elasticache_" + cluster['Engine']), dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'elasticache_engines', self.to_safe(cluster['Engine']))
-
-        # Inventory: Group by parameter group
-        if self.group_by_elasticache_parameter_group:
-            self.push(self.inventory, self.to_safe("elasticache_parameter_group_" + cluster['CacheParameterGroup']['CacheParameterGroupName']), dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'elasticache_parameter_groups', self.to_safe(cluster['CacheParameterGroup']['CacheParameterGroupName']))
-
-        # Inventory: Group by replication group
-        if self.group_by_elasticache_replication_group and 'ReplicationGroupId' in cluster and cluster['ReplicationGroupId']:
-            self.push(self.inventory, self.to_safe("elasticache_replication_group_" + cluster['ReplicationGroupId']), dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'elasticache_replication_groups', self.to_safe(cluster['ReplicationGroupId']))
-
-        # Global Tag: all ElastiCache clusters
-        self.push(self.inventory, 'elasticache_clusters', cluster['CacheClusterId'])
-
-        host_info = self.get_host_info_dict_from_describe_dict(cluster)
-
-        self.inventory["_meta"]["hostvars"][dest] = host_info
-
-        # Add the nodes
-        for node in cluster['CacheNodes']:
-            self.add_elasticache_node(node, cluster, region)
-
-    def add_elasticache_node(self, node, cluster, region):
-        ''' Adds an ElastiCache node to the inventory and index, as long as
-        it is addressable '''
-
-        # Only want available nodes unless all_elasticache_nodes is True
-        if not self.all_elasticache_nodes and node['CacheNodeStatus'] != 'available':
-            return
-
-        # Select the best destination address
-        dest = node['Endpoint']['Address']
-
-        if not dest:
-            # Skip nodes we cannot address (e.g. private VPC subnet)
-            return
-
-        node_id = self.to_safe(cluster['CacheClusterId'] + '_' + node['CacheNodeId'])
-
-        # Add to index
-        self.index[dest] = [region, node_id]
-
-        # Inventory: Group by node ID (always a group of 1)
-        if self.group_by_instance_id:
-            self.inventory[node_id] = [dest]
-            if self.nested_groups:
-                self.push_group(self.inventory, 'instances', node_id)
-
-        # Inventory: Group by region
-        if self.group_by_region:
-            self.push(self.inventory, region, dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'regions', region)
-
-        # Inventory: Group by availability zone
-        if self.group_by_availability_zone:
-            self.push(self.inventory, cluster['PreferredAvailabilityZone'], dest)
-            if self.nested_groups:
-                if self.group_by_region:
-                    self.push_group(self.inventory, region, cluster['PreferredAvailabilityZone'])
-                self.push_group(self.inventory, 'zones', cluster['PreferredAvailabilityZone'])
-
-        # Inventory: Group by node type
-        if self.group_by_instance_type:
-            type_name = self.to_safe('type_' + cluster['CacheNodeType'])
-            self.push(self.inventory, type_name, dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'types', type_name)
-
-        # Inventory: Group by VPC (information not available in the current
-        # AWS API version for ElastiCache)
-
-        # Inventory: Group by security group
-        if self.group_by_security_group:
-
-            # Check for the existence of the 'SecurityGroups' key and also if
-            # this key has some value. When the cluster is not placed in a SG
-            # the query can return None here and cause an error.
-            if 'SecurityGroups' in cluster and cluster['SecurityGroups'] is not None:
-                for security_group in cluster['SecurityGroups']:
-                    key = self.to_safe("security_group_" + security_group['SecurityGroupId'])
-                    self.push(self.inventory, key, dest)
-                    if self.nested_groups:
-                        self.push_group(self.inventory, 'security_groups', key)
-
-        # Inventory: Group by engine
-        if self.group_by_elasticache_engine:
-            self.push(self.inventory, self.to_safe("elasticache_" + cluster['Engine']), dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'elasticache_engines', self.to_safe("elasticache_" + cluster['Engine']))
-
-        # Inventory: Group by parameter group (done at cluster level)
-
-        # Inventory: Group by replication group (done at cluster level)
-
-        # Inventory: Group by ElastiCache Cluster
-        if self.group_by_elasticache_cluster:
-            self.push(self.inventory, self.to_safe("elasticache_cluster_" + cluster['CacheClusterId']), dest)
-
-        # Global Tag: all ElastiCache nodes
-        self.push(self.inventory, 'elasticache_nodes', dest)
-
-        host_info = self.get_host_info_dict_from_describe_dict(node)
-
-        if dest in self.inventory["_meta"]["hostvars"]:
-            self.inventory["_meta"]["hostvars"][dest].update(host_info)
-        else:
-            self.inventory["_meta"]["hostvars"][dest] = host_info
-
-    def add_elasticache_replication_group(self, replication_group, region):
-        ''' Adds an ElastiCache replication group to the inventory and index '''
-
-        # Only want available clusters unless all_elasticache_replication_groups is True
-        if not self.all_elasticache_replication_groups and replication_group['Status'] != 'available':
-            return
-
-        # Select the best destination address (PrimaryEndpoint)
-        dest = replication_group['NodeGroups'][0]['PrimaryEndpoint']['Address']
-
-        if not dest:
-            # Skip clusters we cannot address (e.g. private VPC subnet)
-            return
-
-        # Add to index
-        self.index[dest] = [region, replication_group['ReplicationGroupId']]
-
-        # Inventory: Group by ID (always a group of 1)
-        if self.group_by_instance_id:
-            self.inventory[replication_group['ReplicationGroupId']] = [dest]
-            if self.nested_groups:
-                self.push_group(self.inventory, 'instances', replication_group['ReplicationGroupId'])
-
-        # Inventory: Group by region
-        if self.group_by_region:
-            self.push(self.inventory, region, dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'regions', region)
-
-        # Inventory: Group by availability zone (doesn't apply to replication groups)
-
-        # Inventory: Group by node type (doesn't apply to replication groups)
-
-        # Inventory: Group by VPC (information not available in the current
-        # AWS API version for replication groups
-
-        # Inventory: Group by security group (doesn't apply to replication groups)
-        # Check this value in cluster level
-
-        # Inventory: Group by engine (replication groups are always Redis)
-        if self.group_by_elasticache_engine:
-            self.push(self.inventory, 'elasticache_redis', dest)
-            if self.nested_groups:
-                self.push_group(self.inventory, 'elasticache_engines', 'redis')
-
-        # Global Tag: all ElastiCache clusters
-        self.push(self.inventory, 'elasticache_replication_groups', replication_group['ReplicationGroupId'])
-
-        host_info = self.get_host_info_dict_from_describe_dict(replication_group)
-
-        self.inventory["_meta"]["hostvars"][dest] = host_info
-
-    def get_route53_records(self):
-        ''' Get and store the map of resource records to domain names that
-        point to them. '''
-
-        r53_conn = route53.Route53Connection()
-        all_zones = r53_conn.get_zones()
-
-        route53_zones = [ zone for zone in all_zones if zone.name[:-1]
-                          not in self.route53_excluded_zones ]
-
-        self.route53_records = {}
-
-        for zone in route53_zones:
-            rrsets = r53_conn.get_all_rrsets(zone.id)
-
-            for record_set in rrsets:
-                record_name = record_set.name
-
-                if record_name.endswith('.'):
-                    record_name = record_name[:-1]
-
-                for resource in record_set.resource_records:
-                    self.route53_records.setdefault(resource, set())
-                    self.route53_records[resource].add(record_name)
-
-
-    def get_instance_route53_names(self, instance):
-        ''' Check if an instance is referenced in the records we have from
-        Route53. If it is, return the list of domain names pointing to said
-        instance. If nothing points to it, return an empty list. '''
-
-        instance_attributes = [ 'public_dns_name', 'private_dns_name',
-                                'ip_address', 'private_ip_address' ]
-
-        name_list = set()
-
-        for attrib in instance_attributes:
-            try:
-                value = getattr(instance, attrib)
-            except AttributeError:
-                continue
-
-            if value in self.route53_records:
-                name_list.update(self.route53_records[value])
-
-        return list(name_list)
-
-    def get_host_info_dict_from_instance(self, instance):
-        instance_vars = {}
-        for key in vars(instance):
-            value = getattr(instance, key)
-            key = self.to_safe('ec2_' + key)
-
-            # Handle complex types
-            # state/previous_state changed to properties in boto in https://github.com/boto/boto/commit/a23c379837f698212252720d2af8dec0325c9518
-            if key == 'ec2__state':
-                instance_vars['ec2_state'] = instance.state or ''
-                instance_vars['ec2_state_code'] = instance.state_code
-            elif key == 'ec2__previous_state':
-                instance_vars['ec2_previous_state'] = instance.previous_state or ''
-                instance_vars['ec2_previous_state_code'] = instance.previous_state_code
-            elif type(value) in [int, bool]:
-                instance_vars[key] = value
-            elif isinstance(value, six.string_types):
-                instance_vars[key] = value.strip()
-            elif type(value) == type(None):
-                instance_vars[key] = ''
-            elif key == 'ec2_region':
-                instance_vars[key] = value.name
-            elif key == 'ec2__placement':
-                instance_vars['ec2_placement'] = value.zone
-            elif key == 'ec2_tags':
-                for k, v in value.items():
-                    if self.expand_csv_tags and ',' in v:
-                        v = map(lambda x: x.strip(), v.split(','))
-                    key = self.to_safe('ec2_tag_' + k)
-                    instance_vars[key] = v
-            elif key == 'ec2_groups':
-                group_ids = []
-                group_names = []
-                for group in value:
-                    group_ids.append(group.id)
-                    group_names.append(group.name)
-                instance_vars["ec2_security_group_ids"] = ','.join([str(i) for i in group_ids])
-                instance_vars["ec2_security_group_names"] = ','.join([str(i) for i in group_names])
-            else:
-                pass
-                # TODO Product codes if someone finds them useful
-                #print key
-                #print type(value)
-                #print value
-
-        return instance_vars
-
-    def get_host_info_dict_from_describe_dict(self, describe_dict):
-        ''' Parses the dictionary returned by the API call into a flat list
-            of parameters. This method should be used only when 'describe' is
-            used directly because Boto doesn't provide specific classes. '''
-
-        # I really don't agree with prefixing everything with 'ec2'
-        # because EC2, RDS and ElastiCache are different services.
-        # I'm just following the pattern used until now to not break any
-        # compatibility.
-
-        host_info = {}
-        for key in describe_dict:
-            value = describe_dict[key]
-            key = self.to_safe('ec2_' + self.uncammelize(key))
-
-            # Handle complex types
-
-            # Target: Memcached Cache Clusters
-            if key == 'ec2_configuration_endpoint' and value:
-                host_info['ec2_configuration_endpoint_address'] = value['Address']
-                host_info['ec2_configuration_endpoint_port'] = value['Port']
-
-            # Target: Cache Nodes and Redis Cache Clusters (single node)
-            if key == 'ec2_endpoint' and value:
-                host_info['ec2_endpoint_address'] = value['Address']
-                host_info['ec2_endpoint_port'] = value['Port']
-
-            # Target: Redis Replication Groups
-            if key == 'ec2_node_groups' and value:
-                host_info['ec2_endpoint_address'] = value[0]['PrimaryEndpoint']['Address']
-                host_info['ec2_endpoint_port'] = value[0]['PrimaryEndpoint']['Port']
-                replica_count = 0
-                for node in value[0]['NodeGroupMembers']:
-                    if node['CurrentRole'] == 'primary':
-                        host_info['ec2_primary_cluster_address'] = node['ReadEndpoint']['Address']
-                        host_info['ec2_primary_cluster_port'] = node['ReadEndpoint']['Port']
-                        host_info['ec2_primary_cluster_id'] = node['CacheClusterId']
-                    elif node['CurrentRole'] == 'replica':
-                        host_info['ec2_replica_cluster_address_'+ str(replica_count)] = node['ReadEndpoint']['Address']
-                        host_info['ec2_replica_cluster_port_'+ str(replica_count)] = node['ReadEndpoint']['Port']
-                        host_info['ec2_replica_cluster_id_'+ str(replica_count)] = node['CacheClusterId']
-                        replica_count += 1
-
-            # Target: Redis Replication Groups
-            if key == 'ec2_member_clusters' and value:
-                host_info['ec2_member_clusters'] = ','.join([str(i) for i in value])
-
-            # Target: All Cache Clusters
-            elif key == 'ec2_cache_parameter_group':
-                host_info["ec2_cache_node_ids_to_reboot"] = ','.join([str(i) for i in value['CacheNodeIdsToReboot']])
-                host_info['ec2_cache_parameter_group_name'] = value['CacheParameterGroupName']
-                host_info['ec2_cache_parameter_apply_status'] = value['ParameterApplyStatus']
-
-            # Target: Almost everything
-            elif key == 'ec2_security_groups':
-
-                # Skip if SecurityGroups is None
-                # (it is possible to have the key defined but no value in it).
-                if value is not None:
-                    sg_ids = []
-                    for sg in value:
-                        sg_ids.append(sg['SecurityGroupId'])
-                    host_info["ec2_security_group_ids"] = ','.join([str(i) for i in sg_ids])
-
-            # Target: Everything
-            # Preserve booleans and integers
-            elif type(value) in [int, bool]:
-                host_info[key] = value
-
-            # Target: Everything
-            # Sanitize string values
-            elif isinstance(value, six.string_types):
-                host_info[key] = value.strip()
-
-            # Target: Everything
-            # Replace None by an empty string
-            elif type(value) == type(None):
-                host_info[key] = ''
-
-            else:
-                # Remove non-processed complex types
-                pass
-
-        return host_info
-
-    def get_host_info(self):
-        ''' Get variables about a specific host '''
-
-        if len(self.index) == 0:
-            # Need to load index from cache
-            self.load_index_from_cache()
-
-        if not self.args.host in self.index:
-            # try updating the cache
-            self.do_api_calls_update_cache()
-            if not self.args.host in self.index:
-                # host might not exist anymore
-                return self.json_format_dict({}, True)
-
-        (region, instance_id) = self.index[self.args.host]
-
-        instance = self.get_instance(region, instance_id)
-        return self.json_format_dict(self.get_host_info_dict_from_instance(instance), True)
-
-    def push(self, my_dict, key, element):
-        ''' Push an element onto an array that may not have been defined in
-        the dict '''
-        group_info = my_dict.setdefault(key, [])
-        if isinstance(group_info, dict):
-            host_list = group_info.setdefault('hosts', [])
-            host_list.append(element)
-        else:
-            group_info.append(element)
-
-    def push_group(self, my_dict, key, element):
-        ''' Push a group as a child of another group. '''
-        parent_group = my_dict.setdefault(key, {})
-        if not isinstance(parent_group, dict):
-            parent_group = my_dict[key] = {'hosts': parent_group}
-        child_groups = parent_group.setdefault('children', [])
-        if element not in child_groups:
-            child_groups.append(element)
-
-    def get_inventory_from_cache(self):
-        ''' Reads the inventory from the cache file and returns it as a JSON
-        object '''
-
-        cache = open(self.cache_path_cache, 'r')
-        json_inventory = cache.read()
-        return json_inventory
-
-
-    def load_index_from_cache(self):
-        ''' Reads the index from the cache file sets self.index '''
-
-        cache = open(self.cache_path_index, 'r')
-        json_index = cache.read()
-        self.index = json.loads(json_index)
-
-
-    def write_to_cache(self, data, filename):
-        ''' Writes data in JSON format to a file '''
-
-        json_data = self.json_format_dict(data, True)
-        cache = open(filename, 'w')
-        cache.write(json_data)
-        cache.close()
-
-    def uncammelize(self, key):
-        temp = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', key)
-        return re.sub('([a-z0-9])([A-Z])', r'\1_\2', temp).lower()
-
-    def to_safe(self, word):
-        ''' Converts 'bad' characters in a string to underscores so they can be used as Ansible groups '''
-        regex = "[^A-Za-z0-9\_"
-        if not self.replace_dash_in_groups:
-            regex += "\-"
-        return re.sub(regex + "]", "_", word)
-
-    def json_format_dict(self, data, pretty=False):
-        ''' Converts a dict to a JSON object and dumps it as a formatted
-        string '''
-
-        if pretty:
-            return json.dumps(data, sort_keys=True, indent=2)
-        else:
-            return json.dumps(data)
-
-
-# Run the script
-Ec2Inventory()
diff --git a/portal-1701-dc7/inventory b/portal-1701-dc7/inventory
deleted file mode 100644
index fbdd439..0000000
--- a/portal-1701-dc7/inventory
+++ /dev/null
@@ -1,43 +0,0 @@
-[tag_Name_dc7_n21]
-[tag_Name_dc7_n22]
-[tag_Name_dc7_n9]
-[tag_Name_dc7_n10]
-[tag_Name_dc7_n4]
-
-[planet:children]
-dc-1
-
-[dc-1:children]
-tag_Name_dc7_n21
-tag_Name_dc7_n22
-tag_Name_dc7_n9
-tag_Name_dc7_n10
-tag_Name_dc7_n4
-
-[ms:children]
-dc-1-ms
-
-[dc-1-ms:children]
-tag_Name_dc7_n4
-
-[portal:children]
-tag_Name_dc7_n21
-
-[pg:children]
-dc-1-pg
-
-[dc-1-pg:children]
-dc-1-pgmaster
-dc-1-pgstandby
-
-[pgmaster:children]
-dc-1-pgmaster
-
-[dc-1-pgmaster:children]
-tag_Name_dc7_n9
-
-[pgstandby:children]
-dc-1-pgstandby
-
-[dc-1-pgstandby:children]
-tag_Name_dc7_n10
diff --git a/edge-1601-aio/inventory b/sample-aio/inventory-aio
similarity index 68%
rename from edge-1601-aio/inventory
rename to sample-aio/inventory-aio
index 0bd7ed0..92f2907 100644
--- a/edge-1601-aio/inventory
+++ b/sample-aio/inventory-aio
@@ -1,50 +1,51 @@
-[tag_Name_dc1_n1]
+[aio]
+0.0.0.0
 
 [planet:children]
 dc-1
 
 [dc-1:children]
-tag_Name_dc1_n1
+aio
 
 [ds:children]
 dc-1-ds
 
 [dc-1-ds:children]
-tag_Name_dc1_n1
+aio
 
 [ms:children]
 dc-1-ms
 
 [dc-1-ms:children]
-tag_Name_dc1_n1
+aio
 
 [ui:children]
 dc-1-ui
 
 [dc-1-ui:children]
-tag_Name_dc1_n1
+dc-1-ms
 
 [ldap:children]
 dc-1-ldap
 
 [dc-1-ldap:children]
-tag_Name_dc1_n1
+dc-1-ms
 
 [rmp:children]
 dc-1-rmp
 
 [dc-1-rmp:children]
-tag_Name_dc1_n1
+aio
 
 [qpid:children]
 dc-1-qpid
 
 [dc-1-qpid:children]
-tag_Name_dc1_n1
+aio
 
 [pg:children]
-dc-1-pg
+pg
 
 [dc-1-pg:children]
-tag_Name_dc1_n1
+aio
 
diff --git a/sample-baas-dc1/baas-dc1 b/sample-baas-dc1/baas-dc1
new file mode 100644
index 0000000..c5aa62c
--- /dev/null
+++ b/sample-baas-dc1/baas-dc1
@@ -0,0 +1,49 @@
+[dc-1-elastic]
+0.0.0.0
+0.0.0.0
+0.0.0.0
+
+[dc-1-baas]
+0.0.0.0
+0.0.0.0
+0.0.0.0
+
+[dc-1-portal]
+0.0.0.0
+
+[dc-1-cassandra]
+0.0.0.0
+0.0.0.0
+0.0.0.0
+
+[dc-1-ms]
+0.0.0.0
+
+[planet:children]
+dc-1
+
+[dc-1:children]
+dc-1-elastic
+dc-1-portal
+dc-1-baas
+dc-1-cassandra
+dc-1-ms
+
+[elastic:children]
+dc-1-elastic
+
+[baas:children]
+dc-1-baas
+
+[portal:children]
+dc-1-portal
+
+[ds:children]
+dc-1-ds
+
+[dc-1-ds:children]
+dc-1-cassandra
+
+[cassandra:children]
+dc-1-cassandra
+
diff --git a/sample-devportal-dc1/devportal-dc1 b/sample-devportal-dc1/devportal-dc1
new file mode 100644
index 0000000..5404b4a
--- /dev/null
+++ b/sample-devportal-dc1/devportal-dc1
@@ -0,0 +1,24 @@
+[dc-1-dp-ui]
+cf-011
+
+[dc-1-dp-db]
+cf-011
+
+[dc-1-dp]
+dc-1-dp-ui
+dc-1-dp-db
+
+[planet]
+dc-1-dp
+
+[dp:children]
+dc-1-dp
+
+[dp-ui:children]
+dc-1-dp-ui
+
+[dp-db:children]
+dc-1-dp-db
+
+[dc-1:children]
+dc-1-dp
diff --git a/edge-1601-dc2/ec2.ini b/sample-ec2/ec2.ini
similarity index 100%
rename from edge-1601-dc2/ec2.ini
rename to sample-ec2/ec2.ini
diff --git a/edge-1601-dc2/ec2.py b/sample-ec2/ec2.py
similarity index 100%
rename from edge-1601-dc2/ec2.py
rename to sample-ec2/ec2.py
diff --git a/sample-edge-one-datacenter/edge-dc1 b/sample-edge-one-datacenter/edge-dc1
new file mode 100644
index 0000000..ca57eca
--- /dev/null
+++ b/sample-edge-one-datacenter/edge-dc1
@@ -0,0 +1,88 @@
+[dc-1-edge]
+cf-00[1:9]
+cf-010
+
+[dc-1-ds]
+cf-00[1:3]
+
+# Setting an observer Zookeeper node
+# cf-003 zk_observer=true
+
+# Setting Cassandra with Rack Aware Settings
+# cf-001 rack=1,1
+# cf-002 rack=1,2
+# cf-003 rack=1,3
+
+[dc-1-ms]
+cf-004
+
+[dc-1-ldap]
+cf-004
+
+[dc-1-ui]
+cf-004
+
+[dc-1-rmp]
+cf-00[5:6]
+
+[dc-1-qpid]
+cf-00[7:8]
+
+[dc-1-pgmaster]
+cf-009
+
+[dc-1-pgstandby]
+cf-010
+
+[planet:children]
+dc-1
+
+[dc-1:children]
+dc-1-edge
+dc-1-ds
+dc-1-ms
+dc-1-ldap
+dc-1-ui
+dc-1-rmp
+dc-1-qpid
+dc-1-pg
+
+[edge:children]
+dc-1-edge
+
+[ms:children]
+dc-1-ms
+
+[ui:children]
+dc-1-ui
+
+[dc-1-ui:children]
+dc-1-ms
+
+[ldap:children]
+dc-1-ldap
+
+[dc-1-ldap:children]
+dc-1-ms
+
+[ds:children]
+dc-1-ds
+
+[rmp:children]
+dc-1-rmp
+
+[qpid:children]
+dc-1-qpid
+
+[pg:children]
+dc-1-pg
+
+[dc-1-pg:children]
+dc-1-pgmaster
+dc-1-pgstandby
+
+[pgmaster:children]
+dc-1-pgmaster
+
+[pgstandby:children]
+dc-1-pgstandby
diff --git a/sample-edge-two-datacenters/edge-dc1 b/sample-edge-two-datacenters/edge-dc1
new file mode 100644
index 0000000..a82f4a4
--- /dev/null
+++ b/sample-edge-two-datacenters/edge-dc1
@@ -0,0 +1,80 @@
+[dc-1-edge]
+cf-00[1:9]
+cf-010
+
+[dc-1-ds]
+cf-00[1:3]
+
+[dc-1-ms]
+cf-004
+
+[dc-1-ldap]
+cf-004
+
+[dc-1-ui]
+cf-004
+
+[dc-1-rmp]
+cf-00[5:6]
+
+[dc-1-qpid]
+cf-00[7:8]
+
+[dc-1-pgmaster]
+cf-009
+
+[dc-1-pgstandby]
+cf-010
+
+[planet:children]
+dc-1
+
+[dc-1:children]
+dc-1-edge
+dc-1-ds
+dc-1-ms
+dc-1-ldap
+dc-1-ui
+dc-1-rmp
+dc-1-qpid
+dc-1-pg
+
+[edge:children]
+dc-1-edge
+
+[ms:children]
+dc-1-ms
+
+[ui:children]
+dc-1-ui
+
+[dc-1-ui:children]
+dc-1-ms
+
+[ldap:children]
+dc-1-ldap
+
+[dc-1-ldap:children]
+dc-1-ms
+
+[ds:children]
+dc-1-ds
+
+[rmp:children]
+dc-1-rmp
+
+[qpid:children]
+dc-1-qpid
+
+[pg:children]
+dc-1-pg
+
+[dc-1-pg:children]
+dc-1-pgmaster
+dc-1-pgstandby
+
+[pgmaster:children]
+dc-1-pgmaster
+
+[pgstandby:children]
+dc-1-pgstandby
diff --git a/edge-ops-lab-1701-expansion/inventory-dc2 b/sample-edge-two-datacenters/edge-dc2
similarity index 62%
rename from edge-ops-lab-1701-expansion/inventory-dc2
rename to sample-edge-two-datacenters/edge-dc2
index 4c77b3b..9cc447e 100644
--- a/edge-ops-lab-1701-expansion/inventory-dc2
+++ b/sample-edge-two-datacenters/edge-dc2
@@ -1,42 +1,47 @@
+[dc-2-edge]
+cf-00[1:9]
+cf-010
+
 [dc-2-ds]
-10.142.0.[16:17]
-10.142.0.18 zk_observer=true
+cf-00[1:2]
+cf-003 zk_observer=true
 
 [dc-2-ms]
-10.142.0.19
-
-[dc-2-ui]
-10.142.0.19
+cf-004
 
 [dc-2-ldap]
-10.142.0.19
+cf-004
+
+[dc-2-ui]
+cf-004
 
 [dc-2-rmp]
-10.142.0.[20:21]
+cf-00[5:6]
 
 [dc-2-qpid]
-10.142.0.[23:24]
+cf-00[7:8]
 
-[dc-2-pg:children]
-dc-2-pgstandby
+[dc-2-pgmaster]
+cf-009
 
 [dc-2-pgstandby]
-10.142.0.22
+cf-010
 
 [planet:children]
 dc-2
 
 [dc-2:children]
+dc-2-edge
 dc-2-ds
 dc-2-ms
-dc-2-ui
 dc-2-ldap
+dc-2-ui
 dc-2-rmp
 dc-2-qpid
 dc-2-pg
 
-[ds:children]
-dc-2-ds
+[edge:children]
+dc-2-edge
 
 [ms:children]
 dc-2-ms
@@ -44,9 +49,18 @@
 [ui:children]
 dc-2-ui
 
+[dc-2-ui:children]
+dc-2-ms
+
 [ldap:children]
 dc-2-ldap
 
+[dc-2-ldap:children]
+dc-2-ms
+
+[ds:children]
+dc-2-ds
+
 [rmp:children]
 dc-2-rmp
 
@@ -56,8 +70,12 @@
 [pg:children]
 dc-2-pg
 
-[pgstandby:children]
+[dc-2-pg:children]
+dc-2-pgmaster
 dc-2-pgstandby
 
 [pgmaster:children]
-dc-1-pg
+dc-2-pgmaster
+
+[pgstandby:children]
+dc-2-pgstandby
diff --git a/edge-1601-aio/inventory b/sample-edgemicro/inventory-aio
similarity index 68%
copy from edge-1601-aio/inventory
copy to sample-edgemicro/inventory-aio
index 0bd7ed0..92f2907 100644
--- a/edge-1601-aio/inventory
+++ b/sample-edgemicro/inventory-aio
@@ -1,50 +1,51 @@
-[tag_Name_dc1_n1]
+[aio]
+0.0.0.0
 
 [planet:children]
 dc-1
 
 [dc-1:children]
-tag_Name_dc1_n1
+aio
 
 [ds:children]
 dc-1-ds
 
 [dc-1-ds:children]
-tag_Name_dc1_n1
+aio
 
 [ms:children]
 dc-1-ms
 
 [dc-1-ms:children]
-tag_Name_dc1_n1
+aio
 
 [ui:children]
 dc-1-ui
 
 [dc-1-ui:children]
-tag_Name_dc1_n1
+dc-1-ms
 
 [ldap:children]
 dc-1-ldap
 
 [dc-1-ldap:children]
-tag_Name_dc1_n1
+dc-1-ms
 
 [rmp:children]
 dc-1-rmp
 
 [dc-1-rmp:children]
-tag_Name_dc1_n1
+aio
 
 [qpid:children]
 dc-1-qpid
 
 [dc-1-qpid:children]
-tag_Name_dc1_n1
+aio
 
 [pg:children]
-dc-1-pg
+pg
 
 [dc-1-pg:children]
-tag_Name_dc1_n1
+aio
 
diff --git a/edgemicro-1601-dc1/inventory-edgemicro b/sample-edgemicro/inventory-edgemicro
similarity index 69%
rename from edgemicro-1601-dc1/inventory-edgemicro
rename to sample-edgemicro/inventory-edgemicro
index fc25bf9..fc923ea 100644
--- a/edgemicro-1601-dc1/inventory-edgemicro
+++ b/sample-edgemicro/inventory-edgemicro
@@ -1,4 +1,4 @@
 [tag_Name_dc2_n6]
 
 [micro:children]
-tag_Name_dc2_n6
+0.0.0.0
diff --git a/gcp-sample-inventory/gce.ini b/sample-gcp/gce.ini
similarity index 88%
rename from gcp-sample-inventory/gce.ini
rename to sample-gcp/gce.ini
index 27cbe3b..43af53b 100644
--- a/gcp-sample-inventory/gce.ini
+++ b/sample-gcp/gce.ini
@@ -37,13 +37,14 @@
 # exist in your PYTHONPATH and be picked up automatically with an import
 # statement in the inventory script.  However, you can specify an absolute
 # path to the secrets.py file with 'libcloud_secrets' parameter.
-libcloud_secrets =
+libcloud_secrets = ""
 
 # If you are not going to use a 'secrets.py' file, you can set the necessary
 # authorization parameters here.
-gce_service_account_email_address = SERVICE_ACCOUNT_EMAIL_ADDRESS
-gce_service_account_pem_file_path = SERVICE_ACCOUNT_PRIVATE_SSH_KEY
-gce_project_id = GCP_PROJECT_ID
+gce_service_account_email_address = sample-account-compute@developer.gserviceaccount.com
+gce_service_account_pem_file_path = ~/.apigee-secure/default-service-account.json
+gce_project_id = your-gce-project-id
+gce_zone = your-gce-zone
 
 [inventory]
 # The 'inventory_ip_type' parameter specifies whether 'ansible_ssh_host' should
@@ -51,4 +52,4 @@
 # 'internal' or 'external'. If 'external' is specified but no external instance
 # address exists, the internal address will be used.
 # The INVENTORY_IP_TYPE environment variable will override this value.
-inventory_ip_type = external
+inventory_ip_type = internal
diff --git a/sample-gcp/gce.py b/sample-gcp/gce.py
new file mode 100755
index 0000000..9a0cef0
--- /dev/null
+++ b/sample-gcp/gce.py
@@ -0,0 +1,508 @@
+#!/usr/bin/env python
+# Copyright 2013 Google Inc.
+#
+# This file is part of Ansible
+#
+# Ansible is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# Ansible is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Ansible.  If not, see <http://www.gnu.org/licenses/>.
+
+'''
+GCE external inventory script
+=================================
+
+Generates inventory that Ansible can understand by making API requests
+Google Compute Engine via the libcloud library.  Full install/configuration
+instructions for the gce* modules can be found in the comments of
+ansible/test/gce_tests.py.
+
+When run against a specific host, this script returns the following variables
+based on the data obtained from the libcloud Node object:
+ - gce_uuid
+ - gce_id
+ - gce_image
+ - gce_machine_type
+ - gce_private_ip
+ - gce_public_ip
+ - gce_name
+ - gce_description
+ - gce_status
+ - gce_zone
+ - gce_tags
+ - gce_metadata
+ - gce_network
+ - gce_subnetwork
+
+When run in --list mode, instances are grouped by the following categories:
+ - zone:
+   zone group name examples are us-central1-b, europe-west1-a, etc.
+ - instance tags:
+   An entry is created for each tag.  For example, if you have two instances
+   with a common tag called 'foo', they will both be grouped together under
+   the 'tag_foo' name.
+ - network name:
+   the name of the network is appended to 'network_' (e.g. the 'default'
+   network will result in a group named 'network_default')
+ - machine type
+   types follow a pattern like n1-standard-4, g1-small, etc.
+ - running status:
+   group name prefixed with 'status_' (e.g. status_running, status_stopped,..)
+ - image:
+   when using an ephemeral/scratch disk, this will be set to the image name
+   used when creating the instance (e.g. debian-7-wheezy-v20130816).  when
+   your instance was created with a root persistent disk it will be set to
+   'persistent_disk' since there is no current way to determine the image.
+
+Examples:
+  Execute uname on all instances in the us-central1-a zone
+  $ ansible -i gce.py us-central1-a -m shell -a "/bin/uname -a"
+
+  Use the GCE inventory script to print out instance specific information
+  $ contrib/inventory/gce.py --host my_instance
+
+Author: Eric Johnson <erjohnso@google.com>
+Contributors: Matt Hite <mhite@hotmail.com>, Tom Melendez <supertom@google.com>
+Version: 0.0.3
+'''
+
+try:
+    import pkg_resources
+except ImportError:
+    # Use pkg_resources to find the correct versions of libraries and set
+    # sys.path appropriately when there are multiversion installs.  We don't
+    # fail here as there is code that better expresses the errors where the
+    # library is used.
+    pass
+
+USER_AGENT_PRODUCT = "Ansible-gce_inventory_plugin"
+USER_AGENT_VERSION = "v2"
+
+import sys
+import os
+import argparse
+
+from time import time
+
+if sys.version_info >= (3, 0):
+    import configparser
+else:
+    import ConfigParser as configparser
+
+import logging
+logging.getLogger('libcloud.common.google').addHandler(logging.NullHandler())
+
+try:
+    import json
+except ImportError:
+    import simplejson as json
+
+try:
+    from libcloud.compute.types import Provider
+    from libcloud.compute.providers import get_driver
+    _ = Provider.GCE
+except:
+    sys.exit("GCE inventory script requires libcloud >= 0.13")
+
+
+class CloudInventoryCache(object):
+    def __init__(self, cache_name='ansible-cloud-cache', cache_path='/tmp',
+                 cache_max_age=300):
+        cache_dir = os.path.expanduser(cache_path)
+        if not os.path.exists(cache_dir):
+            os.makedirs(cache_dir)
+        self.cache_path_cache = os.path.join(cache_dir, cache_name)
+
+        self.cache_max_age = cache_max_age
+
+    def is_valid(self, max_age=None):
+        ''' Determines if the cache files have expired, or if it is still valid '''
+
+        if max_age is None:
+            max_age = self.cache_max_age
+
+        if os.path.isfile(self.cache_path_cache):
+            mod_time = os.path.getmtime(self.cache_path_cache)
+            current_time = time()
+            if (mod_time + max_age) > current_time:
+                return True
+
+        return False
+
+    def get_all_data_from_cache(self, filename=''):
+        ''' Reads the JSON inventory from the cache file. Returns Python dictionary. '''
+
+        data = ''
+        if not filename:
+            filename = self.cache_path_cache
+        with open(filename, 'r') as cache:
+            data = cache.read()
+        return json.loads(data)
+
+    def write_to_cache(self, data, filename=''):
+        ''' Writes data to file as JSON.  Returns True. '''
+        if not filename:
+            filename = self.cache_path_cache
+        json_data = json.dumps(data)
+        with open(filename, 'w') as cache:
+            cache.write(json_data)
+        return True
+
+
+class GceInventory(object):
+    def __init__(self):
+        # Cache object
+        self.cache = None
+        # dictionary containing inventory read from disk
+        self.inventory = {}
+
+        # Read settings and parse CLI arguments
+        self.parse_cli_args()
+        self.config = self.get_config()
+        self.driver = self.get_gce_driver()
+        self.ip_type = self.get_inventory_options()
+        if self.ip_type:
+            self.ip_type = self.ip_type.lower()
+
+        # Cache management
+        start_inventory_time = time()
+        cache_used = False
+        if self.args.refresh_cache or not self.cache.is_valid():
+            self.do_api_calls_update_cache()
+        else:
+            self.load_inventory_from_cache()
+            cache_used = True
+            self.inventory['_meta']['stats'] = {'use_cache': True}
+        self.inventory['_meta']['stats'] = {
+            'inventory_load_time': time() - start_inventory_time,
+            'cache_used': cache_used
+        }
+
+        # Just display data for specific host
+        if self.args.host:
+            print(self.json_format_dict(
+                self.inventory['_meta']['hostvars'][self.args.host],
+                pretty=self.args.pretty))
+        else:
+            # Otherwise, assume user wants all instances grouped
+            zones = self.parse_env_zones()
+            print(self.json_format_dict(self.inventory,
+                                        pretty=self.args.pretty))
+        sys.exit(0)
+
+    def get_config(self):
+        """
+        Reads the settings from the gce.ini file.
+
+        Populates a SafeConfigParser object with defaults and
+        attempts to read an .ini-style configuration from the filename
+        specified in GCE_INI_PATH. If the environment variable is
+        not present, the filename defaults to gce.ini in the current
+        working directory.
+        """
+        gce_ini_default_path = os.path.join(
+            os.path.dirname(os.path.realpath(__file__)), "gce.ini")
+        gce_ini_path = os.environ.get('GCE_INI_PATH', gce_ini_default_path)
+
+        # Create a ConfigParser.
+        # This provides empty defaults to each key, so that environment
+        # variable configuration (as opposed to INI configuration) is able
+        # to work.
+        config = configparser.SafeConfigParser(defaults={
+            'gce_service_account_email_address': '',
+            'gce_service_account_pem_file_path': '',
+            'gce_project_id': '',
+            'gce_zone': '',
+            'libcloud_secrets': '',
+            'inventory_ip_type': '',
+            'cache_path': '~/.ansible/tmp',
+            'cache_max_age': '300'
+        })
+        if 'gce' not in config.sections():
+            config.add_section('gce')
+        if 'inventory' not in config.sections():
+            config.add_section('inventory')
+        if 'cache' not in config.sections():
+            config.add_section('cache')
+
+        config.read(gce_ini_path)
+
+        #########
+        # Section added for processing ini settings
+        #########
+
+        # Set the instance_states filter based on config file options
+        self.instance_states = []
+        if config.has_option('gce', 'instance_states'):
+            states = config.get('gce', 'instance_states')
+            # Ignore if instance_states is an empty string.
+            if states:
+                self.instance_states = states.split(',')
+
+        # Caching
+        cache_path = config.get('cache', 'cache_path')
+        cache_max_age = config.getint('cache', 'cache_max_age')
+        # TOOD(supertom): support project-specific caches
+        cache_name = 'ansible-gce.cache'
+        self.cache = CloudInventoryCache(cache_path=cache_path,
+                                         cache_max_age=cache_max_age,
+                                         cache_name=cache_name)
+        return config
+
+    def get_inventory_options(self):
+        """Determine inventory options. Environment variables always
+        take precedence over configuration files."""
+        ip_type = self.config.get('inventory', 'inventory_ip_type')
+        # If the appropriate environment variables are set, they override
+        # other configuration
+        ip_type = os.environ.get('INVENTORY_IP_TYPE', ip_type)
+        return ip_type
+
+    def get_gce_driver(self):
+        """Determine the GCE authorization settings and return a
+        libcloud driver.
+        """
+        # Attempt to get GCE params from a configuration file, if one
+        # exists.
+        secrets_path = self.config.get('gce', 'libcloud_secrets')
+        secrets_found = False
+
+        try:
+            import secrets
+            args = list(secrets.GCE_PARAMS)
+            kwargs = secrets.GCE_KEYWORD_PARAMS
+            secrets_found = True
+        except:
+            pass
+
+        if not secrets_found and secrets_path:
+            if not secrets_path.endswith('secrets.py'):
+                err = "Must specify libcloud secrets file as "
+                err += "/absolute/path/to/secrets.py"
+                sys.exit(err)
+            sys.path.append(os.path.dirname(secrets_path))
+            try:
+                import secrets
+                args = list(getattr(secrets, 'GCE_PARAMS', []))
+                kwargs = getattr(secrets, 'GCE_KEYWORD_PARAMS', {})
+                secrets_found = True
+            except:
+                pass
+
+        if not secrets_found:
+            args = [
+                self.config.get('gce', 'gce_service_account_email_address'),
+                self.config.get('gce', 'gce_service_account_pem_file_path')
+            ]
+            kwargs = {'project': self.config.get('gce', 'gce_project_id'),
+                      'datacenter': self.config.get('gce', 'gce_zone')}
+
+        # If the appropriate environment variables are set, they override
+        # other configuration; process those into our args and kwargs.
+        args[0] = os.environ.get('GCE_EMAIL', args[0])
+        args[1] = os.environ.get('GCE_PEM_FILE_PATH', args[1])
+        args[1] = os.environ.get('GCE_CREDENTIALS_FILE_PATH', args[1])
+
+        kwargs['project'] = os.environ.get('GCE_PROJECT', kwargs['project'])
+        kwargs['datacenter'] = os.environ.get('GCE_ZONE', kwargs['datacenter'])
+
+        # Retrieve and return the GCE driver.
+        gce = get_driver(Provider.GCE)(*args, **kwargs)
+        gce.connection.user_agent_append(
+            '%s/%s' % (USER_AGENT_PRODUCT, USER_AGENT_VERSION),
+        )
+        return gce
+
+    def parse_env_zones(self):
+        '''returns a list of comma separated zones parsed from the GCE_ZONE environment variable.
+        If provided, this will be used to filter the results of the grouped_instances call'''
+        import csv
+        reader = csv.reader([os.environ.get('GCE_ZONE', "")], skipinitialspace=True)
+        zones = [r for r in reader]
+        return [z for z in zones[0]]
+
+    def parse_cli_args(self):
+        ''' Command line argument processing '''
+
+        parser = argparse.ArgumentParser(
+            description='Produce an Ansible Inventory file based on GCE')
+        parser.add_argument('--list', action='store_true', default=True,
+                            help='List instances (default: True)')
+        parser.add_argument('--host', action='store',
+                            help='Get all information about an instance')
+        parser.add_argument('--pretty', action='store_true', default=False,
+                            help='Pretty format (default: False)')
+        parser.add_argument(
+            '--refresh-cache', action='store_true', default=False,
+            help='Force refresh of cache by making API requests (default: False - use cache files)')
+        self.args = parser.parse_args()
+
+    def node_to_dict(self, inst):
+        md = {}
+
+        if inst is None:
+            return {}
+
+        if 'items' in inst.extra['metadata']:
+            for entry in inst.extra['metadata']['items']:
+                md[entry['key']] = entry['value']
+
+        net = inst.extra['networkInterfaces'][0]['network'].split('/')[-1]
+        subnet = None
+        if 'subnetwork' in inst.extra['networkInterfaces'][0]:
+            subnet = inst.extra['networkInterfaces'][0]['subnetwork'].split('/')[-1]
+        # default to exernal IP unless user has specified they prefer internal
+        if self.ip_type == 'internal':
+            ssh_host = inst.private_ips[0]
+        else:
+            ssh_host = inst.public_ips[0] if len(inst.public_ips) >= 1 else inst.private_ips[0]
+
+        return {
+            'gce_uuid': inst.uuid,
+            'gce_id': inst.id,
+            'gce_image': inst.image,
+            'gce_machine_type': inst.size,
+            'gce_private_ip': inst.private_ips[0],
+            'gce_public_ip': inst.public_ips[0] if len(inst.public_ips) >= 1 else None,
+            'gce_name': inst.name,
+            'gce_description': inst.extra['description'],
+            'gce_status': inst.extra['status'],
+            'gce_zone': inst.extra['zone'].name,
+            'gce_tags': inst.extra['tags'],
+            'gce_metadata': md,
+            'gce_network': net,
+            'gce_subnetwork': subnet,
+            # Hosts don't have a public name, so we add an IP
+            'ansible_ssh_host': ssh_host
+        }
+
+    def load_inventory_from_cache(self):
+        ''' Loads inventory from JSON on disk. '''
+
+        try:
+            self.inventory = self.cache.get_all_data_from_cache()
+            hosts = self.inventory['_meta']['hostvars']
+        except Exception as e:
+            print(
+                "Invalid inventory file %s.  Please rebuild with -refresh-cache option."
+                % (self.cache.cache_path_cache))
+            raise
+
+    def do_api_calls_update_cache(self):
+        ''' Do API calls and save data in cache. '''
+        zones = self.parse_env_zones()
+        data = self.group_instances(zones)
+        self.cache.write_to_cache(data)
+        self.inventory = data
+
+    def list_nodes(self):
+        all_nodes = []
+        params, more_results = {'maxResults': 500}, True
+        while more_results:
+            self.driver.connection.gce_params = params
+            all_nodes.extend(self.driver.list_nodes())
+            more_results = 'pageToken' in params
+        return all_nodes
+
+    def group_instances(self, zones=None):
+        '''Group all instances'''
+        groups = {}
+        meta = {}
+        meta["hostvars"] = {}
+
+        for node in self.list_nodes():
+
+            # This check filters on the desired instance states defined in the
+            # config file with the instance_states config option.
+            #
+            # If the instance_states list is _empty_ then _ALL_ states are returned.
+            #
+            # If the instance_states list is _populated_ then check the current
+            # state against the instance_states list
+            if self.instance_states and not node.extra['status'] in self.instance_states:
+                continue
+
+            name = node.name
+
+            meta["hostvars"][name] = self.node_to_dict(node)
+
+            zone = node.extra['zone'].name
+
+            # To avoid making multiple requests per zone
+            # we list all nodes and then filter the results
+            if zones and zone not in zones:
+                continue
+
+            if zone in groups:
+                groups[zone].append(name)
+            else:
+                groups[zone] = [name]
+
+            tags = node.extra['tags']
+            for t in tags:
+                if t.startswith('group-'):
+                    tag = t[6:]
+                else:
+                    tag = 'tag_%s' % t
+                if tag in groups:
+                    groups[tag].append(name)
+                else:
+                    groups[tag] = [name]
+
+            net = node.extra['networkInterfaces'][0]['network'].split('/')[-1]
+            net = 'network_%s' % net
+            if net in groups:
+                groups[net].append(name)
+            else:
+                groups[net] = [name]
+
+            machine_type = node.size
+            if machine_type in groups:
+                groups[machine_type].append(name)
+            else:
+                groups[machine_type] = [name]
+
+            image = node.image and node.image or 'persistent_disk'
+            if image in groups:
+                groups[image].append(name)
+            else:
+                groups[image] = [name]
+
+            status = node.extra['status']
+            stat = 'status_%s' % status.lower()
+            if stat in groups:
+                groups[stat].append(name)
+            else:
+                groups[stat] = [name]
+
+            for private_ip in node.private_ips:
+                groups[private_ip] = [name]
+
+            if len(node.public_ips) >= 1:
+                for public_ip in node.public_ips:
+                    groups[public_ip] = [name]
+
+        groups["_meta"] = meta
+
+        return groups
+
+    def json_format_dict(self, data, pretty=False):
+        ''' Converts a dict to a JSON object and dumps it as a formatted
+        string '''
+
+        if pretty:
+            return json.dumps(data, sort_keys=True, indent=2)
+        else:
+            return json.dumps(data)
+
+# Run the script
+if __name__ == '__main__':
+    GceInventory()
diff --git a/sample-mirror/mirror b/sample-mirror/mirror
new file mode 100644
index 0000000..e587a4f
--- /dev/null
+++ b/sample-mirror/mirror
@@ -0,0 +1,5 @@
+[cfmirror]
+cf-000
+
+[dc-1:children]
+cfmirror
\ No newline at end of file
diff --git a/sample-monitoring-dc1/monitoring-dc1 b/sample-monitoring-dc1/monitoring-dc1
new file mode 100644
index 0000000..17edc2d
--- /dev/null
+++ b/sample-monitoring-dc1/monitoring-dc1
@@ -0,0 +1,14 @@
+[telegraf]
+cf-00[1:9]
+cf-01[1:2]
+
+[grafana]
+cf-013
+
+[influxdb]
+cf-014
+
+[dc-1:children]
+telegraf
+grafana
+influxdb
diff --git a/vagrant/inventory b/vagrant/inventory
deleted file mode 100644
index 5320f2e..0000000
--- a/vagrant/inventory
+++ /dev/null
@@ -1,47 +0,0 @@
-[planet]
-127.0.0.1 ansible_port=2222
-
-[dc-1]
-127.0.0.1
-
-[ds]
-127.0.0.1
-
-[dc-1-ds]
-127.0.0.1
-
-[ldap]
-127.0.0.1
-
-[dc-1-ldap]
-127.0.0.1
-
-[ms]
-127.0.0.1
-
-[dc-1-ms]
-127.0.0.1
-
-[rmp]
-127.0.0.1
-
-[dc-1-rmp]
-127.0.0.1
-
-[qpid]
-127.0.0.1
-
-[dc-1-qpid]
-127.0.0.1
-
-[pg]
-127.0.0.1
-
-[dc-1-pg]
-127.0.0.1
-
-[ui]
-127.0.0.1
-
-[dc-1-ui]
-127.0.0.1
