Hello everybody,
our current configuration management system uses a path notation for
hierarchical hostgroups (subgroups), i.e.
testgroup
testgroup/subgroup1
testgroup/subgroup2
which would correspond to Ansible's
[testgroup:children]
testgroup/subgroup1
testgroup/subgroup2
[testgroup/subgroup1]
[testgroup/subgroup2]
While using a dynamic inventory source for adapting the legacy inventory,
(Ansible does not care about the slash '/' in a group name), we ran into
problems declaring group variables via .yml-files on the filesystem:
group_vars/test/subgroup1/somevars.yml
is found by hosts in any of the above hostgroups, since Ansible
searches for all yml-files below group_vars/test/ and assigns their variables
to every host in the 'test' group.
One way around this problem might be to "flatten" the group tree by
replacing the '/' by '_' in the dynamic inventory source. Apart from
possible (though unlikely) naming conflicts, this would be quite ugly
abanding not only a quite nice notation for subgroups but also the
much cleaner organisation of files and directories below group_vars.
Is there an alternative apart from rewriting Ansible's part of parsing
the group_vars directories?
Many thanks in advance,
Gregor
The biggest caveat here is that groups with a slash (/) in the name no longer work in the latest version of ansible. It treats everything up to but excluding the first slash as the group name.
We were doing this for a while but broke it out so there was no overlap by having a prefix for each group that defined the group's scope, E.g.
site/site1
site/site2
site-env/site1-prod
site-env/site1-testing
env/sand
env/testing
It's no longer hierarchical, but still takes advantage of folders for organization, and you can set lookup priority by, E.g., making site-env/site1-testing a child of the env/testing group.
To make this compatible with the latest ansible, I replaced slashes with underscores. It's not as pretty but it works.
If you’re interested, the crux of the issue with the latest ansible is here: https://github.com/ansible/ansible/blob/8217c1c39c8de848550e2a6c816377f11cc60e9f/lib/ansible/inventory/__init__.py#L777-L785
Ansible is pre-loading a list of all the files in the group_vars directory one level deep. You can still assign your machine to a group named “one/two/three”, but ansible will only have added a group_vars_file entry of “one” from the call to _find_group_vars_files. During variable lookup for the group “one/two/three” it checks for a group_vars_files entry of “one/two/three” (https://github.com/ansible/ansible/blob/8217c1c39c8de848550e2a6c816377f11cc60e9f/lib/ansible/inventory/__init__.py#L833). When it finds none, it just moves on.