# Hierarchical overrides for playbooks

**URL:** <https://forum.ansible.com/t/hierarchical-overrides-for-playbooks/16288>\
**Category:** Ansible Project\
**Created:** [September 19, 2014, 4:58pm UTC](https://forum.ansible.com/t/hierarchical-overrides-for-playbooks/16288 "2014-09-19T16:58:22Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![Javier\_Domingo\_Cansi](https://avatars.discourse-cdn.com/v4/letter/j/3ab097/32.png) [@Javier\_Domingo\_Cansi](https://forum.ansible.com/u/Javier_Domingo_Cansi)\
**Post date:** [September 19, 2014, 4:58pm UTC](https://forum.ansible.com/t/hierarchical-overrides-for-playbooks/16288/1 "2014-09-19T16:58:22Z")

</div>

Hello,

First of all, I am coming from puppet. I have already done some experiments with ansible, and created a user management module, mainly to create the root Authkeys file. This was a little approach to see how overrides etc are handled by ansible.

The result was having the module executed twice, one for the general case and the other for the specific one. Because of this, I wondered whether it would be possible to have overrides correctly done.

I have read a thread asking for Ansible's hiera, and for what I understood, you proposed using lookups and external inventories. I see ansible has a different way to do stuff, but I don't understand how this sort of features would provide such flexibility.

I would be glad if someone could help me understand how to correctly structure Ansible code for my use case.

---

<div class="post-metadata">

**Author:** ![Serge\_van\_Ginderacht](https://avatars.discourse-cdn.com/v4/letter/s/b782af/32.png) [@Serge\_van\_Ginderacht](https://forum.ansible.com/u/Serge_van_Ginderacht)\
**Post date:** [September 19, 2014, 5:25pm UTC](https://forum.ansible.com/t/hierarchical-overrides-for-playbooks/16288/2 "2014-09-19T17:25:24Z")

</div>

Hi Javier,

Perhaps you could start with explainig - for non-puppeteers here - what an ‘override’ exactly is, and show some basic high level example of what you try to accomplish?

Serge

---

<div class="post-metadata">

**Author:** ![Javier\_Domingo\_Cansi](https://avatars.discourse-cdn.com/v4/letter/j/3ab097/32.png) [@Javier\_Domingo\_Cansi](https://forum.ansible.com/u/Javier_Domingo_Cansi)\
**Post date:** [September 19, 2014, 5:45pm UTC](https://forum.ansible.com/t/hierarchical-overrides-for-playbooks/16288/3 "2014-09-19T17:45:38Z")

</div>

My module is just a template that loops on an array, where elements  
are users with groups belongings and sshkeys.

So, If I want to give access to all machines to sysadmins and  
developers the devs ones, my playbook would be:

---

<div class="post-metadata">

**Author:** ![Serge\_van\_Ginderacht](https://avatars.discourse-cdn.com/v4/letter/s/b782af/32.png) [@Serge\_van\_Ginderacht](https://forum.ansible.com/u/Serge_van_Ginderacht)\
**Post date:** [September 19, 2014, 6:09pm UTC](https://forum.ansible.com/t/hierarchical-overrides-for-playbooks/16288/4 "2014-09-19T18:09:16Z")

</div>

OK, I think I see it. There is no such thing as overriding playbooks. Playbooks are a series of plays that are a series of roles and tasks to execute, and tasks use variables.

The overriding here with ansible happens with variables in the inventory.

Given your case, you would define the variable user\_groups in the inventory, as a group variable:

group\_vars/all

---

<div class="post-metadata">

**Author:** ![Javier\_Domingo\_Cansi](https://avatars.discourse-cdn.com/v4/letter/j/3ab097/32.png) [@Javier\_Domingo\_Cansi](https://forum.ansible.com/u/Javier_Domingo_Cansi)\
**Post date:** [September 19, 2014, 8:36pm UTC](https://forum.ansible.com/t/hierarchical-overrides-for-playbooks/16288/5 "2014-09-19T20:36:00Z")

</div>

No no, I meant overriding variables. In this case, the variable “user\_groups” is an array of the groups that the role “users” has to install in each machine, and it doesn’t inherit from all the “sysadmin” group.

I need to know if there is something similar to achieve hierarchies of inheritance for variables. Or a big sample project. I need to understand how stuff is structured, because I find it like too linear atm, not allowing to specify that some machines have different properties makes harder to me to understand the abstraction layers.

I mean not being able to specify exceptions without having them be executed twice. (once for all and another for the specific case).

I understand is because of the knowledge I have and that I am accustomed to puppet, so any example on how to structure a big project would be really helpful. I aim to control everything with ansible, from users, configuration, installed programs, iptables rules, applications deployed, etc.

Thank you,

---

<div class="post-metadata">

**Author:** ![Serge\_van\_Ginderacht](https://avatars.discourse-cdn.com/v4/letter/s/b782af/32.png) [@Serge\_van\_Ginderacht](https://forum.ansible.com/u/Serge_van_Ginderacht)\
**Post date:** [September 19, 2014, 9:13pm UTC](https://forum.ansible.com/t/hierarchical-overrides-for-playbooks/16288/6 "2014-09-19T21:13:36Z")

</div>

​Javier,​

> No no, I meant overriding variables. In this case, the variable  
> "user\_groups" is an array of the groups that the role "users" has to  
> install in each machine, and it doesn't inherit from all the "sysadmin"  
> group.

​You are confusing me,  
- overriding variables happens within inventory groups, and as documented  
- ​you talk about a "sysadmin group". Is this a /etc/group group or an  
ansible group?

I need to know if there is something similar to achieve hierarchies of

> inheritance for variables.

​Yes, that's what I was talking about. groups within the inventory have a ​  
hierarch  
​y: child groups override​ parent groups.

Check  
&nbsp;&nbsp;&nbsp;&nbsp;[http://docs.ansible.com/intro\_inventory.html](http://docs.ansible.com/intro_inventory.html)  
and the topic of variable precedence

[http://docs.ansible.com/playbooks\_variables.html#variable-precedence-where-should-i-put-a-variable](http://docs.ansible.com/playbooks_variables.html#variable-precedence-where-should-i-put-a-variable)

(I'd agree the hierarchy of groups should be better documented though.)

Or a big sample project. I need to understand how stuff is structured,

> because I find it like too linear atm, not allowing to specify that some  
> machines have different properties makes harder to me to understand the  
> abstraction layers.

​Basically you can define groups of groups, and the deeper the group, the  
higher the level of importance.​

> I mean not being able to specify exceptions without having them be  
> executed twice. (once for all and another for the specific case).

​You need to execute on the highest level group​, then modify variables on  
child and/or grandchild groups.

> I understand is because of the knowledge I have and that I am accustomed  
> to puppet, so any example on how to structure a big project would be really  
> helpful. I aim to control everything with ansible, from users,  
> configuration, installed programs, iptables rules, applications deployed,  
> etc.

​I'm actually not aware of extensive examples​

​of group hierarchy. Maybe a fellow list member can help here?

&nbsp;&nbsp;Serge​

---

<div class="post-metadata">

**Author:** ![Brian\_Coca1](https://avatars.discourse-cdn.com/v4/letter/b/278dde/32.png) [@Brian\_Coca1](https://forum.ansible.com/u/Brian_Coca1)\
**Post date:** [September 21, 2014, 2:46pm UTC](https://forum.ansible.com/t/hierarchical-overrides-for-playbooks/16288/7 "2014-09-21T14:46:13Z")

</div>

I think an example can be clearer, your play would look like this:

- hosts: all  
&nbsp;&nbsp;user: root  
&nbsp;&nbsp;roles:  
&nbsp;&nbsp;&nbsp;&nbsp;- users

now in group\_vars/all you have

user\_groups:  
&nbsp;&nbsp;- sysadmins

and in group\_vars/dev you have

user\_groups:  
&nbsp;&nbsp;- sysadmins  
&nbsp;&nbsp;- development

This is using the default strategy that overwrites, if you set it to  
merge, you don't need to add the sysadmins in the devs file.

---

<div class="post-metadata">

**Author:** ![Michael\_DeHaan1](https://avatars.discourse-cdn.com/v4/letter/m/5e9695/32.png) [@Michael\_DeHaan1](https://forum.ansible.com/u/Michael_DeHaan1)\
**Post date:** [September 21, 2014, 7:37pm UTC](https://forum.ansible.com/t/hierarchical-overrides-for-playbooks/16288/8 "2014-09-21T19:37:41Z")

</div>

> Hello,
> 
> First of all, I am coming from puppet. I have already done some  
> experiments with ansible, and created a user management module, mainly to  
> create the root Authkeys file. This was a little approach to see how  
> overrides etc are handled by ansible.
> 
> The result was having the module executed twice, one for the general case  
> and the other for the specific one. Because of this, I wondered whether it  
> would be possible to have overrides correctly done.
> 
> I have read a thread asking for Ansible's hiera, and for what I  
> understood, you proposed using lookups and external inventories. I see  
> ansible has a different way to do stuff, but I don't understand how this  
> sort of features would provide such flexibility.

Yeah, you don't want.

That is a confusing overdesigned hack to patch over something Puppet  
couldn't do well originally, and something that Ansible was designed for  
early on.

Ansible provides all the group and inventory management \*out of the box\*,  
actually.

group\_vars, host\_vars, etc, all required without using an external tool.

---

<div class="post-metadata">

**Author:** ![Javier\_Domingo\_Cansi](https://avatars.discourse-cdn.com/v4/letter/j/3ab097/32.png) [@Javier\_Domingo\_Cansi](https://forum.ansible.com/u/Javier_Domingo_Cansi)\
**Post date:** [September 23, 2014, 11:33am UTC](https://forum.ansible.com/t/hierarchical-overrides-for-playbooks/16288/9 "2014-09-23T11:33:48Z")

</div>

One last questions. I learnt how to add new values (ex. devs can  
access dev), but how may I selectively use merge or not strategy?

I mean, I want overrides on user\_groups vars, but not in all of them.  
In puppet it exists lookup\_array, lookup\_hash for merges, and  
lookup\_hiera for overriding.

For example,  
--- groups\_all  
- users\_groups:  
&nbsp;&nbsp;- sysadmin  
--- groups\_dev  
- users\_groups:  
&nbsp;&nbsp;- devs

lookup\_hiera(users\_groups) =\> ['devs']  
lookup\_array(users\_groups) =\> ['devs', 'sysadmin']

So that I can choose to locally use some merge configs.

Thanks for the tips btw, I found strange the names but just because of  
not being used to =)

---

<div class="post-metadata">

**Author:** ![Brian\_Coca1](https://avatars.discourse-cdn.com/v4/letter/b/278dde/32.png) [@Brian\_Coca1](https://forum.ansible.com/u/Brian_Coca1)\
**Post date:** [September 23, 2014, 11:55am UTC](https://forum.ansible.com/t/hierarchical-overrides-for-playbooks/16288/10 "2014-09-23T11:55:01Z")

</div>

you could always compose by env:

in group\_vars/dev:

users: "{{devs|union(sysadmins)}}

in group\_vars/prod:

users: "{{sysadmins}}"

---

<div class="post-metadata">

**Author:** ![Javier\_Domingo\_Cansi](https://avatars.discourse-cdn.com/v4/letter/j/3ab097/32.png) [@Javier\_Domingo\_Cansi](https://forum.ansible.com/u/Javier_Domingo_Cansi)\
**Post date:** [September 23, 2014, 2:10pm UTC](https://forum.ansible.com/t/hierarchical-overrides-for-playbooks/16288/11 "2014-09-23T14:10:14Z")

</div>

The problem with that is that I have to say sysadmin...

wouldn't it be possible to have something like:

in group\_vars/all:

groups: sysadmins

in group\_vars/dev:

users: "{{devs|union(all)}}

in group\_vars/prod:

users: "{{nsoc|union(all}}"

For example?

The idea is to specify "Merge this with the higher level result" or  
"Substitute with this".

---

<div class="post-metadata">

**Author:** ![Brian\_Coca1](https://avatars.discourse-cdn.com/v4/letter/b/278dde/32.png) [@Brian\_Coca1](https://forum.ansible.com/u/Brian_Coca1)\
**Post date:** [September 23, 2014, 2:21pm UTC](https://forum.ansible.com/t/hierarchical-overrides-for-playbooks/16288/12 "2014-09-23T14:21:04Z")

</div>

no, union takes a list, not a inventory file name

you can set global merge behavior but not make it per item, not sure  
why specify the file works better than specify the list in the file

---

<div class="post-metadata">

**Author:** ![Javier\_Domingo\_Cansi](https://avatars.discourse-cdn.com/v4/letter/j/3ab097/32.png) [@Javier\_Domingo\_Cansi](https://forum.ansible.com/u/Javier_Domingo_Cansi)\
**Post date:** [September 24, 2014, 7:53am UTC](https://forum.ansible.com/t/hierarchical-overrides-for-playbooks/16288/13 "2014-09-24T07:53:55Z")

</div>

The idea is that if I want to merge top to bottom, makes no sense if I  
have to put all the vars of the top file in the bottom file.

I will try to explore a little bit if this is something I can achieve somehow...
