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.
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.
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.
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.
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":[]
}
}Hosts are used to find variables and their values.
When run with the --host option, the script must return either an empty JSON hash/dictionary, or a hash/dictionary of inventory variables for that host:
HOSTNAME
{
"foovar": "fooval",
"barvar": "barval",
}
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"
}
}
}
}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": {}
}
The -i convention at the command line used by the inventoryansible and ansible-* programs to load inventory data also works with dynamic inventories.
That means you can use ansible-inventory -i 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 scriptdyn_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: