As mentioned in yesterday’s blogpost, using a combination of environments, applications and operations can cause a cartesian explosion in hosts and groups to manage.
Even 10 applications in 3 environments over 2 operations can lead to sixty hosts, plus likely as many groups.
For example, we use a structure that looks like:
[environment:children]
application-environment
[application-environment:children]
operation-application-environment
[operation-application:children]
operation-application-environment
[operation-application-environment]
operation-application-environment-runner
[runner]
operation-application-environment-runner
[application:children]
application-environment
operation-application
[operation:children]
operation-application
And that’s just one host! Admittedly using groups that will be reused many times.
This problem has always been solvable using a script to generate inventory, but Ansible 2.4’s inventory plugin architecture, combined with the inspiration from the constructed plugin caused me to simplify my problem through creating a generator plugin. If the plugin proves popular I’ll likely raise a PR soon.
The generator plugin is then installed by putting it into our ansible playbooks repo under plugins/inventory/generator.py, and updating ansible.cfg to include
[defaults]
inventory_plugins = plugins/inventory
[inventory]
enable_plugins = generator,host_list,script,yaml,ini
The above inventory can be expressed with the inventory plugin using:
# inventory.config file in YAML format
plugin: generator
strict: False
hosts:
name: "{{ operation }}-{{ application }}-{{ environment }}-runner"
parents:
- name: "{{ operation }}-{{ application }}-{{ environment }}"
parents:
- name: "{{ operation }}-{{ application }}"
parents:
- name: "{{ operation }}"
- name: "{{ application }}"
- name: "{{ application }}-{{ environment }}"
parents:
- name: "{{ application }}"
- name: "{{ environment }}"
- name: runner
layers:
operation:
- build
- launch
environment:
- dev
- test
- prod
application:
- web
- api
We are already using this to reduce 100+ line static inventory host files (our biggest as-yet unreduced file is 500 lines!) to something very similar to the above.
The major benefit is, as always, reducing repetition - expanding this to more environments or applications is then a matter of adding a single element to the appropriate layer, rather than adding the appropriate groups and hosts in 10 different places.
ansible-inventory-grapher copes fine with the results (I put the effort in to finally fixing it so that I could validate the result)
ansible-inventory-grapher -i inventory/generator.config all -a 'rankdir=LR;' -q | dot -Tpng | display png:-