1

On ansible [core 2.13.3] my var.yml file is like this :

vlans: Servers: vlan_id: 10 ip: 192.168.22.20 mask: 255.255.255.0 mode: tagged: 1/1,1/2 untagged: 1/3 Clients: vlan_id: 20 mode: tagged: 1/1,1/3 Printers: vlan_id: 30 

The objective is to launch one task for each elements in vlans (Servers, Clients, Printers...) and for each mode (tagged, untagged, forbid...).

I successful iterate on vlans but not in vlans and mode. I can't find the good way to success nested loop. Try everything like subelement, with_subelements, loop_nested without success.

 - name: Set member of vlan arubaoss_vlan: command: config_vlan_port config: "create" vlan_id: "{{ item.value.vlan_id }}" port_id: "{{ item.value.port | default('') }}" port_mode: "{{ item.value.mode | default('POM_UNTAGGED') | regex_replace('^tagged$', 'POM_TAGGED_STATIC') | regex_replace('^untagged$', 'POM_UNTAGGED') | regex_replace('^forbid$', 'POM_FORBIDDEN') }}" api_version: "{{ ansible_api_version }}" use_ssl: "{{ ansible_use_ssl }}" port: "{{ ansible_port }}" host: "{{ ansible_host }}" username: "{{ ansible_user }}" password: "{{ ansible_password }}" loop: "{{ lookup('dict', vlans) }}" when: "'port' in dict(item)" tags: - vlans - vlans_mode 

How I can make nested loop in Ansible ?

 - name: Debug2 debug: msg: "Name: {{ item.key }} - mode: {{ item.value.mode }}" loop: "{{ lookup('dict', vlans) }}" when: "'mode' in dict(item.value)" tags: - debug 

Debug 2 return :

ok: [sw39stack01.group.corp] => (item={'key': 'Servers', 'value': {'vlan_id': 10, 'ip': '192.168.22.20', 'mask': '255.255.255.0', 'mode': {'tagged': '1/1,1/2', 'untagged': '1/3'}}}) => { "msg": "Name: Servers - mode: {'tagged': '1/1,1/2', 'untagged': '1/3'}" } ok: [sw39stack01.group.corp] => (item={'key': 'Clients', 'value': {'vlan_id': 20, 'mode': {'tagged': '1/1,1/3'}}}) => { "msg": "Name: Clients - mode: {'tagged': '1/1,1/3'}" } skipping: [sw39stack01.group.corp] => (item={'key': 'Printers', 'value': {'vlan_id': 30}}) => { "ansible_loop_var": "item", "item": { "key": "Printers", "value": { "vlan_id": 30 } } }

Best regards,

2 Answers 2

2

Convert the dictionaries mode to lists

 modes: | {% for k,v in vlans.items() %} {{ k }}: mode: {{ v.mode|d({})|dict2items }} {% endfor %} vlans2: "{{ vlans|combine(modes|from_yaml, recursive=true) }}" 

gives

 vlans2: Clients: mode: - key: tagged value: 1/1,1/3 vlan_id: 20 Printers: mode: [] vlan_id: 30 Servers: ip: 192.168.22.20 mask: 255.255.255.0 mode: - key: tagged value: 1/1,1/2 - key: untagged value: 1/3 vlan_id: 10 

Convert the dictionary vlans2 to a list and iterate with subelements value.mode

 - debug: msg: "{{ item.0.key }} {{ item.1.key }} {{ item.1.value }}" loop: "{{ vlans2|dict2items|subelements('value.mode') }}" 

gives (abridged)

 msg: Servers tagged 1/1,1/2 msg: Servers untagged 1/3 msg: Clients tagged 1/1,1/3 

Example of a complete playbook

- hosts: localhost vars: vlans: Servers: vlan_id: 10 ip: 192.168.22.20 mask: 255.255.255.0 mode: tagged: 1/1,1/2 untagged: 1/3 Clients: vlan_id: 20 mode: tagged: 1/1,1/3 Printers: vlan_id: 30 modes: | {% for k,v in vlans.items() %} {{ k }}: mode: {{ v.mode|d({})|dict2items }} {% endfor %} vlans2: "{{ vlans|combine(modes|from_yaml, recursive=true) }}" tasks: - debug: var: modes|from_yaml - debug: var: vlans2 - debug: msg: "{{ item.0.key }} {{ item.1.key }} {{ item.1.value }}" loop: "{{ vlans2|dict2items|subelements('value.mode') }}" 
0

Inventory file are edited like this:

vlans: - name: Servers vlan_id: 10 ip: 192.168.22.20 mask: 255.255.255.0 mode: - tagged: 1/1,1/2 - untagged: 1/3 - name: Clients vlan_id: 20 mode: - tagged: 1/1,1/3 - name: Printers vlan_id: 30 

And query is used:

 - name: Debug1 ansible.builtin.debug: var=item loop: "{{ query('subelements', vlans, 'mode', {'skip_missing': True}) }}" tags: - debug 

Output work as expected:

ok: [sw] => (item=[{'name': 'Servers', 'vlan_id': 10, 'ip': '192.168.22.20', 'mask': '255.255.255.0'}, {'tagged': '1/1,1/2'}]) => { "ansible_loop_var": "item", "item": [ { "ip": "192.168.22.20", "mask": "255.255.255.0", "name": "Servers", "vlan_id": 10 }, { "tagged": "1/1,1/2" } ] } ok: [sw] => (item=[{'name': 'Servers', 'vlan_id': 10, 'ip': '192.168.22.20', 'mask': '255.255.255.0'}, {'untagged': '1/3'}]) => { "ansible_loop_var": "item", "item": [ { "ip": "192.168.22.20", "mask": "255.255.255.0", "name": "Servers", "vlan_id": 10 }, { "untagged": "1/3" } ] } 

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.