AWS - Create a Dynamic Inventory

Create a dynamic inventory of the deployed hosts on AWS.

We'll cover the following

Ansible has a built-in inventory plugin for AWS called aws_ec2. The plugin queries AWS for EC2 instance details and constructs an Ansible inventory from that information. The inventory’s hosts are populated by the EC2 instances that are returned. Group and group memberships are determined by the host variables that are assigned to each host.

We ceate a file named hosts_aws_ec2.yml and define the aws_ec2 settings.

Press + to interact
plugin: aws_ec2
regions:
- us-east-1
filters:
tag:app: ansible

Let’s break down the file.

  • plugin: Define the inventory plugin, aws_ec2.

  • regions: List all the regions for the inventory. All EC2 instances within the listed regions will then be added to the inventory.

  • filter: tag:app limit the inventory to only EC2 instances that match the tag specified, ansible. Without this, it would include all EC2 instances in the us-east-1 region.

Confirm that the inventory works by running the ansible-inventory command.

ansible-inventory -i hosts_aws_ec2.yml --graph
Confirm ansible inventory

Viewing the output, notice that the all groups contain two nested groups: aws_ec2 and ungrouped. Both of the EC2 instances are listed under the aws_ec2 group.

Let’s run the site.yml playbook using the dynamic inventory. Update the <Password> with the password created by using the ansible-vault command in the group_vars/linux.yml and group_vars/windows.yml files.

Click on the Run button and wait for the environment to set up.

plugin: aws_ec2
regions:
  - us-east-1
filters:
  tag:app: ansible
AWS dynamic inventory

Once set up, execute the following command in the terminal to confirm that the inventory work:

ansible-inventory -i hosts_aws_ec2.yml --graph
Confirm ansible inventory

Next, run the following command to execute the playbook:

ansible-playbook site.yml -i hosts_aws_ec2.yml --ask-vault-pass
Execute Ansible playbook with dynamic inventory

No hosts matched the groups linux or windows because they do not yet exist in the inventory.

Before you run site.yml, you have to create those groups and assign the appropriate group memberships.

Groups

The aws_ec2 inventory plugin has a parameter called groups. It adds hosts to groups based on Jinja 2 conditionals. The conditionals use hostvars to evaluate the conditions. Using the ansible-inventory command and a JSON parser, you can discover the hostvars to create conditionals for the groups.

AWS adds the resource tags as hostvars on each instance. You can use the ansible-inventory command to output all the hostvars and then parse the JSON returned with jq or PowerShell for debugging purposes.

#Linux ec2 instance
ansible-inventory -i hosts_aws_ec2.yml --list | jq .'_meta.hostvars."<LinuxHost>>".tags'
#Windows ec2 instance
ansible-inventory -i hosts_aws_ec2.yml --list | jq .'<WindowsHost".tags'
Parse hostvars with jq or PowerShell.

Replace <(Linux|Windows)Host with the AWS Public DNS of each host.

Tag

The tag Name follows a naming convention that indicates which operating system it is. Because of that, the Name tag can be used to create the linux and windows groups. The syntax for the groups parameter starts with the group’s name, followed by a colon, and then a Jinja2 expression.

If the tag "Name" variable contains "linux", place it in the linux group.

Press + to interact
linux: "'linux' in tags.Name"

if the tag "Name" variable contains "win", place it in the windows group.

Press + to interact
windows: "'win' in tags.Name"

Add the groups parameter and the conditions to the hosts_aws_ec2.yml inventory.

Press + to interact
plugin: aws_ec2
regions:
- us-east-1
filters:
tag:app: ansible
groups:
linux: "'linux' in tags.Name"
windows: "'win' in tags.Name"

The Jinja2 expression looks for a text match within the tags.Name hostvar. If it matches, the host is added to the corresponding group.

Update the <Password> in the group_vars/linux.yml and group_vars/windows.yml files.

Click on the Run button and wait for the environment to set up.

plugin: aws_ec2
regions:
  - us-east-1
filters:
  tag:app: ansible
groups:
  linux: "'linux' in tags.Name"
  windows: "'win' in tags.Name"
AWS dynamic inventory

Once set up, confirm the inventory works by running the ansible-inventory command.

ansible-inventory -i hosts_aws_ec2.yml --graph
Confirm ansible inventory

Run the site.yml playbook to configure the web servers.

Press + to interact
ansible-playbook site.yml -i hosts_aws_ec2.yml --ask-vault-pass

Troubleshooting tips

Install jq: apt-get install jq

In this lesson, we introduced how to create a dynamic inventory of hosts deployed on AWS using Ansible. We looked at the following commands and modules:

  • aws_ec2: To query EC2 instances from AWS. We made use of this in the hosts_aws_ec2.yml file.
  • ansible_inventory: To populate the dynamic repository using the hosts_aws_ec2.yml file.
  • groups: An option used with the aws_ec2 plugin to add hosts to groups based on Jinja2 conditionals.

Get hands-on with 1300+ tech skills courses.