Declare default variable values for two (or more) inventory groups using same role

32 views
Skip to first unread message

andrew...@xtra.co.nz

unread,
Aug 12, 2017, 6:04:04 PM8/12/17
to Ansible Project

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:

  • Inventories: define where a play is run (and organize servers by groups)
  • Playbooks: define what roles are applied to a group (the link between inventory and role)
  • Roles: define how the components are applied to the group

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?

andrew...@xtra.co.nz

unread,
Oct 4, 2017, 9:45:40 PM10/4/17
to Ansible Project
As there was no reply to my original question, now that ansible 2.4 has been released I'm coming in with a followup question.

In it's many new features is there any support for setting variables defaults per group that apply to all roles that can be overridden per inventory?

eg:
Variable configuration:
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

Result:

When using dev inventory test_value variable should contain "dev envrionment value"  
When using uat inventory test_value variable should contain "inventory default"  
 
 
A couple of options I have considered:

  1. I quite like the feature where you can specify multiple inventory files on the command line using -i file1 -i file2 as it has the added advantage of being able to define hosts and groups that can be shared along with variables but... I'd like to not have to specify that first -i file1 and have it picked from some configuration setting. Is this possible?
  1. I was also wondering if a custom inventory plugin might help here, I'm guessing it could read the inventory file and look for a tag like "include: ../_common" and process that inventory before continuing with the current inventory.  Not sure how much work that would be to implement or even if it would be feasible.  Does anyone have any thoughts on this approach?

Thanks
  Andrew
Reply all
Reply to author
Forward
0 new messages