Ansible 中有没有一种方法可以将基于 k:v 查找的字典值替换为另一个字典?

Is there a way in Ansible to replace a dictionary value based on k:v lookup to another dictionary?

我有 k:v 主机名字典:我想在从另一个字典查找时使用它来替换与第一个字典中的键匹配的条目,并将其替换为第二个字典中的相应值;

第一名:

"nb_console_ip": {
    "office-con01": "10.20.30.100",

第二名:

"nb_console_port": [
        {
            "console": "office-con01", 
            "hostname": "office-core01", 
            "port": "con1"
        }, 
        {
            "console": "office-con01", 
            "hostname": "office-core02", 
            "port": "con2"
        }, 
        {
            "console": "office-con01", 
            "hostname": "office-fw01", 
            "port": "con5"
        }, 
        {
            "console": "office-con01", 
            "hostname": "office-fw02", 
            "port": "con6"
        }, 
        {
            "console": "office-con01", 
            "hostname": "office-vpn01", 
            "port": "con3"
        }, 
        {
            "console": "office-con01", 
            "hostname": "office-vpn02", 
            "port": "con4"
        }
    ]

本质上,我正在尝试 set_fact 查找第二个字典,并将 office-con01 替换为 10.20.30.100,但要查找包含 30 多个主机的列表。 原因是我有一个 jinja 模板,它将使用 console_ip、主机名和端口的 3 个值。 我在想也许里面有更适合查找、查找、替换等的过滤器。 两组数据都是来自 API 调用的 json_query 在 return 上的结果。

可以在每次迭代中循环 include_tasks 并替换 k:v。例如,创建一个文件,其中包含替换从外部循环提交的 outer_item.key: outer_item.value 的任务

shell> cat test-task.yml
- set_fact:
    nb_console_port: "{{ nb_console_port|difference([item]) +
                         [dict(my_keys|zip(my_values2))] }}"
  vars:
    my_keys: "{{ item.keys()|list }}"
    my_values: "{{ item.values()|list }}"
    my_values2: "{{ my_values|
                   map('regex_replace', outer_item.key, outer_item.value)|
                   list }}"
  loop: "{{ nb_console_port }}"

然后下面的剧本就可以完成这项工作。变量 nb_console_port 存储在文件 test-data.yml

shell> cat test.yml
- hosts: localhost

  vars:

    nb_console_ip:
      office-con01: "10.20.30.100"
      office-con02: "10.20.30.101"
      office-con03: "10.20.30.102"

  tasks:

    - include_vars: test-data.yml

    - include_tasks: test-task.yml
      loop: "{{ nb_console_ip|dict2items }}"
      loop_control:
        loop_var: outer_item

    - debug:
        var: nb_console_port