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
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.
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
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:
staging:
sudoers:
prod:
sudoers:
-it
-releng
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
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
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
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
Something like this sounds like a good compromise!
-- Michael
this is easy to implement using yaml tags/directives, but would look a bit diff:
mysql: !!merge
port: some_default_value4
Brian,
That's interesting -- so if "!!merge" was specified somewhere down the
line that var would get merged versus replaced? I like it!
- James
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.
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
Er maybe?
Checkout my quick implementation at https://github.com/tartansandal/ansible.git
If I run the following against it
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
Hi guys,
If we’re talking about implementation of new features, this should go to ansible-devel list
Thanks!