group_vars best practices

1,237 views
Skip to first unread message

James Martin

unread,
Dec 4, 2013, 5:05:40 PM12/4/13
to ansible...@googlegroups.com
Is it considered bad practice to have variables in group_vars defined as such:


ntp:
server: server.foo.com
setting: foo

myapp:
database: bar
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

Michael DeHaan

unread,
Dec 4, 2013, 5:25:17 PM12/4/13
to ansible...@googlegroups.com
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.





--
You received this message because you are subscribed to the Google Groups "Ansible Project" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ansible-proje...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.



--
Michael DeHaan <mic...@ansibleworks.com>
CTO, AnsibleWorks, Inc.
http://www.ansibleworks.com/

James Martin

unread,
Dec 4, 2013, 6:31:22 PM12/4/13
to ansible...@googlegroups.com
I'm trying to visualize a case where hash merging would be bad:

Let's you had this in your group_vars/all

foo:
bar: baz
zib: zab

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

foo:
bar: biz


If you had merging on, that would yield:

foo:
bar: biz
zib: zab

Without merging, it would yield:

foo:
bar:biz

Is that why merging is off by default?

- James

Michael DeHaan

unread,
Dec 4, 2013, 6:34:37 PM12/4/13
to ansible...@googlegroups.com
Yep!

-- Michael

Brian Coca

unread,
Dec 4, 2013, 7:43:54 PM12/4/13
to ansible...@googlegroups.com
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

James Martin

unread,
Dec 5, 2013, 12:17:05 PM12/5/13
to ansible...@googlegroups.com
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

Kahlil Hodgson

unread,
Dec 5, 2013, 2:48:13 PM12/5/13
to ansible...@googlegroups.com
I wonder if merging could be handled explicitly with a jinja filter,
say, something like:

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

Serge van Ginderachter

unread,
Dec 5, 2013, 3:09:52 PM12/5/13
to ansible...@googlegroups.com

On 5 December 2013 20:48, Kahlil Hodgson <kahlil....@dealmax.com.au> wrote:
I wonder if merging could be handled explicitly with a jinja filter,
say, something like:

    mysql: prod_mysql | merge(default_mysql)

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

​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:
  _meta_merge: True
  server: some_default_value1
  port: some_default_value2
  
GROUP: production
mysql:
  _meta_merge: True
  port: some_default_value3

GROUP: production
mysql:
  _meta_merge: True
  port: some_default_value4
  


Serge

Michael DeHaan

unread,
Dec 5, 2013, 4:28:45 PM12/5/13
to ansible...@googlegroups.com
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

Michael DeHaan

unread,
Dec 5, 2013, 4:29:13 PM12/5/13
to ansible...@googlegroups.com
Something like this sounds like a good compromise!

-- Michael

Brian Coca

unread,
Dec 5, 2013, 4:58:52 PM12/5/13
to ansible...@googlegroups.com
this is easy to implement using yaml tags/directives, but would look a bit diff:

mysql: !!merge
  port: some_default_value4

James Martin

unread,
Dec 5, 2013, 5:14:17 PM12/5/13
to ansible...@googlegroups.com
Brian,

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

- James

Michael DeHaan

unread,
Dec 5, 2013, 5:19:05 PM12/5/13
to ansible...@googlegroups.com
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.



James Martin

unread,
Dec 5, 2013, 10:24:54 PM12/5/13
to ansible...@googlegroups.com
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:
setting1: foo
setting2: bar
setting3: baz


group_vars/prod_mysql
setting2: bip


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

- James

Kahlil Hodgson

unread,
Dec 6, 2013, 2:18:02 AM12/6/13
to ansible...@googlegroups.com
Er maybe?

Checkout my quick implementation at https://github.com/tartansandal/ansible.git

If I run the following against it

---
- name: merging like a maniac
hosts: localhost
connection: local
vars:
- foo:
- a:
- luck:
a: c
b: d
- b:
- luck:
a: g
e: f
- bar:
- a:
- luck:
z: q
a: t

- baz: "{{ foo | merge(bar) }}"

tasks:
- debug: var=baz


I get:

<eric:ansible> ansible-playbook stub.yml -i hosts

PLAY [merging like a maniac] **************************************************

GATHERING FACTS ***************************************************************
ok: [localhost]

TASK: [debug var=baz] *********************************************************
ok: [localhost] => {
"baz": [
{
"a": [
{
"luck": {
"a": "t",
"b": "d",
"z": "q"
}
}
]
},
{
"b": [
{
"luck": {
"a": "g",
"e": "f"
}
}
]
}
]
}

PLAY RECAP ********************************************************************
localhost : ok=2 changed=0 unreachable=0 failed=0



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



Kahlil Hodgson

unread,
Dec 6, 2013, 2:23:13 AM12/6/13
to ansible...@googlegroups.com
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



Michael DeHaan

unread,
Dec 6, 2013, 7:56:56 AM12/6/13
to ansible...@googlegroups.com
Hi guys,

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

Thanks!
Reply all
Reply to author
Forward
0 new messages