
ansible [core 2.13.3] では、var.yml ファイルは次のようになります。
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
目的は、VLAN 内の各要素 (サーバー、クライアント、プリンターなど) と各モード (タグ付き、タグなし、禁止など) ごとに 1 つのタスクを起動することです。
VLAN の反復処理は成功しましたが、VLAN とモードでは成功しませんでした。ネストされたループを成功させる良い方法が見つかりません。subelement、with_subelements、loop_nested などすべてを試しましたが、成功しませんでした。
- 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
Ansible でネストされたループを作成するにはどうすればよいでしょうか?
- name: Debug2
debug:
msg: "Name: {{ item.key }} - mode: {{ item.value.mode }}"
loop: "{{ lookup('dict', vlans) }}"
when: "'mode' in dict(item.value)"
tags:
- debug
デバッグ2の戻り値:
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": "名前: 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": "名前: クライアント - モード: {'tagged': '1/1,1/3'}" } スキップ中: [sw39stack01.group.corp] => (item={'key': 'プリンター', 'value': {'vlan_id': 30}}) => { "ansible_loop_var": "item", "item": { "key": "プリンター", "value": { "vlan_id": 30 } } }
よろしくお願いします、
答え1
辞書を変換するモードリストへ
modes: |
{% for k,v in vlans.items() %}
{{ k }}:
mode: {{ v.mode|d({})|dict2items }}
{% endfor %}
vlans2: "{{ vlans|combine(modes|from_yaml, recursive=true) }}"
与える
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
辞書を変換するVLAN2リストに追加して繰り返し処理するサブ要素 値.モード
- debug:
msg: "{{ item.0.key }} {{ item.1.key }} {{ item.1.value }}"
loop: "{{ vlans2|dict2items|subelements('value.mode') }}"
与える(要約)
msg: Servers tagged 1/1,1/2
msg: Servers untagged 1/3
msg: Clients tagged 1/1,1/3
完全なプレイブックの例
- 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') }}"
答え2
インベントリファイルは次のように編集されます。
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
そしてクエリが使用されます:
- name: Debug1
ansible.builtin.debug: var=item
loop: "{{ query('subelements', vlans, 'mode', {'skip_missing': True}) }}"
tags:
- debug
出力は期待どおりに動作します:
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"
}
]
}