如何在 Ansible 中遍历嵌套列表?

Com*_*sar 0 ansible

我有一个设备列表,每个设备都有必须在设备上创建的不同属性列表,一次一个。有没有办法构建一组嵌套的循环来做到这一点?with_nested 构造将每个属性应用于每个设备;每次调用我只需要每个设备一个属性。

这个剧本展示了我的尝试(Ansible 2.7.1,Python 2.7.1):

- name:                                 Test nested list traversal
  hosts:                                localhost
  connection:                           local
  vars:
    Stuff:
      - Name:         DeviceA
        Info:         AInfo
        Values:
        -             ValueA1
        -             ValueA2
      - Name:         DeviceB
        Info:         BInfo
        Values:
        -             ValueB1
        -             ValueB2
        -             ValueB3

  tasks:
  - name: Loop test
    debug:  msg="{{ item.Name }},{{ item.Info }}, {{ item.Values }}"
    with_items: 
      - "{{ Stuff }}"
Run Code Online (Sandbox Code Playgroud)
What I get: (One call per device, containing all attributes at once)

ok: [localhost] => (item={u'Info': u'AInfo', u'Values': [u'ValueA1', u'ValueA2'], u'Name': u'DeviceA'}) =>
  msg: DeviceA,AInfo, [u'ValueA1', u'ValueA2']
ok: [localhost] => (item={u'Info': u'BInfo', u'Values': [u'ValueB1', u'ValueB2', u'ValueB3'], u'Name': u'DeviceB'}) =>
  msg: DeviceB,BInfo, [u'ValueB1', u'ValueB2', u'ValueB3']

Run Code Online (Sandbox Code Playgroud)
What I want (each msg represents a separate operation to be performed 
on the device with just that one attribute)

msg: A, AInfo, ValueA1
msg: A, AInfo, ValueA2
msg: B, BInfo, ValueB1
msg: B, BInfo, ValueB2
msg: B, BInfo, ValueB3
Run Code Online (Sandbox Code Playgroud)

lar*_*sks 5

您可以使用subelements过滤器获得所需内容:

---
- hosts: localhost
  gather_facts: false
  vars:
    Stuff:
      - Name: DeviceA
        Info: AInfo
        Values:
          - ValueA1
          - ValueA2
      - Name: DeviceB
        Info: BInfo
        Values:
          - ValueB1
          - ValueB2
          - ValueB3
  tasks:
    - debug:
        msg: "{{ item.0.Name }}, {{ item.0.Info }}, {{ item.1 }}"
      loop: "{{ Stuff|subelements('Values') }}"
      loop_control:
        label: "{{ item.0.Name }}"
Run Code Online (Sandbox Code Playgroud)

运行上面的剧本可以让你:

PLAY [localhost] ******************************************************************************************************************************************************************************

TASK [debug] **********************************************************************************************************************************************************************************
ok: [localhost] => (item=DeviceA) => {
    "msg": "DeviceA, AInfo, ValueA1"
}
ok: [localhost] => (item=DeviceA) => {
    "msg": "DeviceA, AInfo, ValueA2"
}
ok: [localhost] => (item=DeviceB) => {
    "msg": "DeviceB, BInfo, ValueB1"
}
ok: [localhost] => (item=DeviceB) => {
    "msg": "DeviceB, BInfo, ValueB2"
}
ok: [localhost] => (item=DeviceB) => {
    "msg": "DeviceB, BInfo, ValueB3"
}

PLAY RECAP ************************************************************************************************************************************************************************************
localhost                  : ok=1    changed=0    unreachable=0    failed=0   
Run Code Online (Sandbox Code Playgroud)