首页 > 解决方案 > Ansible 循环和更新字典

问题描述

我正在尝试使用 Ansible 循环遍历嵌套的字典并添加一个新的键:值。我可以使用 combine 将值添加到顶级字典,但不确定如何更新值字典。我看到可以使用循环来遍历 dict 但如何同时进行更新?

我的字典

{'host-a': {'os': 'Linux', 'port': '22', 'status': 'Running'},
 'host-b': {'os': 'Linux', 'port': '22', 'status': 'Running'},
 'host-c': {'os': 'Linux', 'port': '22', 'status': 'Running'}}

我能够附加到顶级字典,但不知道如何循环和另一个键:值到嵌套字典列表。

tasks:
 - name: Iterate and update dict
   set_fact:
     my_dict: '{{my_dict|combine({"location": "building-a"})}}'
 - debug: var=my_dict

更新后所需的字典:

{'host-a': {'os': 'Linux', 'port': '22', 'status': 'Running', 'location': 'building-a'},
 'host-b': {'os': 'Linux', 'port': '22', 'status': 'Running', 'location': 'building-a'},
 'host-c': {'os': 'Linux', 'port': '22', 'status': 'Running', 'location': 'building-a'}}

标签: pythonloopsdictionaryansibleansible-2.x

解决方案


您需要使用过滤器的recursive参数combine,如下所示:

- hosts: localhost
  gather_facts: false
  vars:
    my_dict:
      host-a: {'os': 'Linux', 'port': '22', 'status': 'Running'}
      host-b: {'os': 'Linux', 'port': '22', 'status': 'Running'}
      host-c: {'os': 'Linux', 'port': '22', 'status': 'Running'}

  tasks:
    - name: update dict
      set_fact:
        my_dict: "{{ my_dict|combine({item: {'location': 'building-a'}}, recursive=true) }}"
      loop: "{{ my_dict|list }}"

    - debug:
        var: my_dict

上面的剧本将输出:


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

TASK [update dict] ***********************************************************************************************************************************************************
ok: [localhost] => (item=host-a)
ok: [localhost] => (item=host-b)
ok: [localhost] => (item=host-c)

TASK [debug] *****************************************************************************************************************************************************************
ok: [localhost] => {
    "my_dict": {
        "host-a": {
            "location": "building-a",
            "os": "Linux",
            "port": "22",
            "status": "Running"
        },
        "host-b": {
            "location": "building-a",
            "os": "Linux",
            "port": "22",
            "status": "Running"
        },
        "host-c": {
            "location": "building-a",
            "os": "Linux",
            "port": "22",
            "status": "Running"
        }
    }
}

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

推荐阅读