pugazhendhi_r
pugazhendhi_r

Reputation: 101

Use variable with item in when condition in ansible task

I'm using the below playbook to capture the vmware datacenter information, which is working fine without any issues:

---
- hosts: localhost
  vars_files: 1credentials.yml
  tasks:
    - name: Gather information about all datacenters
      community.vmware.vmware_datacenter_info:
        hostname: '{{ vcenter_hostname }}'
        username: '{{ vcenter_username }}'
        password: '{{ vcenter_password }}'
        validate_certs: no
      delegate_to: localhost
      register: datacenter

    - debug:
        msg: "{{ item.name }}"
      loop: "{{ datacenter.datacenter_info }}"
      when:
        - item.name is defined
        - item.name == datacenter

below is the output:

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

TASK [Gathering Facts] *************************************************************************************************************************************************
ok: [localhost]

TASK [Gather information about all datacenters] ************************************************************************************************************************
ok: [localhost]

TASK [debug] ***********************************************************************************************************************************************************
skipping: [localhost] => (item={'name': 'Datacenter-Test', 'moid': 'datacenter-1247', 'config_status': 'gray', 'overall_status': 'gray'})
ok: [localhost] => (item={'name': 'opendc-rookie', 'moid': 'datacenter-2', 'config_status': 'gray', 'overall_status': 'gray'}) => {
    "msg": "opendc-rookie"
}

PLAY RECAP *************************************************************************************************************************************************************
localhost                  : ok=3    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

But when I try to use a var_prompt and ask for user input for the variable datacenter, as below:

---
- hosts: localhost
  vars_files: 1credentials.yml
  vars_prompt:
    - name: datacenter
      prompt: mention the datacenter name
      private: no
  tasks:
    - name: Gather information about all datacenters
      community.vmware.vmware_datacenter_info:
        hostname: '{{ vcenter_hostname }}'
        username: '{{ vcenter_username }}'
        password: '{{ vcenter_password }}'
        validate_certs: no
      delegate_to: localhost
      register: datacenter

    - debug:
        msg: "{{ item.name }}"
      loop: "{{ datacenter.datacenter_info }}"
      when:
        - item.name is defined
        - item.name == "datacenter"

It is skipping the debug task without substituting the datacenter variable's value which was the user's input in the when condition. Kindly suggest how can I incorporate the variable value with the when condition having item. Below is the output skipping the variable

mention the datacenter name: opendc-rookie

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

TASK [Gathering Facts] *************************************************************************************************************************************************
ok: [localhost]

TASK [Gather information about all datacenters] ************************************************************************************************************************
ok: [localhost]

TASK [debug] ***********************************************************************************************************************************************************
skipping: [localhost] => (item={'name': 'Datacenter-Test', 'moid': 'datacenter-1247', 'config_status': 'gray', 'overall_status': 'gray'})
skipping: [localhost] => (item={'name': 'opendc-rookie', 'moid': 'datacenter-2', 'config_status': 'gray', 'overall_status': 'gray'})
skipping: [localhost]

PLAY RECAP *************************************************************************************************************************************************************
localhost                  : ok=2    changed=0    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0

Upvotes: 0

Views: 6944

Answers (3)

Vladimir Botka
Vladimir Botka

Reputation: 68144

  • Use json_query. This filter doesn't fail when an attribute is missing. For example,
shell> cat pb.yml
- hosts: localhost
  vars:
    datacenter:
      datacenter_info:
        - config_status: gray
          moid: datacenter-1247
          name: Datacenter-Test
          overall_status: gray
        - config_status: gray
          moid: datacenter-2
          name: opendc-rookie
          overall_status: gray
  tasks:
    - debug:
        msg: "{{ _item }}"
      vars:
        _item: "{{ datacenter.datacenter_info|json_query(_query) }}"
        _query: '[?name == `{{ dc_name|d("") }}`]'

gives

shell> ansible-playbook pb.yml -e dc_name=Datacenter-Test

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

TASK [debug] *********************************************************************************
ok: [localhost] => 
  msg:
  - config_status: gray
    moid: datacenter-1247
    name: Datacenter-Test
    overall_status: gray
shell> ansible-playbook pb.yml

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

TASK [debug] *********************************************************************************
ok: [localhost] => 
  msg: []

  • You can iterate the list. For example,
    - debug:
        msg: "{{ item.name }}"
      loop: "{{ datacenter.datacenter_info|json_query(_query) }}"
      vars:
        _query: '[?name == `{{ dc_name|d("") }}`]'

  • If you want to test the name is in a list create an intersect. For example,
shell> cat pb.yml
- hosts: localhost
  vars:
    datacenter:
      datacenter_info:
        - config_status: gray
          moid: datacenter-1247
          name: Datacenter-Test
          overall_status: gray
        - config_status: gray
          moid: datacenter-2
          name: opendc-rookie
          overall_status: gray
    names: "{{ datacenter.datacenter_info|json_query('[].name') }}"
    dc_names: ''
    names_selected: "{{ names|intersect(dc_names.split(',')) }}"
  tasks:
    - debug:
        msg: "{{ item.name }}"
      loop: "{{ datacenter.datacenter_info }}"
      when: item.name|d('') in names_selected

gives

shell> ansible-playbook pb.yml -e dc_names=Datacenter-Test,opendc-rookie

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

TASK [debug] *********************************************************************************
ok: [localhost] => (item={'config_status': 'gray', 'moid': 'datacenter-1247', 'name': 'Datacenter-Test', 'overall_status': 'gray'}) => 
  msg: Datacenter-Test
ok: [localhost] => (item={'config_status': 'gray', 'moid': 'datacenter-2', 'name': 'opendc-rookie', 'overall_status': 'gray'}) => 
  msg: opendc-rookie
shell> ansible-playbook pb.yml -e dc_names=opendc-rookie

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

TASK [debug] *********************************************************************************
skipping: [localhost] => (item={'config_status': 'gray', 'moid': 'datacenter-1247', 'name': 'Datacenter-Test', 'overall_status': 'gray'}) 
ok: [localhost] => (item={'config_status': 'gray', 'moid': 'datacenter-2', 'name': 'opendc-rookie', 'overall_status': 'gray'}) => 
  msg: opendc-rookie
shell> ansible-playbook

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

TASK [debug] *********************************************************************************
skipping: [localhost] => (item={'config_status': 'gray', 'moid': 'datacenter-1247', 'name': 'Datacenter-Test', 'overall_status': 'gray'}) 
skipping: [localhost] => (item={'config_status': 'gray', 'moid': 'datacenter-2', 'name': 'opendc-rookie', 'overall_status': 'gray'}) 
skipping: [localhost]

Upvotes: 1

Frenchy
Frenchy

Reputation: 17027

i suggest you to rename your register value (same name than the prompt var)

- hosts: localhost
  vars_files: 1credentials.yml
  vars_prompt:
    - name: datacenter
      prompt: mention the datacenter name
      private: no
  tasks:
    - name: Gather information about all datacenters
      community.vmware.vmware_datacenter_info:
        hostname: '{{ vcenter_hostname }}'
        username: '{{ vcenter_username }}'
        password: '{{ vcenter_password }}'
        validate_certs: no
      delegate_to: localhost
      register: datacenterX

    - debug:
        msg: "{{ item.name }}"
      loop: "{{ datacenterX.datacenter_info }}"
      when:
        - item.name is defined
        - item.name == datacenter

Upvotes: 1

Romain
Romain

Reputation: 21948

In the trace we can see that the debug task is iterating over 2 dict items with the keys (or property) name = "Datacenter-Test" and name = "opendc-rookie". Since you have a condition on item.name == "datacenter", the condition will only be true for items having the property `name = "datacenter". Which is not what you want to achieve.

how can I add the list values "Datacenter-Test" and "opendc-rookie" as variable in the when condition

Here are two options to filter the list of datacenters in order to retain the two selected names.

  • "simple condition": use a simple or in the when condition.
  • "list condition": filter directly the list to iterate over the items defined in the list wanted_datacenters. This option works with an input ansible-playbook loop.yml --extra-vars='{"wanted_datacenters": ["opendc-rookie", "Datacenter-Test"]}'
- hosts: localhost
  vars:
    datacenter:
      - name: opendc-rookie
      - name: Datacenter-Test
    wanted_datacenters:
      - opendc-rookie
      - Datacenter-Test
  tasks:
    - name: "simple condition"
      debug:
        msg: "{{ item.name }}"
      loop: "{{ datacenter }}"
      when: item.name == "Datacenter-Test" or item.name == "opendc-rookie"
    - name: "list condition"
      debug:
        msg: "{{ item.name }}"
      loop: "{{ datacenter|selectattr('name', 'in', wanted_datacenters)|list }}"

Upvotes: 1

Related Questions