Ansible. Override Single Dictionary Key
Solution 1:
By default, Ansible overrides variables at the first level. If you want to be able to merge dictionaries, you have to change your ansible.cfg
file and set :
hash_behaviour=merge
(the default value being replace
).
Note that the Ansible team does not recommend this.
I guess this is a real dividing setting between users. A kind of decision that is done once for all : when you start using this feature, you can not go back, and you probably can not share your playbook with replace
-type people.
However, you can still benefit from the playbooks out there (I don't hink playbooks use replace
behaviour as a "feature"). It's like having an AB blood type, being an universal receiver... but since the magic usually happens at variable resolution, not inside tasks or templates, I think it is often possible to share your roles without any changes.
If you need to override a single key from, let's say, role parameters, you'll have to pass parameters in some convoluted way.
For instance, to override post_max_size
and upload_max_size
keys in a php5
dictionnary for a specific role, you'll have to do it this way :
- { role: php5-fpm, php5: { post_max_size: 40M,
upload_max_filesize: 20M }}
This being said, I use merge
behaviour since the beginning, and I'm pretty happy with it. It is very handy to keep variables organised.
Solution 2:
Starting with Ansible 2.0, you can use the Jinja2 combine
filter to merge YAML hashes/dictionaries without having to set hash_behavior=merge
at a global level in your ansible.cfg
file.
Relevant docs: https://docs.ansible.com/ansible/latest/user_guide/playbooks_filters.html#sts=Combining%20hashes/dictionaries%C2%B6
Solution 3:
The best way I have found is to use variables as the value of the dictionary item, and override that. I find this allows simple and powerful variable precedence with regards to ansible's order of variable
role/parent/defaults/main.yml
---
root_pw_value: ParentPassword
parent_dict:
- root_pw: "{{ root_pw_value }}"
role/child/defaults/main.yml
Note: role/child/meta/main.yml
contains dependencies: - { role: parent }
---
root_pw_value: ChildPassword
play-me.yml
---
- hosts: all
roles:
- child
roles/parent/tasks/main.yml & roles/child/tasks/main.yml
- debug: var=parent_dict
Run ansible -i localhost, --connection="local" play-me.yml
and you get the following output:
PLAY [all] ********************************************************************
GATHERING FACTS ***************************************************************
ok: [localhost]
TASK: [parent | debug var=parent_dict] ****************************************
ok: [localhost] => {
"var": {
"parent_dict": [
{
"root_pw": "ParentPassword"
}
]
}
}
TASK: [child | debug var=parent_dict] *****************************************
ok: [localhost] => {
"var": {
"parent_dict": [
{
"root_pw": "ChildPassword"
}
]
}
}
PLAY RECAP ********************************************************************
localhost : ok=3 changed=0 unreachable=0 failed=0
And these are defaults. If you specify root_pw_value
at more specific levels of precedence, such as inventory group/host variables, role variables, extra_vars on the command line, or anything from the precedence order[0] you'll get those.
Solution 4:
Just tried with ansible 1.9.3 and it works fine. Not sure but it seems you just have a typo within name of group_vars
directory (not groups_vars
).
Post a Comment for "Ansible. Override Single Dictionary Key"