Skip to content

Commit

Permalink
aws_ec2 inventory: add includes_entries_matching keys
Browse files Browse the repository at this point in the history
Expose a new `includes_entries_matching` configuration key that
gives the user the ability to compose the final inventory list
with several queries.

Closes: #248
  • Loading branch information
goneri committed Apr 13, 2021
1 parent 9130653 commit 43c6596
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 4 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
---
minor_changes:
- "aws_ec2 inventory - the inventory plugin now exposes a new `includes_entries_matching` configuration key that gives the user the ability to compose the final inventory list with multiple queries (https://github.com/ansible-collections/amazon.aws/pull/328)."
38 changes: 34 additions & 4 deletions plugins/inventory/aws_ec2.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,12 @@
- Available filters are listed here U(http://docs.aws.amazon.com/cli/latest/reference/ec2/describe-instances.html#options).
type: dict
default: {}
includes_entries_matching:
description:
- A list of filters. The instances matching the filters will be included in the result.
- Available filters are listed here U(http://docs.aws.amazon.com/cli/latest/reference/ec2/describe-instances.html#options).
type: list
default: []
include_extra_api_calls:
description:
- Add two additional API calls for every instance to include 'persistent' and 'events' host variables.
Expand Down Expand Up @@ -151,6 +157,20 @@
# Use the private IP address to connect to the host
# (note: this does not modify inventory_hostname, which is set via I(hostnames))
ansible_host: private_ip_address
# Example using another extra filters to add more entries in the result
plugin: aws_ec2
regions:
- us-east-1
- us-west-1
filters:
tag:Name:
- 'my_first_tag'
includes_entries_matching:
- tag:Name:
- 'my_second_tag'
- tag:Name:
- 'my_third_tag'
'''

import re
Expand Down Expand Up @@ -456,7 +476,7 @@ def _get_instances_by_region(self, regions, filters, strict_permissions):

all_instances.extend(instances)

return sorted(all_instances, key=lambda x: x['InstanceId'])
return all_instances

def _get_reservation_details(self, reservation):
return {
Expand Down Expand Up @@ -537,14 +557,23 @@ def _get_hostname(self, instance, hostnames):
else:
return to_text(hostname)

def _query(self, regions, filters, strict_permissions):
def _query(self, regions, filters, includes_entries_matching, strict_permissions):
'''
:param regions: a list of regions to query
:param filters: a list of boto3 filter dictionaries
:param hostnames: a list of hostname destination variables in order of preference
:param includes_entries_matching: a list of filters, instances matching these filters are included in the result
:param strict_permissions: a boolean determining whether to fail or ignore 403 error codes
'''
return {'aws_ec2': self._get_instances_by_region(regions, filters, strict_permissions)}
instances = self._get_instances_by_region(regions, filters, strict_permissions)
for includes in includes_entries_matching:
filter = ansible_dict_to_boto3_filter_list(includes)
instances += self._get_instances_by_region(regions, filter, strict_permissions)

instances = sorted(instances, key=lambda x: x['InstanceId'])

return {'aws_ec2': instances}

def _populate(self, groups, hostnames):
for group in groups:
Expand Down Expand Up @@ -650,6 +679,7 @@ def parse(self, inventory, loader, path, cache=True):
# get user specifications
regions = self.get_option('regions')
filters = ansible_dict_to_boto3_filter_list(self.get_option('filters'))
includes_entries_matching = self.get_option('includes_entries_matching')
hostnames = self.get_option('hostnames')
strict_permissions = self.get_option('strict_permissions')

Expand All @@ -669,7 +699,7 @@ def parse(self, inventory, loader, path, cache=True):
cache_needs_update = True

if not cache or cache_needs_update:
results = self._query(regions, filters, strict_permissions)
results = self._query(regions, filters, includes_entries_matching, strict_permissions)

self._populate(results, hostnames)

Expand Down
3 changes: 3 additions & 0 deletions tests/integration/targets/inventory_aws_ec2/runme.sh
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ ansible-playbook playbooks/create_inventory_config.yml -e "template='inventory_w
ansible-playbook playbooks/test_populating_inventory_with_constructed.yml "$@"
ansible-playbook playbooks/create_inventory_config.yml -e "template='inventory_with_concatenation.yml.j2'" "$@"
ansible-playbook playbooks/test_populating_inventory_with_concatenation.yml "$@"
# generate inventory config with includes_entries_matching and prepare the tests
ansible-playbook playbooks/create_inventory_config.yml -e "template='inventory_with_includes_entries_matching.yml.j2'" "$@"
ansible-playbook playbooks/test_populating_inventory_with_includes_entries_matching.yml "$@"

# cleanup inventory config
ansible-playbook playbooks/empty_inventory_config.yml "$@"

0 comments on commit 43c6596

Please sign in to comment.