ansible loop with when condition a register variable for more then one match string instance

Hi Team,

I am trying to loop with a condition to match vm_name for all the VM groups I see that the loop stops at the first instance match . I need help how can I run the loop for all the vm group name in the variable output to match vm_name and extract the match group names in the list

for example:

“vm_drs_groups”: "“[{‘group_name’: VM2-on-dev’, ‘vms’: [‘deep-test’, ‘NED-DEV601-X’], ‘type’: ‘vm’}, {‘group_name’: ‘VM2-on-uat’, ‘vms’: [‘NED-TST601-X’], ‘type’: ‘vm’}, {‘group_name’: VM2-on-qa’, ‘vms’: [‘deep-test’, ‘NED-DEV601-X’], ‘type’: ‘vm’}
}

If vm_name = ‘NED-DEV601-X’ I have two match group name but my logic stops after the first match how can I search for all the groups in the register variable.

  • name: set fact specific VM group
    ansible.builtin.set_fact:
    vm_drs_groups: “{{ group_info.drs_group_info[vcenter_env.cluster] | selectattr(‘type’, ‘==’, “vm” ) | list }}”

  • name: “Set facts to specific VM groups for matching vm name”
    ansible.builtin.set_fact:
    match_vm_group: “{{ item.group_name }}”
    when: item | regex_search(vm_name)
    loop: “{{ vm_drs_groups }}”

I appreciate any help.

Thanks and Regards,
Deepak Kumar

Deepak,

Here’s a playbook that demonstrates one way to do it. I tried lots of incorrect Jinja2 expressions that failed to achieve the final output before going back to iterative loops. It feels like the subelements lookup should be part of the solution, and that is shown below. However, it’s actually more straightforward to do old-school looping over your original data to find the matching group names, and that’s what the second set_fact task does.

If there is a way to express this with Jinja2 filters, it’s unintuitive enough to me that I wouldn’t want to maintain it anyway. I can read the loops and make some sense out of it, so that’s the way I’d go.

[utoddl@tango ansible]$ **cat test-subelements3.yml** 
---
- name: Demo set_fact over subelements
  hosts: localhost
  gather_facts: false
  vars:
    **vm_name**: NED-DEV601-X
    **vm_drs_groups**: 
      - group_name: VM2-on-dev
        vms:
          - deep-test
          - NED-DEV601-X
        type: vm
      - group_name: VM2-on-uat
        vms:
          - NED-TST601-X
        type: vm
      - group_name: VM2-on-qa
        vms:
          - deep-test
          - NED-DEV601-X
        type: vm
  tasks:
    - name: Show the list generated by the subelements lookup
      ansible.builtin.debug:
        msg: "{{ lookup('subelements', **vm_drs_groups**, 'vms') }}"

    - name: Iterate over subelements to gather the group_names for {{ **vm_name** }}
      ansible.builtin.set_fact:
        match_vm_group: |
          {% set matching_groups = [] %}
          {% for vm_by_group_name in lookup('subelements', **vm_drs_groups**, 'vms') %}
          {%   if vm_by_group_name[1] == **vm_name** %}
          {%      set _ = matching_groups.append(vm_by_group_name[0].group_name) %}
          {%   endif %}
          {% endfor %}{{ matching_groups }}

    - name: Same thing without subelements
      ansible.builtin.set_fact:
        match_vm_group: |
          {% set matching_groups = [] %}
          {% for vm_drs_group in **vm_drs_groups** %}
          {%   if **vm_name** in vm_drs_group.vms %}
          {%      set _ = matching_groups.append(vm_drs_group.group_name) %}
          {%   endif %}
          {% endfor %}{{ matching_groups }}

[utoddl@tango ansible]$ **ANSIBLE_STDOUT_CALLBACK=yaml ansible-playbook test-subelements3.yml -v**
Using /etc/ansible/ansible.cfg as config file

PLAY [Demo set_fact over subelements] ***********************************************************

TASK [Show the list generated by the subelements lookup] ****************************************
ok: [localhost] => 
  msg:
  - - group_name: VM2-on-dev
      type: vm
    - deep-test
  - - group_name: VM2-on-dev
      type: vm
    - NED-DEV601-X
  - - group_name: VM2-on-uat
      type: vm
    - NED-TST601-X
  - - group_name: VM2-on-qa
      type: vm
    - deep-test
  - - group_name: VM2-on-qa
      type: vm
    - NED-DEV601-X

TASK [Iterate over subelements to gather the group_names for NED-DEV601-X] **********************
ok: [localhost] => changed=false 
  ansible_facts:
    match_vm_group:
    - VM2-on-dev
    - VM2-on-qa

TASK [Same thing without subelements] ***********************************************************
ok: [localhost] => changed=false 
  ansible_facts:
    match_vm_group:
    - VM2-on-dev
    - VM2-on-qa

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

Cheers,

I appreciate the immediate help . But my client don’t want use python in the ansible just wanted to know can we use ansible loop and condition to determine the match group_names?

Thanks
Deepak Kumar

This is not “python in ansible”. This is jinja2 templating which is a fully supported feature of ansible.

Walter

Todd,

Thank you for trying out the option. But I am trying a different approach instead of matching groups . I have listed all the vm groups to a variable, using a loop and when condition to skip the vm_group which it should not check to remove the drs community.vmware.vmware_drs_group_manager module.
when:

  • vm_match
  • not vm_group_name

I am all set with the playbook . Thank you for your valuable feedback.

Cheers
Deepak Kumar