How to add a key / value to a dict in an unoccupied play, conditionally

Let's say I want to add the InterestingVar dict key and the associated value when the test_var variable test_var (passed with -e in command line ), how can I do this?

 # ansible-playbook ./add_to_dict_on_condition.yml -i 127.0.0.1, -e env=test -e test_var=123 - hosts: localhost gather_facts: no vars: - tags: InterestingVar: "{{test_var}}" # How to omit this line if test_var == '' ? Name: xxx Env: "{{ env }}" tasks: - debug: var=tags 

I tested

  InterestingVar: "{{test_var|default(omit)}} 

but I get:

 "InterestingVar": "__omit_place_holder__caca01e207397883640613b08e8ce3a8fbdd6" 

instead of nothing.

Any help would be greatly appreciated.

I am using ansible 1.8

+7
jinja2 ansible ansible-playbook
source share
1 answer

The only thing I can think of is to combine the dictionaries with the set_fact task when your condition is met. It depends on the combine filter introduced in Ansible 2.0.

 - hosts: localhost connection: local gather_facts: no vars: - tags: Name: xxx Env: "{{ env }}" - optional_tags: InterestingVar: "{{ test_var }}" tasks: - name: combine tags set_fact: tags: "{{ tags | combine(optional_tags) }}" when: test_var is defined - name: debug tags debug: var=tags 

Which outputs the following, then test_var is undefined:

 vagrant@Test-02 :~$ ansible-playbook -i "localhost," conditional_key.yml -e "env=test" PLAY *************************************************************************** TASK [combine tags] ************************************************************ skipping: [localhost] TASK [debug tags] ************************************************************** ok: [localhost] => { "changed": false, "tags": { "Env": "test", "Name": "xxx" } } PLAY RECAP ********************************************************************* localhost : ok=1 changed=0 unreachable=0 failed=0 

And this conclusion, when defined:

 vagrant@Test-02 :~$ ansible-playbook -i "localhost," conditional_key.yml -e "env=test" -e "test_var=123" PLAY *************************************************************************** TASK [combine tags] ************************************************************ ok: [localhost] TASK [debug tags] ************************************************************** ok: [localhost] => { "changed": false, "tags": { "Env": "test", "InterestingVar": "123", "Name": "xxx" } } PLAY RECAP ********************************************************************* localhost : ok=2 changed=0 unreachable=0 failed=0 

If you cannot use 2.0+, then another option would be to change the Ansible hash behavior to merge the dictionaries, rather than overriding them by setting:

 hash_behaviour=merge 

at ansible.cfg .

With this, you could use something like this:

 - hosts: localhost connection: local gather_facts: no vars: - tags: Name: xxx Env: "{{ env }}" - tags: InterestingVar: "{{ test_var }}" tasks: - name: debug tags debug: var=tags 

With your vars defined in the following files:

 vagrant@Test-01 :~$ cat tags.yml tags: Name: xxx Env: "{{ env }}" vagrant@Test-01 :~$ cat optional_tags.yml tags: InterestingVar: "{{ test_var }}" 

Then you will get the desired result, but you should not include optional_vars.yml if you do not have test_var :

 vagrant@Test-01 :~$ ansible-playbook -i "localhost," conditional_key.yml -e "env=test" -e "test_var=123" -e@tags.yml -e@optional _tags.yml PLAY [localhost] ************************************************************** TASK: [debug tags] ************************************************************ ok: [localhost] => { "var": { "tags": { "Env": "test", "InterestingVar": "123", "Name": "xxx" } } } PLAY RECAP ******************************************************************** localhost : ok=1 changed=0 unreachable=0 failed=0 

Keep in mind that using this approach, any expected redefinition of dictionaries through inheritance now combines dictionaries instead, so this may not be all that is useful for those who redefine them in their inventories.

+6
source share

All Articles