首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用ansible对多个字典列表进行循环

使用ansible对多个字典列表进行循环
EN

Stack Overflow用户
提问于 2021-07-16 15:50:30
回答 2查看 1.4K关注 0票数 1

我正在尝试使用ansible循环下面的可变结构,我想要的是在每个子网上循环。对于子网-1,我想得到网络,cidr,vlan,类似地循环其他密钥子网-2,子网-3。

flavor.json

代码语言:javascript
复制
{
  "subnets-1": [
    {
      "network": "test1",
      "cidr": 21,
      "vlan": 123
    },
    {
      "network": "test2",
      "cidr": 22,
      "vlan": 234
    }
  ],
  "subnets-2": [
    {
      "network": "test3",
      "cidr": 43,
      "vlan": 879
    },
    {
      "network": "test4",
      "cidr": 21,
      "vlan": "12fsd"
    },
    {
      "network": "test5",
      "cidr": "22sdf",
      "vlan": "234sdfd"
    }
  ],
  "subnets-3": [
    {
      "network": "test44",
      "cidr": "fg",
      "vlan": "dsfsd"
    }
  ]
}

我已经尝试过以下使用with_dict的方法

playbook.yml (Anble2.9.7)

代码语言:javascript
复制
---
- hosts: local
  gather_facts: no  
  tasks:
  - name: lookup yaml
    set_fact:
      flavors: "{{ lookup('file','flavor.json') | from_json }}"
  - name: json out
    debug:
      msg: "{{ flavors }}"
  - name: check keys
    shell: |
      echo "s_name = {{ item.network }}"
      echo "s_cidr = {{ item.cidr }}"
      echo "s_vlan = {{ item.vlan }}"
    with_dict:
      "{{ flavors }}"

这是我在执行剧本时遇到的错误。

错误:

代码语言:javascript
复制
fatal: [192.168.110.128]: FAILED! => {
    "msg": "The task includes an option with an undefined variable. The error was: 'dict object' has no attribute 'network'\n\nThe error appears to be in '/root/fla.yml': line 19, column 5, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n\n  - name: check keys\n    ^ here\n"
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-07-16 17:56:16

使用https://docs.ansible.com/ansible/latest/collections/ansible/builtin/include_vars_module.html#ansible-builtin-include-vars-load-variables-from-files-dynamically-within-a-task。与查找和from_yaml相比,它更简单。

代码语言:javascript
复制
    - include_vars:
        file: flavor.json
        name: flavors

给出

代码语言:javascript
复制
  flavors:
    subnets-1:
    - {cidr: 21, network: test1, vlan: 123}
    - {cidr: 22, network: test2, vlan: 234}
    subnets-2:
    - {cidr: 43, network: test3, vlan: 879}
    - {cidr: 21, network: test4, vlan: 12fsd}
    - {cidr: 22sdf, network: test5, vlan: 234sdfd}
    subnets-3:
    - {cidr: fg, network: test44, vlan: dsfsd}

然后将字典转换为列表和迭代https://docs.ansible.com/ansible/latest/collections/ansible/builtin/subelements_lookup.html#ansible-builtin-subelements-traverse-nested-key-from-a-list-of-dictionaries

代码语言:javascript
复制
    - debug:
        msg: "{{ item.0.key }}
              {{ item.1.network }}
              {{ item.1.cidr }}
              {{ item.1.vlan }}"
      with_subelements:
        - "{{ flavors|dict2items }}"
        - value

给出

代码语言:javascript
复制
  msg: subnets-1 test1 21 123
  msg: subnets-1 test2 22 234
  msg: subnets-2 test3 43 879
  msg: subnets-2 test4 21 12fsd
  msg: subnets-2 test5 22sdf 234sdfd
  msg: subnets-3 test44 fg dsfsd
票数 2
EN

Stack Overflow用户

发布于 2021-07-16 17:17:25

Ansible不能很好地执行嵌套循环。在这种情况下,您知道最多有三个数组元素。所以你可以这样循环:

代码语言:javascript
复制
- name: loop over flavors
  debug:
    msg: "{{ flavors[item.0][item.1] }}"
  with_nested:
    - "{{ flavors }}"
    - [ 0, 1, 2 ]
  when: flavors[item.0][item.1] is defined

导致了这样的结果:

代码语言:javascript
复制
TASK [loop over flavors] *********************************************************************************************
ok: [localhost] => (item=['subnets-1', 0]) => {
    "msg": {
        "cidr": 21,
        "network": "test1",
        "vlan": 123
    }
}
ok: [localhost] => (item=['subnets-1', 1]) => {
    "msg": {
        "cidr": 22,
        "network": "test2",
        "vlan": 234
    }
}
skipping: [localhost] => (item=['subnets-1', 2]) 
ok: [localhost] => (item=['subnets-2', 0]) => {
    "msg": {
        "cidr": 43,
        "network": "test3",
        "vlan": 879
    }
}
ok: [localhost] => (item=['subnets-2', 1]) => {
    "msg": {
        "cidr": 21,
        "network": "test4",
        "vlan": "12fsd"
    }
}
ok: [localhost] => (item=['subnets-2', 2]) => {
    "msg": {
        "cidr": "22sdf",
        "network": "test5",
        "vlan": "234sdfd"
    }
}
ok: [localhost] => (item=['subnets-3', 0]) => {
    "msg": {
        "cidr": "fg",
        "network": "test44",
        "vlan": "dsfsd"
    }
}
skipping: [localhost] => (item=['subnets-3', 1]) 
skipping: [localhost] => (item=['subnets-3', 2]) 
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68411894

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档