I’m having
a bit of trouble figuring out the best structure for declaring a default variable
value per inventory group that would be used by a role, that is over rideable per
inventory.
I'm aware that versions of this question have been asked many, many times before but I haven't yet seen a suitable answer.
I’ve structured my project similar to this:
├── ansible.cfg
├── inventories/ # Parent directory for our environment-specific directories
│ │
│ ├── dev/ # Contains all files specific to the dev environment
│ │ ├── group_vars/ # dev specific group_vars files
│ │ │ ├── all.yml
│ │ │ ├── billing.yml
│ │ │ └── policy.yml
│ │ └── hosts # Contains only the hosts in the dev environment
│ │
│ ├── prod/ # As above but for the prod environment
│ │
│ └── stage/ # As above but for the stage environment
│
├── playbook.yml
├── group_vars/ # Play specific group_vars files
│ ├── all.yml
│ ├── billing.yml
│ └── policy.yml
│
├── roles/
│ ├── deploy-tomcat-war/
│
└── . . .
I keep all common variables in playbook/group_vars/<group>.yml because there is no other place to declare them that all inventories have access to (that I am aware of).
I keep all environment specific overrides in inventory/group_vars/<group>.yml.
For any of you familiar with my problem you’ll already know the fatal flaw in my approach. Ansible’s order of precedence means that the playbook/group_vars override inventory/group_vars. The “recommended” solution for this is to place the default variable declaration in playbook/group_vars/all as inventory/group_vars will override this, but playbook/group_vars/all does not support declaring the same variable with a different value per group.
https://github.com/ansible/ansible/issues/9877 has a very good write up of the issue but fails to come up with a good solution.
My understanding of the purpose of each Ansible component is:
Given that understanding it should follow that variables define in roles are overridden by those defined in playbook/group_vars which in turn should be overridden by those defined in inventories/group_vars. However I keep coming across the statement that “playbook/group_vars are meant to override the inventory as plays are more specific than inventory”. I don’t understand how the Ansible developers have come to that conclusion, sure playbooks control what is run but I would argue that inventories are more specific because they control the where.
All the proposed solutions I’ve seen fall into the following groups:
1. Use customs variable loader.
a. Seems a lot of work for something that should be in built
2. Put all override-able variables into playbook/group_vars/all.yml and which will allow you to use inventories/group_vars/<group>.yml to override them.
a. You lose the ability to define variables per group which is vital in my playbook / role combinations
3. Use environment specific groups in inventory your files.
a. I can’t even be bothered explaining how bad a solution that strikes me as
4. Keep fingers crossed that developers provide a mechanism to do this, e.g.
- allow override of the precedence order
- support groups in playbooks/group_vars/all/<group>/yml
a. Based on the age of some of the threads I’ve seen people have been waiting a long, long time so I'm not expecting this any time soon
So all you Ansible dev's out there, where do you suggest I put default variable declarations for each group where it can be overridden by an inventory if required?
roles\widget\defaults\main.yml - test_value: "role default"
inventories\_common\group_vars\all.yml - test_value: "inventory default"
inventories\dev\group_vars\all.yml - test_value: "dev envrionment value"
inventories\uat\group_vars\all.yml