Hello guenter,
On sie 23, dev wrote:
but I do not really understand - or had a totally different narrativ,
on how
debops works with groups.
first: there is no such thing as max of 3 groups? correct?
Yes, you can have as many inventory groups as you want. However, during
execution Ansible "collapses" inventory variables on three distinct levels:
- the variables in 'ansible/inventory/group_vars/all/' are merged into
- the variables in 'ansible/inventory/group_vars/*/' and then merged with
- the variables in 'ansible/inventory/host_vars/<host>/*/'
During the merge process, the variables of the same name from lower levels
override the variables from higher levels. For example, if you define
'resources__paths' in the 'ansible/group_vars/all/resources.yml' file,
and
then define the same 'resources__paths' variable in
'ansible/host_vars/<host>/resources.yml' file, the value of the variable
defined on the host level will take precedence.
This of course has a problem on the "group level", since all groups are
esentially on the same level and the values will be read from the inventory
groups in the order they are defined (alphabetical according to the filenames,
I think). To aid with that, you can define in each group the
'ansible_group_priority' variable with a numerical value which can change the
final group ordering.
But you still have one 'resources__group_paths' variable to work with so
that's another problem to solve. One way to go about it is to define
additional variables, one per group, and then merge them either in the 'all'
level for multiple hosts, or on the 'host' level for a single host. For
example, let's say you have an inventory like this:
#v+
[group_alpha]
hostname
[group_beta]
hostname
[group_gamma]
hostname
#v-
You can then define variables for that group in
'ansible/inventory/group_vars/<group>/resources.yml' file, for each group:
#v+
---
# ansible/inventory/group_vars/group_alpha/resources.yml
resources__group_alpha_paths: [ '/tmp/alpha' ]
#v-
#v+
---
# ansible/inventory/group_vars/group_beta/resources.yml
resources__group_beta_paths: [ '/tmp/beta' ]
#v-
#v+
---
# ansible/inventory/group_vars/group_gamma/resources.yml
resources__group_gamma_paths: [ '/tmp/gamma' ]
#v-
And to tie it all together, let's add all of the lists to each other on the
highest level so that if a host is in one of the groups, they will see the
proper values:
#v+
---
# ansible/inventory/group_vars/all/resources.yml
resources__group_paths: '{{ q("flattened",
resources__group_alpha_paths | d([])
+ resources__group_beta_paths | d([])
+ resources__group_gamma_paths | d([])) }}'
#v-
Notice the 'd([])' statements - this is needed so that if a host is not in one
of the groups, it doesn't result in an undefined variable and role being
broken.
Yes, this system is cumbersome, brittle and needs to be hand-holded on each
change when you add or remove groups. But that's the nature of Ansible and
inventories based on YAML files. A better alternative would be to set up some
kind of dynamic inventory which returns the variables you want for each host
when Ansible calls it. But that might be overkill depending on the size of
your environment.
Am 21.08.20 um 11:43 schrieb Imre Jonk:
> On Thu, 2020-08-20 at 12:55 +0200, dev wrote:
what do you mean by overriding? from my understanding, they should all be
“combined”, i.e.
|resources__commands| will be concatenated with all
|resources__group_commands|, and then concatenated with the
|resources__host_commands|.
if there are entries with the same |name:|, the last one wins.
so, when a host is part in diff. groups of the same role, which i.e. have
all |resources__group_commands| in the inventory, how can one group
overwrite the other, given the fact that I don’t use the same |name:| for
commands
Just to reiterate - this is done by Ansible itself during inventory
processing, there's no way to handle this in the roles themselves. Well,
actually there is - you just write roles with all the group variables that you
want. But DebOps roles are different - they are meant to be read-only, so that
updates can be possible. That's why we need to work around this limitation
with an additional variable that merges the group variables, described above.
> 2. Change Ansible's hash_behaviour to merge variables
instead of
> overriding them. I haven't tried this though, it might very well mess
> everything up (and the Ansible documentation recommends against
> changing it). But if you want to give it a try, add "hash_behaviour =
> merge" to the [ansible defaults] section in .debops.cfg.
Please don't use 'hash_behaviour=merge', even its original proponent
discourages it[1]. It was also deprecated in Ansible and will be removed in
the future[2]. Better not to rely on it which leads to broken behaviour.
[1]:
https://www.reddit.com/r/ansible/comments/a7x92q/in_which_case_hash_behav...
[2]:
https://github.com/ansible/ansible/pull/63300
I had a look at the how-variables-are-merged
<
https://docs.ansible.com/ansible/latest/user_guide/intro_inventory.html#h...
and it talks about overwriting variables with the same name.
does that mean, variables like |apt_install__group_packages| are overwritten
by each later group in the alphabet which also uses
|apt_install__group_packages|?
Yes.
when I understand that right, that would mean, each host could
effectively
be only in one group per role, where some of this i.e.
|apt_install__group_pks|, |resources__group_*| are used.
That's true, but there are ways to work around that. Some of the newer DebOps
roles that rely on a custom filter to process their variables, use a special
'<role>__combined_variables' pattern which are variables that define a list
of
default variables to work on. These specific variables can be redefined by the
user in the inventory to let the role process multiple group variables or even
data from other sources like 'consul' or 'etcd' databases, when processed
via
lookup plugins. But the roles you are interested in ('apt_install',
'resources') currently don't use this system.
> Let's see if option #1 works for you. You can also post the
relevant
> inventory variables to the mailing list so that we can have a look.
my real world example is of that structure:
I have a couple of proxmox-hosts. to set them up, I depend heavily on the
“resources__*” role
there are settings (pve-user, groups, acls, backup-strorage, image-downloads
etc.), which are all the same for all my PVEs, which I wrote in
|resources__group_[files, urls, commands]|
then there are hostbased settings (i.e disk-structures, storage-def.), which
go into:
|resources__host_[files, urls, commands]|
and the there is this new and shiny Proxmox-Backup-Server PBS, which uses
the same role-structure and is likely to be installed on the same hosts (but
not always), but utilizes diff. groups
|resources__group_[files, urls, commands]|
then there are hostbased settings, which go into:
|resources__host_[files, urls, commands]|
how to arrange something like that?
You can check the extended example above to see how the issue of multiple
inventory groups can be solved in the inventory itself.
If this is something that you plan to rely on often, I would also consider
rewriting this into a proper role or multiple roles. The 'resources' role
+ configuration via Ansible inventory is a good "staging setup", but
encapsulating all this into a proper Ansible role might give you access to
more tools like proper 'systemd' or 'service' Ansible modules,
idempotency,
etc. You can then apply that role via its playbook with other DebOps playbook
and services that you use, for example:
debops common service/mariadb_server custom_proxmox_role -l host1,host2
Let us know if you have any other questions, and have fun with DebOps. :-)
-- Maciej