diff --git a/awx/plugins/inventory/ec2.ini.example b/awx/plugins/inventory/ec2.ini.example index a0c8672394..c66bf309b1 100644 --- a/awx/plugins/inventory/ec2.ini.example +++ b/awx/plugins/inventory/ec2.ini.example @@ -73,3 +73,23 @@ nested_groups = False # If you want to exclude any hosts that match a certain regular expression # pattern_exclude = stage-* + +# 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=stage tag +# instance_filters = tag:env=stage + +# 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=stage +# instance_filters = instance-type=t1.micro,tag:env=stage + +# 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* diff --git a/awx/plugins/inventory/ec2.py b/awx/plugins/inventory/ec2.py index c8e6d6e7f3..aec6473be6 100755 --- a/awx/plugins/inventory/ec2.py +++ b/awx/plugins/inventory/ec2.py @@ -123,6 +123,7 @@ from boto import ec2 from boto import rds from boto import route53 import ConfigParser +from collections import defaultdict try: import json @@ -257,6 +258,8 @@ class Ec2Inventory(object): 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, e: self.pattern_include = None @@ -265,8 +268,17 @@ class Ec2Inventory(object): 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, e: - self.pattern_exclude = '' + self.pattern_exclude = None + + # Instance filters (see boto and EC2 API docs) + self.ec2_instance_filters = defaultdict(list) + if config.has_option('ec2', 'instance_filters'): + for x in config.get('ec2', 'instance_filters', '').split(','): + filter_key, filter_value = x.split('=') + self.ec2_instance_filters[filter_key].append(filter_value) def parse_cli_args(self): ''' Command line argument processing ''' @@ -312,7 +324,13 @@ class Ec2Inventory(object): print("region name: %s likely not supported, or AWS is down. connection to region failed." % region) sys.exit(1) - reservations = conn.get_all_instances() + reservations = [] + if self.ec2_instance_filters: + for filter_key, filter_values in self.ec2_instance_filters.iteritems(): + 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)