首页 > 解决方案 > 在 Ansible 的 netbox_device 中循环多个列表

问题描述

我的目标是使用 ansible 在 NetBox 中创建新设备。因此,出于这个原因,我使用 netbox_device。我从 json 文件中获取所需的信息(设备名称、类型、序列号等),如下所示:

{
"results":{
       "infos": [
            {
                "device_type": "type1",
                "device_name": "name1",
                "serial_number": "num1"
            },
            {
                "device_type": "type2",
                "device_name": "name2",
                "serial_number": "num2"
            }

        ]

} 

}

所以,我正在做的是我有这个简单的任务来创建 1 个新设备:

- name: Create new devices within Netbox 
  netbox_device:
    netbox_url: http://url.goes.here
    netbox_token: 7575747448..66353
    data:
      name: name1
      device_type: type1
      device_role: Core Switch
      serial_number: "num1"
      site: Main
    state: present

如果有人想创建一个特定的新设备,这很简单,但我想在循环一些包含所需信息的列表时动态创建新设备。

特别是,我从 json 文件创建了一个包含所有设备名称的列表

ok: [localhost] => {
"ansible_facts": {
    "dev_names": [
        "nameisone", 
        "nameistwo"
    ]
}, 
"changed": false

}

然后我使用设备类型从 json 文件创建另一个列表

ok: [localhost] => {
"ansible_facts": {
    "dev_types": [
        "type_one", 
        "type_two"
    ]
}, 
"changed": false

}

所以现在我有一个关于上述列表的 1 个循环的任务:

 - name: Create new devices within Netbox looping the lists with the required info
  netbox_device:
    netbox_url: http://url.goes.here
    netbox_token: 754544444444404509504959433333333
    data:
      name: "{{ item }}"
      device_type: "{{ item }}"
      device_role: "Core Switch"
      site: Site 
      #serial_number: "number"
    state: present
  loop:
    - "{{ dev_names }}"
    - "{{ dev_types }} "

这仅适用于一个列表,这意味着如果我注释掉两个列表之一,我不会收到任何错误。

当我使用我的两个列表运行此任务时遇到的错误是:

 File "/tmp/poioanni/ansible_netbox_device_payload_5W1o8U/ansible_netbox_device_payload.zip/ansible/module_utils/net_tools/netbox/netbox_utils.py", line 352, in normalize_data

AttributeError: 'list' 对象没有属性 'lower'

失败:[localhost] (item=[u'nameisone', u'nameistwo']) => { "ansible_loop_var": "item", "changed": false, "item": ["nameisone", "nameistwo" ] ,

有任何想法吗 ?

标签: listloopsansible

解决方案


如果你确定你的列表是同步的,你可以使用zipfilter,如下面的test.ymlMVCE playbook 所示。

---
- name: Zip demo
  hosts: localhost
  gather_facts: false

  vars:
    "dev_names": [
      "nameisone",
      "nameistwo"
    ]

    "dev_types": [
      "type_one",
      "type_two"
    ]

  tasks:
    - name: demonstrate how to use the zip filter with a loop
      debug:
        msg: "Element from first list: {{ item.0 }}. Element from second list: {{ item.1 }}"
      loop: "{{ dev_names | zip(dev_types) | list }}"

这使:

$ ansible-playbook test.yml 

PLAY [Zip demo] ************************************************************************************************************************************************************************************************************************

TASK [demonstrate how to use the zip filter with a loop] *******************************************************************************************************************************************************************************
ok: [localhost] => (item=['nameisone', 'type_one']) => {
    "msg": "Element from first list: nameisone. Element from second list: type_one"
}
ok: [localhost] => (item=['nameistwo', 'type_two']) => {
    "msg": "Element from first list: nameistwo. Element from second list: type_two"
}

PLAY RECAP *****************************************************************************************************************************************************************************************************************************
localhost                  : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

推荐阅读