How to Setup Ansible AWS Dynamic Inventory

Ansible AWS Dynamic Inventory Setup

When you are using Ansible with AWS, maintaining the inventory file will be a hectic task as AWS has frequently changed IPs, autoscaling instances, and much more.

However, there is an easy solution called ansible dynamic inventory. Dynamic inventory is an ansible plugin that makes an API call to AWS to get the instance information in the run time. It gives you the ec2 instance details dynamically to manage the AWS infrastructure.

When I started using the Dynamic inventory, it was just a Python file. Later it became an Ansible plugin.

cloud engineer

I will talk more about how to manage the AWS dynamic inventory later in this article.

Dynamic inventory is not limited to just AWS. It supports most of the public and private cloud platforms. Here is the article on managing GCP resources using Ansible Dynamic inventory. 

Setup Ansible AWS Dynamic Inventory

In this tutorial, you will learn how to set up a dynamic inventory on AWS using boto and the AWS ec2 Ansible plugin.

Follow the steps carefully for the setup.

Step 1: Install python3

sudo yum install python3 -y

Step 2: Install the boto3 library.

sudo pip3 install boto

Step 3: Create a inventory directory under /opt and cd in to the directory.

sudo mkdir -p /opt/ansible/inventory
cd /opt/ansible/inventory

Step 4: Create a file named aws_ec2.yaml in the inventory directory and copy the following configuration.

Note: The file name should be aws_ec2.yaml. Also, replace add your AWS access key and secret to the config file.

plugin: aws_ec2
aws_access_key: <YOUR-AWS-ACCESS-KEY-HERE>
aws_secret_key: <YOUR-AWS-SECRET-KEY-HERE>
  - key: tags
    prefix: tag

If you have an AWS instance role attached to the instance with required Ansible permissions, you don’t have to add the access and secret key in the configuration. Ansible will automatically use the attached role to make the AWS API calls.

Step 5: Open /etc/ansible/ansible.cfg and find the [inventory] section and add the following line to enable the ec2 plugin.

enable_plugins = aws_ec2

It should look something like this.

enable_plugins = aws_ec2

Step 6: Now lets test the dynamic inventory configuration by listing the ec2 instances.

ansible-inventory -i /opt/ansible/inventory/aws_ec2.yaml --list

The above command returns the list of ec2 instances with all its parameters in JSON format.

If you want to use the dynamic inventory as a default Ansible inventory, edit the ansible.cfg file present in /etc/ansible directory and search for inventory parameter under defaults. Change the inventory parameter value as shown below.

inventory      = /opt/ansible/inventory/aws_ec2.yaml

Now if you run the inventory list command without passing the inventory file, Ansible looks for the default location and picks up the aws_ec2.yaml inventory file.

Step 6: Execute the following command to test if Ansible is able to ping all the machines returned by the dynamic inventory.

ansible all -m ping

Grouping EC2 Resources

The primary use case of AWS Ansible dynamic inventory is to execute Ansible playbooks or ad-hoc commands against a single or group of categorized or grouped instances based on tags, regions, or other ec2 parameters.

You can group instances using tags, instances type, instance names, custom filters and more. Take a look at all supported filters and keyed groups from here.

Here is a minimal configuration for aws_ec2.yaml that uses few keyed_groups and filters.

plugin: aws_ec2

aws_access_key: <YOUR-AWS-ACCESS-KEY-HERE>
aws_secret_key: <YOUR-AWS-SECRET-KEY-HERE>

  - us-west-2

  - key: tags
    prefix: tag
  - prefix: instance_type
    key: instance_type
  - key: placement.region
    prefix: aws_region

Execute the following command to list the dynamic inventory groups.

ansible-inventory --graph

You will see an output like the following with all instances grouped under tags, zones, and region with dynamic group names like aws_region_us_west_2 , instance_type_t2_micro, tag_Name_Ansible

aws inventory grouping min

Now you can execute Ansible ad-hoc commands or playbook against these groups.

Execute Anisble Commands With Dynamic Inventory

Lets test the dynamic inventory by executing few ansible ad-hoc commands.

Note: Make sure you have the SSH keys or user/password setup in your ansible configuration for Ansible to connect to it for executing the commands.

Execute Ping

I am going to execute the ping command with all instances in the region us_west_2. As per my configuration, the dynamic group name is aws_region_us_west_2.

ansible aws_region_us_west_2 -m ping

If you have all the right configurations, you should see an output like the following. | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python3"
    "changed": false,
    "ping": "pong"

Using Dynamic Inventory Inside Playbook

If you want to use dynamic inventory inside the playbook, you just need to mention the group name in the hosts varaible as shown below.

- name: Ansible Test Playbook
  gather_facts: false
  hosts: aws_region_us_west_2

    - name: Run Shell Command
      command: echo "Hello World"

  1. Hi, thanks for the valuable information. I need some help here,

    using the below I can get all the ec2 isntances list. But how to get only running instances?

    – key: aws_ec2
    prefix: ec2_hosts

  2. I uninstalled the deb packages and used pip:

    /etc/ansible$ pip install boto
    Collecting boto
    Downloading boto-2.47.0-py2.py3-none-any.whl (1.4MB)
    100% |████████████████████████████████| 1.4MB 940kB/s
    Installing collected packages: boto
    Successfully installed boto

    /etc/ansible$ ./ –list
    ERROR: “Working with RDS instances requires boto3 – please install boto3 and try again”, while: getting RDS [email protected]:/etc/ansible$

    /etc/ansible$ sudo pip install boto3 (permission error in /usr/local/lib… w/o sudo)

    …same error

  3. /etc/ansible$ ./ –list
    Traceback (most recent call last):
    File “./”, line 1600, in
    File “./”, line 193, in __init__
    File “./”, line 527, in do_api_calls_update_cache
    File “./”, line 633, in get_rds_instances_by_region
    client = ec2_utils.boto3_inventory_conn(‘client’, ‘rds’, region, **self.credentials)
    AttributeError: ‘module’ object has no attribute ‘boto3_inventory_conn’

    I’m running ubuntu 16.04 with boto2 and boto3 installed:

    $ dpkg -l | grep boto
    ii python-boto 2.38.0-1ubuntu1 all Python interface to Amazon’s Web Services – Python 2.x
    ii python-boto3 1.2.2-2 all Python interface to Amazon’s Web Services – Python 2.x
    ii python-botocore 1.4.70-1~16.04.0 all Low-level, data-driven core of boto 3 (Python 2)

    I have the credentials in ~/.aws/credentials

  4. I was trying to find examples in Ansible documentation but couldn’t find anything like this. Thanks!

  5. I was go throug all your steps which you provided for the setup, all these steps are very easy to undestand thank you for sharing this tutorial.

Leave a Reply

Your email address will not be published. Required fields are marked *

You May Also Like