Ansible : 루프 내부 루프

Ansible : 루프 내부 루프

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의 각 요소(서버, 클라이언트, 프린터...)와 각 모드(태그됨, 태그 없음, 금지...)에 대해 하나의 작업을 시작하는 것입니다.

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': '서버', 'value': {'vlan_id': 10, 'ip': '192.168.22.20', 'mask': '255.255 .255.0', '모드': {'태그': '1/1,1/2', '태그 없음': '1/3'}}}) => { "msg": "이름: 서버 - 모드: {'태그': '1/1,1/2', '태그 없음': '1/3'}" } ok: [sw39stack01.group.corp] => (item={'key': '클라이언트', '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"
        }
    ]
}

관련 정보