Skip to content

Ansible Dynamic Inventory

Ansible Dynamic Inventory#

Dynamic inventory is useful when:

  • Inventory changes over time as hosts start and stop
  • Hosts need to be tracked from different sources

In those cases you probably have, or need, an external dynamic inventory system.

Ansible integrates with dynamic inventory in two ways:

  • Inventory plugins
  • Inventory scripts

Plugins are recommended over scripts.

Ansible Tower, now AWX or Red Hat Ansible Automation Platform, provides a GUI for handling dynamic inventory and syncing its inventory database with external inventory sources.

Run an ad hoc command#

You need to be able to SSH without a password.

ansible -i root@10.10.10.204, all -a 'uname -a'

To do this for multiple hosts:

ansible -i "root@10.10.10.93, root@10.10.10.92, root@10.200.1.94" all -a 'uptime'

To run a module for multiple hosts:

ansible -i "root@10.10.10.93, root@10.10.10.92, root@10.10.10.94" all -m setup

I have noticed that if one host requires a password, it will fail. If you set -k to ask for the SSH password, they all fail.

$ ansible -i "root@10.10.10.93, root@10.10.10.92, root@10.10.10.94" all -m setup
root@10.10.10.92 | UNREACHABLE! => {
    "changed": false,
    "msg": "Failed to connect to the host via ssh: root@10.10.10.92: Permission denied (publickey,gssapi-keyex,gssapi-with-mic,password).\r\n",
    "unreachable": true
}

Ensure that Jenkins is started:

ansible -i "root@10.10.10.94," all -m service -a "name=jenkins state=started"

To use an inventory script with an ad hoc command:

ansible -i digital_ocean.py all -a 'uptime'

You can use the ansible-inventory utility to check the hosts visually:

ansible-inventory -i digital_ocean.py --list

Remember to ensure the inventory script is executable with chmod +x inventory_file.py

What dynamic inventory output should look like#

We want this inventory to know how to connect, so set the following variables:

ansible_connection=ssh
ansible_user=vagrant
ansible_host=10.0.0.1

We need to ensure that the _meta variable is set

It should look like this:

{
    "_meta": {
        "hostvars": {
            "host001": {
                "var001": "value"
            },
            "host002": {
                "var002": "value"
            }
        }
    }
}

If you intend to replace an existing static inventory file with an inventory script, it must return a JSON object with an all group that includes every host in the inventory as a member and every group in the inventory as a child.

{
    "_meta": {
        "hostvars": {}
    },
    "all": {
        "children": [
            "ungrouped"
        ]
    },
    "ungrouped": {
        "children": []
    }
}

Other variables we might want are:

  • Guest OS or distribution
  • Name
  • Networks

Inventory scripts#

You can run a Python script to get your hosts. This can be done by passing in the script as the inventory parameter: -i openstack_inventory.py

If you want to do this implicitly, remember that explicit is better than implicit.

You can place the script at /etc/ansible/hosts

There are existing integrations to check out as scripts for:

There are other existing inventory scripts

Or you can create your own inventory script

Using inventory directories and multiple inventory sources#

Using a directory can let Ansible use multiple inventories at the same time. This also allows mixing static and dynamic inventories.

Files ending in ~, .orig, .bak, .ini, .cfg, .retry, .pyc, .pyo will be ignored

Which you can change to your own with the inventory_ignore_extensions entry in ansible.cfg

More information is available in the documentation on multiple inventory sources.

Build a dynamic inventory#

In previous versions you had to create a script or program that could output JSON in the correct format when invoked with the proper arguments.

Inventory sources#

Inventory sources are what you pass to -i. They can be a path to a file, a script or the raw data for a plugin to use.

  • host list: comma-separated list of hosts
  • yaml: path to YAML format data file
  • constructed: path to YAML config file
  • ini: path to INI formatted data file
  • virtualbox: path to YAML config file
  • script plugin: path to executable outputting JSON

Read more about developing plugins.

Inventory plugins normally only execute at the start of a run, before playbooks, plays and roles are loaded. They can be re-executed via the meta: refresh_inventory task, which clears out the existing inventory and rebuilds it.

Sources#