Bookmark this page

Generating and Using Dynamic Inventories

Objectives

After completing this section, you should be able to run an existing dynamic inventory script that provides automatically updated inventory information to Ansible in JSON format.

Moving Beyond Static Inventories

Files created and edited by hand are tedious to maintain over time as environments change. This is especially challenging when virtual machine instances are dynamically provisioned or deployed; in a cloud computing environment, for instance.

You need inventories stay current by being updated automatically on an ongoing basis. A dynamic inventory is a script that returns group and host information in JSON form.

Dynamic inventory scripts rely on information from one or more external sources. The sources can be anything: cloud provider APIs, Cobbler, LDAP directories, DNS, Consul, Infoblox, Device42, CMDB software; whatever the dynamic inventory script was designed to use.

Dynamic inventories are recommended for any large and rapidly changing IT environment, where systems are often deployed, tested, and then removed.

Managing Inventories Under Ansible Tower

Ansible Tower comes with built-in dynamic inventory support for a number of external inventory sources, including:

  • Amazon EC2

  • Google Compute Engine

  • Microsoft Azure Resource Manager

  • VMware vCenter

  • Red Hat Satellite 6

  • Red Hat CloudForms

  • OpenStack

  • Custom or DIY

In the next section, you will start to work with Red Hat Ansible Tower. You will see how Ansible Tower makes it easy to transition from static to dynamic inventories.

Unlocking Dynamic Inventories

Here we take a closer look at how dynamic inventories work.

A dynamic inventory is a script that must:

  • Have a --list option that returns a JSON array of group hashes/dictionaries.

  • Have a --host option that returns either a hash/dictionary of variables or an empty JSON hash/dictionary ({}).

  • Non-Ansible Tower dynamic inventory files (scripts or programs) must be marked executable by the file system.

You do not need to create any dynamic inventory scripts for this course, but information is provided on how to understand them.

Listing Host Groups

Groups are used to find hosts.

The --list option must return a JSON encoded hash/dictionary of all groups. It must be formatted as shown here:

{
  "foo": {
    "hosts": [
      "host1",
      "host2"
    ],
    "vars": {
      "var1": true
    },
    "children": [
      "bar"
    ]
  },
  "bar": {
    "hosts": [
      "host3",
      "host4"
    ],
    "vars": {
      "var2": 500
    },
    "children":[]
  }
}

Obtaining Host Information

Hosts are used to find variables and their values.

When run with the --host HOSTNAME option, the script must return either an empty JSON hash/dictionary, or a hash/dictionary of inventory variables for that host:

{
  "foovar": "fooval",
  "barvar": "barval",
}

Optimizing Inventory Performance

Calling --host for every host is not nearly as efficient as having the script return all of the host variables at once. Dynamic inventory scripts can do this by returning all host variables under a top-level element named _meta.

{
  "_meta": {
    "hostvars": {
      "host1": {
        "var1" : "value"
      },
      "host2": {
        "var2": "value"
      }
    }
  }
}

Describing the Outer Structure

What should be the outer structure of well-formed data from a dynamic inventory script?

Ideally, the top-level, skeletal structure of the JSON object returned by a dynamic inventory script should look like this:

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

Validating Dynamic Inventories

The -i inventory convention at the command line used by the ansible and ansible-* programs to load inventory data also works with dynamic inventories. That means you can use ansible-inventory -i script along with other options to verify that the script is working properly and returning results as expected. You can compare this to results obtained with a static inventory. The file does not need to be named dyn_inv.py, as long as it is executable.

[user@host ~]$ ansible-inventory -i inventory.yml --graph
@all:
|--@leafs:
|  |--leaf1
|  |--leaf2
|--@servers:
|  |--server1
|  |--server2
|--@spines:
|  |--spine1
|  |--spine2
|--@ungrouped:
[user@host ~]$ ansible-inventory -i dyn_inv.py --graph
@all:
|--@leafs:
|  |--leaf1
|  |--leaf2
|--@servers:
|  |--server1
|  |--server2
|--@spines:
|  |--spine1
|  |--spine2
|--@ungrouped:
Revision: do457-2.5-4693601