Checking whether nested variable is defined in the when statement

Nested data structures can be accessed either by indexing using the key name or dot syntax with the key name - https://docs.ansible.com/ansible/latest/user_guide/playbooks_variables.html#accessing-complex-variable-data

But I’m not able to access nested data structure from variables in the when statement. Here is a minimal sample to demonstrate the issue

cat play.yml

  • hosts: localhost

vars:

parent:

child1: true

tasks:

  • name: “Check if variable is defined”

fail:

msg: “mandatory variable {{ item }} not passed as extra args when invoking playbook”

when: item not in vars

loop:

  • parent

  • parent.child1

  • parent.child2

Here is the sample output

ansible-playbook play.yml (livingstone-dev/monitoring)

[WARNING]: No inventory was parsed, only implicit localhost is available

[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match ‘all’

PLAY [localhost] *********************************************************************************************************************************************

TASK [Gathering Facts] ***************************************************************************************************************************************

ok: [localhost]

TASK [Check if variable is defined] **************************************************************************************************************************

skipping: [localhost] => (item=parent)

failed: [localhost] (item=parent.child1) => {“ansible_loop_var”: “item”, “changed”: false, “item”: “parent.child1”, “msg”: “mandatory variable parent.child1 not passed as extra args when invoking playbook”}

failed: [localhost] (item=parent.child2) => {“ansible_loop_var”: “item”, “changed”: false, “item”: “parent.child2”, “msg”: “mandatory variable parent.child2 not passed as extra args when invoking playbook”}

PLAY RECAP ***************************************************************************************************************************************************

localhost : ok=1 changed=0 unreachable=0 failed=1 skipped=0 rescued=0 ignored=0

Any idea how I can have nested variables in ansible when statements.

Hi Emmanuel,

  vars:
    parent:
      child1: true
  tasks:
  - name: "Check if variable is defined"
    fail:
      msg: "mandatory variable {{ item }} not passed as extra args"
    when: item not in vars
    loop:
    - parent
    - parent.child1
    - parent.child2

skipping: [localhost] => (item=parent)
failed: [localhost] (item=parent.child1) => {"ansible_loop_var": "item",
"changed": false, "item": "parent.child1", "msg": "mandatory variable
parent.child1 not passed as extra args when invoking playbook"}

'json_query' returns 'False' when the parameter is not defined. 'set_fact'
before the evaluation to register the variable with 'hostvars'. For example

    - set_fact:
        parent: "{{ parent }}"

    - fail:
        msg: "mandatory variable {{ item }} not passed as extra args"
      when: not hostvars[inventory_hostname]|json_query(item)
      loop:
        - parent
        - parent.child1
        - parent.child2

Cheers,

  -vlado

Thanks Vladimir. I’m sure your solution works. I’ve figured out a simpler solution. Just posting it here for reference - https://stackoverflow.com/a/59367345/434678