Ansible: Dynamic Inventory
I know that Ansible could use as inventory virtually anything, including scripts. However, all inventories on my day job are static, and we keep them in a source repository, and until now, I haven't had a chance to create or use one.
As any developer, I have checked the Stack Exchange before looking into Ansible documentation where I find a boiled-down solution. There are a few ground rules for scripting dynamic directories:
- Script should accept at least two arguments:
- --list - return all hosts as a response
- --host <hostname> - return a singe host
- The script result is valid invnetory JSON data
Lets combain all we have learned and create a simple dynamic inventory script with two groups, one static and one dynamic.
#!/bin/sh
set +x
if [ "$1" == "--list" ]; then
echo -e '{ "static_group": {\n\t"hosts": [ "localhost"]},'
echo -e ' "dynamic_group": {\n\t"hosts": ['
# Calcualte second group member
coin=$(( $RANDOM % 2 ))
if [ $coin -ge 1 ]; then
echo -e '"localhost"]},'
else
echo -e ']},'
fi
echo -e '"_meta": {"hostvars": {}}\n}'
elif [ "$1" == "--host" ]; then
echo '{"_meta": {"hostvars": { }}}'
else
echo "{ }"
fi
Script accepts required parameters and returns group and hstnames only for the --list argument, otherwise it returns an empty (almost) JSON object. To demonstrate the dynamic nature of the script I use special environment variable $RANDOM. For odd number script returns a list ["localhost] and empty list for even numbers. On the screenshot below, you may see a different set of targets for the same command.

Athough, this code is merely a demonstration of capabilities, some advanced version could be useful fo automated collection or module tests.
Sample code and playbook are published on the site Github project.