How to use Ansible AWS EC2 Dynamic Inventory Plugin
By: Shahin Ahmed
Tags: Ansible Inventory, Ansible, Ansible Playbook, Ansible Tutorial, Ansible Dynamic Inventory

Ansible is a great automation tool used for IT tasks such as configuration management, application deployment etc. Many organisations have adopted Ansible as their configuration management tool. However, managing a static inventory file can be a tedious job if your Ansible inventory fluctuates over time, with hosts spinning up and shutting down in response to business demands. In scenarios like this, the static inventory solution will not serve your needs; You would need to adopt an Ansible dynamic inventory to meet your business demands efficiently.

Ansible supports many dynamic inventory plugins, e.g. aws_ec2, aws_rds, azure_rm, docker_swarm, gcp_compute, etc. These plugins provide a great way to manage compute resources from various cloud providers without having to maintain a standard local inventory.

To see the full list of Ansible Dynamic Inventory plugins run the following command in your terminal ansible-doc -t inventory -l .

Recently, I worked on an Ansible project for one of our clients where we needed to use dynamic inventory to target a group of the EC2 instances and execute an Ansible Playbook. Whilst I was working on the project, I had noticed there were not many resources available online for Ansible EC2 Dynamic Inventory. For those learning and using Ansible, this is a short article that will depict how you can setup the AWS Ansible dynamic inventory plugin for AWS EC2 host management.

In this article, I will be using the Ansible EC2 dynamic inventory to target a group of EC2 instance to install few packages using apt modules.

The below requirements are needed on the local controller node that executes this inventory.

boto3

botocore

Ansible Version >= 2.9.13

You can install boto3 and botocore using pip. Please follow the commands below to install boto3 and botocore:

pip install botocore pip install boto3

For this demonstration, I am using my MacBook Pro as my local controller node, and I have spun up an EC2 instance in AWS, which will serve as my target server. Your organisation must define a tagging strategy, and you should follow the tagging strategy to tag your instances. In this case, since I am doing a demo, I have decided to organise my resources with the following tags:

Once you have a set of servers available in AWS, you can proceed to the next stage of configuring Ansible with Dynamic Inventory. For this demo, I have created an ansible-demo repository which I have made publicly available in Github. You can clone the repository from here https://github.com/DevMasterPro/ansible-demo.The structure of the Ansible repo looks something like the screenshot below.

In the ansible-demo repository, I have the following folders group_vars, inventory and playbook.

Group_vars

The group_vars folder is created to store all the global variables which will be accessible during ansible-playbook execution. For this demo, I have created a file under the group_vars folder to store global variables. Please see the content of the file below:

File: group_vars/all

--- ansible_user: ubuntu

I have declared a global variable called ansible_user and assigned the username that I will be using to authenticate against the target machine. In your case, you might have to change the username value to your desired preference.

Note: This demo will be using a SSH key to authenticate against the target machine. Hence, you would have to add your SSH key to your SSH authentication agent. You can find the instructions on how to add the SSH key to SSH Authentication agent here https://www.ssh.com/ssh/add.

Inventory

Now that the group_vars folder is ready, I can now move to the inventory folder. The inventory folder has been created to keep the dynamic inventory in a structured manner. I have created a dynamic inventory file called dynamic.aws_ec2.yml . The file contains script to interact with the AWS EC2 dynamic inventory plugin. It’s important to note that when creating a dynamic inventory plugin file, the suffix portion of the file should be aws_ec2.yml . For example:

The following content goes in the dynamic.aws_ec2.yaml file:

plugin: aws_ec2 boto_profile: sandbox regions: - eu-west-1 # keyed_groups may be used to create custom groups strict: true keyed_groups: # Add hosts to tag_Name_Value groups for each Name/Value tag pair - prefix: tag key: tags hostnames: # - private-ip-address - ip-address

The above script will use the Ansible AWS ec2_plugin to generate the host group dynamically. The aws_ec2 plugin will require credentials to authenticate against AWS. In this case, I am using my local AWS profile called sandbox . You can either use boto_profile or access key and secret key to authenticate against AWS. Furthermore, I am going to create a dynamic inventory host group using AWS tags.

Once you have the group_vars and inventory set up correctly, we can test it to see if we can generate the host group dynamically.

Note: When using tags to generate dynamic inventory, you have to pass the tags key and value in the following format. The prefix should always start with tag , and the rest should follow by a tag key and value . For example:

tag_Key_Value --> tag_Environment_Dev

Now run the following command to generate inventory:

ansible-inventory -i inventory/dynamic.aws_ec2.yml tag_Key_Value –graph

The outcome of the command should look something like the below screenshot:

Playbook

So far, I have demonstrated how you can use the dynamic inventory to create your host group. Now let’s look at how to execute an Ansible Playbook against the dynamically generated host group. I have created a simple playbook that would install Nginx and make sure the service is running in the target host.

File: playbook/ansible-demo-pb.yaml

--- - name: Ansible Demo hosts: "{{ host_group }}" become: true tasks: - name: Install nginx latest version apt: name: nginx state: latest - name: Start nginx service: name: nginx state: started

To execute the playbook run the following command:

ansible-playbook -i inventory/dynamic.aws_ec2.yml -e 'host_group=tag_Environment_Dev' playbook/ansible-demo-pb.yaml -u ubuntu

The outcome of the command should look something like the below screenshot:

Now let's check if Nginx is successfully installed in the target machine.

As you can see, I have demonstrated how you can use Ansible to manage your inventory dynamically. I hope you found this article useful.

If you have any further query you can connect with me on Linkedin →