Search code examples
ansiblejinja2ansible-2.xansible-facts

Add key-value pair to a dictionary only if value is present


I wanted to add a key-value pair if and only if the value has been declared/found previously. If there is no declaration of the variable, then I do not want to add the key-value pair in the dictionary.

---
- hosts: localhost
  tasks:
    - name: Set fruits
      set_fact:
        fruits:
          name: "Apple"
          color: "Red"
          size: "Medium"

#    - name: set place
#      set_fact:
#        place: "Earth"

    - name: Add place if present
      set_fact:
        fruits: "{{ fruits | combine ({ 'place' : place })  }}"

    - debug:
        msg: "{{ fruits }}"

Here's the output of the above script:

ok: [localhost] => {
    "msg": "{'name': 'Apple', 'color': 'Red', 'size': 'Medium', 'place': AnsibleUndefined}"
}

Expected output:

ok: [localhost] => {
    "msg": "{'name': 'Apple', 'color': 'Red', 'size': 'Medium'}"
}

What changes should be done to obtain the expected output? Any help would be appreciated. Thank you.

EDIT: Basically, I am passing the updated dictionary('fruits') to another playbook as an argument. Is it possible to achieve this inline (by adding some command in the command where 'fruits' was updated) rather than adding a condition check using 'when' statement?


Solution

  • Set default to omit. The operation will be omitted if the variable place is not defined

        - name: Add place if present
          set_fact:
            fruits: "{{ fruits|combine({'place' : place|d(omit)}) }}"
    

    Q: "Do not remove the already present 'place' field if variable place is not defined."

    A: Try this. Use default fruit.place if defined otherwise omit

        - name: Add place if present
          set_fact:
            fruits: "{{ fruits|combine({'place' : _place}) }}"
          vars:
            _place: "{{ place|d(fruit.place)|d(omit) }}"