Ansible Dynamic Inventory

When is this needed: * Inventory fluctuates over time starting up and shutting down * Tracking hosts from different sources

Then you most probably have a dynamic external inventory system

The way ansible integrates with them in 2 ways: * inventory plugins * inventory scripts

Plugins are recommended over scripts

Ansible tower is a GUI for handling dynamic inventory, ithe nventory database syncs with all your dynamic inventory sources.

Run an ad hoc command

You need to be able to ssh with no 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. Then if you set the -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 adhoc 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 output of a dynamic inventory should look like

We want this inventory to know how to connect so we need to 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:

{
    # results of inventory script as above go here
    # ...

    "_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 which contains 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 / 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 implictly - Explicit is better than implicit.

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

There are existing integrations to checkout as scripts for: * Cobbler * AWS EC2 * OpenStack

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 mutliple inventories at the same time This also allows mixing of 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 info on using multiple inventory sources

Building a Dynamic Inventory

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

Inventory Sources

What you pass to -i, which can represent a path to a file, script or be the raw data for the 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

More on developing plugins

Inventory plugins normally only execute at the start of a run, before playbooks/plays and roles are loaded, but they can be ‘re-executed’ via the meta: refresh_inventory task, which will clear out the existing inventory and rebuild it.

Source