This repository is an basic implementation of an Ansible Dynamic Inventory Plugin. It covers the basic anatomy of a Dynamic inventory plugin, including annotations in-line as to the most common calls you'll make when writing a Dynamic Inventory Plugin.
A requirements.txt has been provided, but it's mostly for reference, and serves as a point-in-time snapshot. It includes the dependencies that were installed for this repository when demoed, but in effect, what was actually executed to produce this list of requirements was:
# Python 3.13.2
python3 -m venv ve
source ve/bin/activate
pip install ansibleIn other words, the requirements listed aren't hand-selected for this demo repository, but rather, ansible was installed, and the rest came along as dependencies.
This repository includes an ansible.cfg to aid in development. It has been annotated. None of the entries are strictly required for inventory plugins to work.
The example inventory plugin called "dir_inventory" can be found at inventory_plugins/dir_inventory.py. The source code is heavily annotated, showing you the common calls you may want to use when generating an inventory.
The dir_inventory plugin is a bit of a contrived example, but effectively it converts a matrix of base directories and sub directories into "hosts". In practice, this would allow a role or playbook to operate as if each "host" was a directory, and take actions with that assumption in place.
In this example, the user is expected to define a set of base directories (the "base_dirs" key in example.dir_inventory.yaml), and the plugin will enumerate the subdirectories for each base directory.
In real world use cases, inventory plugins would dynamically determine the hosts that are relevant at call time.
Assuming a properly configured environment (i.e. ansible package has been installed), you should be able to run the following to see the plugin at work.
ansible-inventory -i example.dir_inventory.yaml --list
Sample output:
{
"_meta": {
"hostvars": {
"bar_etc": {
"ansible_connection": "local",
"paths": {
"base_dir": "bar",
"concatenated_path": "bar/etc",
"sub_dir": "etc"
}
},
"bar_mnt": {
"ansible_connection": "local",
"paths": {
"base_dir": "bar",
"concatenated_path": "bar/mnt",
"sub_dir": "mnt"
}
},
"bar_root": {
"ansible_connection": "local",
"paths": {
"base_dir": "bar",
"concatenated_path": "bar/root",
"sub_dir": "root"
}
},
"bar_var": {
"ansible_connection": "local",
"paths": {
"base_dir": "bar",
"concatenated_path": "bar/var",
"sub_dir": "var"
}
},
"foo_etc": {
"ansible_connection": "local",
"paths": {
"base_dir": "foo",
"concatenated_path": "foo/etc",
"sub_dir": "etc"
}
},
"foo_mnt": {
"ansible_connection": "local",
"paths": {
"base_dir": "foo",
"concatenated_path": "foo/mnt",
"sub_dir": "mnt"
}
},
"foo_root": {
"ansible_connection": "local",
"paths": {
"base_dir": "foo",
"concatenated_path": "foo/root",
"sub_dir": "root"
}
},
"foo_var": {
"ansible_connection": "local",
"paths": {
"base_dir": "foo",
"concatenated_path": "foo/var",
"sub_dir": "var"
}
}
}
},
"all": {
"children": [
"ungrouped",
"dir_hosts"
]
},
"dir_hosts": {
"hosts": [
"foo_etc",
"foo_var",
"foo_mnt",
"foo_root",
"bar_etc",
"bar_var",
"bar_mnt",
"bar_root"
]
}
}