Multiple inventory: latest var is not override

Hello.

I have a var “db_name” in three locations:

  1. path1/inventory/group_vars/pgdb.yml , db_name: “database1”
  2. path2/inventory/group_vars/pgdb.yml , db_name: “database2”
  3. path2/inventory/group_vars/server.yml , db_name: “database3”

I have an ansible.cfg file with these multiple inventories.
According to documentation: Variables defined multiple times are overwritten, the last one defined wins.

When I tried to debug this var, I got one result, that was not expected:
Example 1 (expected)
ansible.cfg looks like:

...
inventory = path1/inventory
...

debug db_name show “database1”.

Example 2 (expected)
ansible.cfg looks like:

...
inventory = path2/inventory
...

debug db_name show “database3”.

Example 3 (not expected)
ansible.cfg looks like:

...
inventory = path1/inventory,path2/inventory
...

debug db_name show “database2”.

Dear Sirs, could you answer, please, what it can be?

doing something like ansible <hostname/pattern> -m debug -a "var=hostvars[inventory_hostname]" and looking at the group_names object might help clue you in on what’s going on?

What appears to be happening is that its processing path2/inventory/group_vars/pgdb.yml last, which is not what I’d expect to be happening.

yes, this is expected and documented. the inventories are parsed in order , variables are flattened to the host level and last one wins when there is a conflict. https://docs.ansible.com/ansible/latest/inventory_guide/intro_inventory.html#intro-inventory

I can’t agree with you completely, because:

the inventories are parsed in order

In 3d example, as we see, wins second inventory with two same vars. It means, that 1st inventory didn’t use for resolving conflicts - it’s expected.

variables are flattened to the host level and last one wins when there is a conflict

I have a host in two groups: “pgdb” and “server”. Last var, in alphabetically order, always wins(from “server”).
And when I set only one inventory(2nd example), it works.
But it didn’t work with two inventories(3d example).
It is the question.

doing something like ansible <hostname/pattern> -m debug -a "var=hostvars[inventory_hostname]" and looking at the group_names object might help clue you in on what’s going on?

It is always one host for testing. I just modify ansible.cfg. Groups are identical.

What appears to be happening is that its processing path2/inventory/group_vars/pgdb.yml last, which is not what I’d expect to be happening.

When I set only one(inventory path2), processing is going in right order.
When I set two inventories, it looks like processing works only with first found var.

That documentation applies to inventory sources. group_vars aren’t inventory sources themselves - for those, the order depends on the order of the host’s groups. The documentation should be clearer about this. For example, with this inventory file:

[server:children]
pgdb

[pgdb]
host

The ancestor groups are always ordered first, so the variable plugin receives the groups in the order server, pgdb, causing the pgdb variables to win. If I don’t use child groups, then it seems to be alphabetical.

yes, group variables are merged by parent/child, priority and name (you can set priority yourself, if not set its 0)

1 Like

@shertel @bcoca dear sirs, I can’t understand why it works normally with one inventory, but breaks with multiple.

Based on what @shertel and @bcoca have said, I think we need to see your inventory file to tell for sure.

It sounds like, if there is any inheritance going on there, that changes the order that the group_vars files are parsed it.

1 Like

i’m not sure what you mean by ‘break’, as i stated above there is a precedence, by inventory source and playbook dir as the locations which then get processed by vars plugins (host_group_vars in this case). Then variables get merged by entity, first by groups, with internal precedence as stated above and with the ‘all’ group being treated specially. Then via the host name.

I believe the issue is that you are assuming that inventory sources are not part of the precedence. While this is documented in several places, the main ‘list’ is mostly oriented to a single inventory and assumes the default vars plugin, I have been planning on updating to be more explicit about other cases.