# group\_vars best practices

**URL:** <https://forum.ansible.com/t/group-vars-best-practices/14065>\
**Category:** Ansible Project\
**Created:** [December 4, 2013, 10:05pm UTC](https://forum.ansible.com/t/group-vars-best-practices/14065 "2013-12-04T22:05:40Z")\
**Posts on this page:** 17\
**Page:** 1

<div class="post-metadata">

**Author:** ![James\_Martin2](https://avatars.discourse-cdn.com/v4/letter/j/b9e5f3/32.png) [@James\_Martin2](https://forum.ansible.com/u/James_Martin2)\
**Post date:** [December 4, 2013, 10:05pm UTC](https://forum.ansible.com/t/group-vars-best-practices/14065/1 "2013-12-04T22:05:40Z")

</div>

Is it considered bad practice to have variables in group\_vars defined as such:

ntp:  
&nbsp;&nbsp;server: server.foo.com  
&nbsp;&nbsp;setting: foo

myapp:  
&nbsp;&nbsp;&nbsp;database: bar  
&nbsp;&nbsp;&nbsp;option: baz

instead of :

ntp\_server: server.foo.com  
ntp\_setting: foo

myapp\_database: bar  
myapp\_option: baz

It seems the first option is cleaner, but I don't believe you could  
override variables in your hosts file. Instead, you'd create a  
inventory/host\_vars/myhost file to override?

Thanks,

James

---

<div class="post-metadata">

**Author:** ![Michael\_DeHaan2](https://avatars.discourse-cdn.com/v4/letter/m/da6949/32.png) [@Michael\_DeHaan2](https://forum.ansible.com/u/Michael_DeHaan2)\
**Post date:** [December 4, 2013, 10:25pm UTC](https://forum.ansible.com/t/group-vars-best-practices/14065/2 "2013-12-04T22:25:17Z")

</div>

There’s no problem doing it either way, but you’re right in that the first requires configuring host variable merging in ansible.cfg (which is not the standard option).

As a result, people shouldn’t really write roles for sharing that rely on that in many cases.

---

<div class="post-metadata">

**Author:** ![James\_Martin2](https://avatars.discourse-cdn.com/v4/letter/j/b9e5f3/32.png) [@James\_Martin2](https://forum.ansible.com/u/James_Martin2)\
**Post date:** [December 4, 2013, 11:31pm UTC](https://forum.ansible.com/t/group-vars-best-practices/14065/3 "2013-12-04T23:31:22Z")

</div>

I'm trying to visualize a case where hash merging would be bad:

Let's you had this in your group\_vars/all

foo:  
&nbsp;&nbsp;bar: baz  
&nbsp;&nbsp;zib: zab

but at some point you wanted to override that completely with:

foo:  
&nbsp;&nbsp;bar: biz

If you had merging on, that would yield:

foo:  
&nbsp;&nbsp;bar: biz  
&nbsp;&nbsp;zib: zab

Without merging, it would yield:

foo:  
&nbsp;&nbsp;bar:biz

Is that why merging is off by default?

- James

---

<div class="post-metadata">

**Author:** ![Michael\_DeHaan2](https://avatars.discourse-cdn.com/v4/letter/m/da6949/32.png) [@Michael\_DeHaan2](https://forum.ansible.com/u/Michael_DeHaan2)\
**Post date:** [December 4, 2013, 11:34pm UTC](https://forum.ansible.com/t/group-vars-best-practices/14065/4 "2013-12-04T23:34:37Z")

</div>

Yep!

-- Michael

---

<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:** [December 5, 2013, 12:43am UTC](https://forum.ansible.com/t/group-vars-best-practices/14065/5 "2013-12-05T00:43:54Z")

</div>

group\_vars/all:  
tomcat\_jvm\_settings:

- debug=on
- GCfunckymode=True
- dump\_heap=true

group\_vars/prod:  
tomcat\_jvm\_settings:

- XmxMax: 234324
- XmxMin: 12342

with merge off, i can use same settings for dev/qa/staging and differnt ones for prod, if i had merge ON, i would have to always override the settings in prod:

- debug=off
- GCfunkymode=False
- dump\_heap=true

but I think a better example is with user access:

all:  
sudoers:

- devs
- managers
- it
- releng

staging:  
sudoers:

- managers
- releng
- it

prod:  
sudoers:  
-it  
-releng

---

<div class="post-metadata">

**Author:** ![James\_Martin2](https://avatars.discourse-cdn.com/v4/letter/j/b9e5f3/32.png) [@James\_Martin2](https://forum.ansible.com/u/James_Martin2)\
**Post date:** [December 5, 2013, 5:17pm UTC](https://forum.ansible.com/t/group-vars-best-practices/14065/6 "2013-12-05T17:17:05Z")

</div>

Thanks for the example. Would it be crazy/possible to implement  
optional merging dependent on the hash's name? Seems like for some  
vars you could possibly want it, in others, not. So things that are  
in nature restrictive like sudo would be merged, and others wouldn't.

something like:

hash\_behaviour = replace # by default we replace all vars except  
those in merge\_hashes  
merge\_hashes = foo, baz, bar

- James

---

<div class="post-metadata">

**Author:** ![kahlil.hodgson](https://avatars.discourse-cdn.com/v4/letter/k/b9bd4f/32.png) [@kahlil.hodgson](https://forum.ansible.com/u/kahlil.hodgson)\
**Post date:** [December 5, 2013, 7:48pm UTC](https://forum.ansible.com/t/group-vars-best-practices/14065/7 "2013-12-05T19:48:13Z")

</div>

I wonder if merging could be handled explicitly with a jinja filter,  
say, something like:

&nbsp;&nbsp;&nbsp;&nbsp;mysql: prod\_mysql | merge(default\_mysql)

That way the merging would be explicit and encapsulated in the playbook.

Kahlil (Kal) Hodgson GPG: C9A02289  
Head of Technology (m) +61 (0) 4 2573 0382  
DealMax Pty Ltd (w) +61 (0) 3 9008 5281

Suite 1415  
401 Docklands Drive  
Docklands VIC 3008 Australia

"All parts should go together without forcing. You must remember that  
the parts you are reassembling were disassembled by you. Therefore,  
if you can't get them together again, there must be a reason. By all  
means, do not use a hammer." -- IBM maintenance manual, 1925

---

<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:** [December 5, 2013, 8:09pm UTC](https://forum.ansible.com/t/group-vars-best-practices/14065/8 "2013-12-05T20:09:52Z")

</div>

​I agree it would be a good feature if merging dicts or not could be​ set  
more granullary.

About your example, I think this is already possible with Jinja2, something  
like

{{ default\_mysql.update(prod\_mysql) }}

But allowing merges or not per variable, instead of inventory wide as per  
ansible.cfg is more difficult. Code wise, the merging happens​ (or not)  
when loading the inventory, before a host is contacted for the first time,  
and before the playbook starts to run, so this example can't be implemented  
(at least without a major update to ansible.)

I think going that path would add a lot of unnecessary complexity, e.g. the  
following ugly example 🙂

GROUP: all  
mysql:  
&nbsp;&nbsp;\_meta\_merge: True  
&nbsp;&nbsp;server: some\_default\_value1  
&nbsp;&nbsp;port: some\_default\_value2

GROUP: production  
mysql:  
&nbsp;&nbsp;\_meta\_merge: True  
&nbsp;&nbsp;port: some\_default\_value3

GROUP: production  
mysql:  
&nbsp;&nbsp;\_meta\_merge: True  
&nbsp;&nbsp;port: some\_default\_value4

Serge  
​

---

<div class="post-metadata">

**Author:** ![Michael\_DeHaan2](https://avatars.discourse-cdn.com/v4/letter/m/da6949/32.png) [@Michael\_DeHaan2](https://forum.ansible.com/u/Michael_DeHaan2)\
**Post date:** [December 5, 2013, 9:28pm UTC](https://forum.ansible.com/t/group-vars-best-practices/14065/9 "2013-12-05T21:28:45Z")

</div>

I'd rather not introduce something like that as adds something rather  
abstract to think about which would not be immediately clear when  
auditing the playbook.

-- Michael

---

<div class="post-metadata">

**Author:** ![Michael\_DeHaan2](https://avatars.discourse-cdn.com/v4/letter/m/da6949/32.png) [@Michael\_DeHaan2](https://forum.ansible.com/u/Michael_DeHaan2)\
**Post date:** [December 5, 2013, 9:29pm UTC](https://forum.ansible.com/t/group-vars-best-practices/14065/10 "2013-12-05T21:29:13Z")

</div>

Something like this sounds like a good compromise!

-- Michael

---

<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:** [December 5, 2013, 9:58pm UTC](https://forum.ansible.com/t/group-vars-best-practices/14065/11 "2013-12-05T21:58:52Z")

</div>

this is easy to implement using yaml tags/directives, but would look a bit diff:

mysql: !!merge  
port: some\_default\_value4

---

<div class="post-metadata">

**Author:** ![James\_Martin2](https://avatars.discourse-cdn.com/v4/letter/j/b9e5f3/32.png) [@James\_Martin2](https://forum.ansible.com/u/James_Martin2)\
**Post date:** [December 5, 2013, 10:14pm UTC](https://forum.ansible.com/t/group-vars-best-practices/14065/12 "2013-12-05T22:14:17Z")

</div>

Brian,

That's interesting -- so if "!!merge" was specified somewhere down the  
line that var would get merged versus replaced? I like it!

- James

---

<div class="post-metadata">

**Author:** ![Michael\_DeHaan2](https://avatars.discourse-cdn.com/v4/letter/m/da6949/32.png) [@Michael\_DeHaan2](https://forum.ansible.com/u/Michael_DeHaan2)\
**Post date:** [December 5, 2013, 10:19pm UTC](https://forum.ansible.com/t/group-vars-best-practices/14065/13 "2013-12-05T22:19:05Z")

</div>

I don’t like it at all.

We shouldn’t be inserting lesser known YAML syntax into things, especially if we have to define a new “directive”.

This would be moving Ansible down the wrong direction.

---

<div class="post-metadata">

**Author:** ![James\_Martin2](https://avatars.discourse-cdn.com/v4/letter/j/b9e5f3/32.png) [@James\_Martin2](https://forum.ansible.com/u/James_Martin2)\
**Post date:** [December 6, 2013, 3:24am UTC](https://forum.ansible.com/t/group-vars-best-practices/14065/14 "2013-12-06T03:24:54Z")

</div>

Kahlil,

Is this how you'd expect your solution to work?

I'm thinking in your case you'd have a

group\_vars/all:

default\_mysql:  
&nbsp;&nbsp;setting1: foo  
&nbsp;&nbsp;setting2: bar  
&nbsp;&nbsp;setting3: baz

group\_vars/prod\_mysql  
&nbsp;&nbsp;setting2: bip

and maybe you had a role called mysql that internally used "mysql" as  
the variable hash?

- James

---

<div class="post-metadata">

**Author:** ![kahlil.hodgson](https://avatars.discourse-cdn.com/v4/letter/k/b9bd4f/32.png) [@kahlil.hodgson](https://forum.ansible.com/u/kahlil.hodgson)\
**Post date:** [December 6, 2013, 7:18am UTC](https://forum.ansible.com/t/group-vars-best-practices/14065/15 "2013-12-06T07:18:02Z")

</div>

Er maybe?

Checkout my quick implementation at [https://github.com/tartansandal/ansible.git](https://github.com/tartansandal/ansible.git)

If I run the following against it

---

<div class="post-metadata">

**Author:** ![kahlil.hodgson](https://avatars.discourse-cdn.com/v4/letter/k/b9bd4f/32.png) [@kahlil.hodgson](https://forum.ansible.com/u/kahlil.hodgson)\
**Post date:** [December 6, 2013, 7:23am UTC](https://forum.ansible.com/t/group-vars-best-practices/14065/16 "2013-12-06T07:23:13Z")

</div>

Ergh, hit send too fast.

The branch you want to look at is called 'merge-filter'.

Apologies if this makes no sense because:

1. I've had a few beers,  
2. I'm writing this on a tram,  
3. My python skills are limited.

K

Kahlil (Kal) Hodgson GPG: C9A02289  
Head of Technology (m) +61 (0) 4 2573 0382  
DealMax Pty Ltd (w) +61 (0) 3 9008 5281

Suite 1415  
401 Docklands Drive  
Docklands VIC 3008 Australia

"All parts should go together without forcing. You must remember that  
the parts you are reassembling were disassembled by you. Therefore,  
if you can't get them together again, there must be a reason. By all  
means, do not use a hammer." -- IBM maintenance manual, 1925

---

<div class="post-metadata">

**Author:** ![Michael\_DeHaan2](https://avatars.discourse-cdn.com/v4/letter/m/da6949/32.png) [@Michael\_DeHaan2](https://forum.ansible.com/u/Michael_DeHaan2)\
**Post date:** [December 6, 2013, 12:56pm UTC](https://forum.ansible.com/t/group-vars-best-practices/14065/17 "2013-12-06T12:56:56Z")

</div>

Hi guys,

If we’re talking about implementation of new features, this should go to ansible-devel list

Thanks!
