From 5b5103e6b4efc91f8749787c49c6ddfdfb9f9139 Mon Sep 17 00:00:00 2001 From: Michal Gasek Date: Wed, 3 Sep 2014 00:50:28 +0200 Subject: [PATCH] Add support for filtering EC2 instances in dynamic inventory This allows filtering out EC2 instances based on various different filters including tags. As requested in 7480 it supports logical "OR" instead of "AND" on the provided list of filters. --- plugins/inventory/ec2.ini | 20 ++++++++++++++++++++ plugins/inventory/ec2.py | 16 +++++++++++++++- 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/plugins/inventory/ec2.ini b/plugins/inventory/ec2.ini index a0c8672394..c66bf309b1 100644 --- a/plugins/inventory/ec2.ini +++ b/plugins/inventory/ec2.ini @@ -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/plugins/inventory/ec2.py b/plugins/inventory/ec2.py index f4e98f6dd7..aec6473be6 100755 --- a/plugins/inventory/ec2.py +++ b/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 @@ -272,6 +273,13 @@ class Ec2Inventory(object): except ConfigParser.NoOptionError, e: 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 ''' @@ -316,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)