
No ansible [core 2.13.3] meu arquivo var.yml é assim:
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
O objetivo é lançar uma tarefa para cada elemento das vlans (Servidores, Clientes, Impressoras...) e para cada modo (marcado, não marcado, proibido...).
Eu iterei com sucesso em vlans, mas não em vlans e modo. Não consigo encontrar o bom caminho para o sucesso do loop aninhado. Tente tudo como subelemento, with_subelements, loop_nested sem sucesso.
- 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
Como posso fazer um loop aninhado no Ansible?
- name: Debug2
debug:
msg: "Name: {{ item.key }} - mode: {{ item.value.mode }}"
loop: "{{ lookup('dict', vlans) }}"
when: "'mode' in dict(item.value)"
tags:
- debug
Retorno da depuração 2:
ok: [sw39stack01.group.corp] => (item={'key': 'Servidores', 'valor': {'vlan_id': 10, 'ip': '192.168.22.20', 'máscara': '255.255 .255.0', 'mode': {'tagged': '1/1,1/2', 'untagged': '1/3'}}}) => { "msg": "Nome: Servidores - modo: {'tagged': '1/1,1/2', 'untagged': '1/3'}" } ok: [sw39stack01.group.corp] => (item={'key': 'Clientes', 'value': {'vlan_id': 20, 'mode': {'tagged': '1/1,1/3'}}}) => { "msg": "Nome: Clientes - modo: {'tagged ': '1/1,1/3'}" } pulando: [sw39stack01.group.corp] => (item={'chave': 'Impressoras', 'valor': {'vlan_id': 30}}) => { "ansible_loop_var": "item", "item": { "key": "Impressoras", "valor": { "vlan_id": 30 } } }
Atenciosamente,
Responder1
Converta os dicionáriosmodopara listas
modes: |
{% for k,v in vlans.items() %}
{{ k }}:
mode: {{ v.mode|d({})|dict2items }}
{% endfor %}
vlans2: "{{ vlans|combine(modes|from_yaml, recursive=true) }}"
dá
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
Converta o dicionáriovlans2para uma lista e iterar comsubelementos valor.modo
- debug:
msg: "{{ item.0.key }} {{ item.1.key }} {{ item.1.value }}"
loop: "{{ vlans2|dict2items|subelements('value.mode') }}"
dá (resumido)
msg: Servers tagged 1/1,1/2
msg: Servers untagged 1/3
msg: Clients tagged 1/1,1/3
Exemplo de um manual completo
- 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') }}"
Responder2
O arquivo de inventário é editado assim:
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
E a consulta é usada:
- name: Debug1
ansible.builtin.debug: var=item
loop: "{{ query('subelements', vlans, 'mode', {'skip_missing': True}) }}"
tags:
- debug
A saída funciona conforme esperado:
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"
}
]
}