如何使用 Jinja2 从 var 文件中获取一个值到 Ansible 中的 JSON 文件中

How do I fetch a value from a var file using Jinja2 into an JSON file in Ansible

我想 fetch/replace 输入 YAML 中的值 — abc.yml — 来自 var 文件 — var.yml — 使用 Jinja2 根据输入文件和 var 文件之间的匹配 id 值(此处 id 值为 123)并创建一个 JSON 作为预期结果。

Jinja2 代码:

[
    {% for list in abc['fwrules'] %}
        {
            {% for item in abc['details'] %}
            "country": "{{item.Country}}",
            "destCidr": "{{list.destCidr}}"
            {% endfor %}
        }{% if not loop.last %},
        {% endif %}
    {% endfor %}
]

输入 yml — abc.yml:

---
details: 
         -   Country: "abc" 
             id: 123 
fwrules:
         -   destCidr: "{{ DNS }}, 10.20.20.20/24"
             srcCidr: "10.30.20.20/24"

         -   destCidr: "10.30.30.30/24"
             srcCidr: "{{ NTP }}, 10.40.20.20/24"

Var 文件 — var.yml:

---
names:
    -   id: "123"
        DNS: "10.10.10.10"
        NTP: "10.100.100.100"

    -   id: "456"
        DNS: "20.20.20.20"
        NTP: "10.200.200.200"

预期JSON结果:

[
    {
        "country": "abc",
        "destCidr": "10.10.10.10, 10.20.20.20/24",
        "srcCidr": "10.30.20.20/24"
    },
    {
        "country": "abc",
        "destCidr": "10.30.30.30/24"
        "srcCidr": "10.100.100.100, 10.40.20.20/24"
    }
]

您可以仅使用过滤器来实现此目的。

给定两个 yaml — abc.ymlvar.yml — 您使用这两个任务提供:

- include_vars:
    file: "{{ item }}.yml"
  loop:
    - var
    - abc

- set_fact:
    output: >-
      {{
        output | default([]) 
          + [{
            'country': details.0.Country,
            'destCidr': item.destCidr,
            'srcCidr': item.srcCidr
          }] 
      }} 
  loop: "{{ fwrules }}"
  vars: 
    _matched_id: >-
      {{ 
        names 
        | selectattr('id', 'eq', details.0.id | string) 
        | first 
      }}
    DNS: "{{ _matched_id.DNS }}"
    NTP: "{{ _matched_id.NTP }}"

将创建一个变量 output 具有您想要的输出。

TASK [debug] ********************************************************************
ok: [localhost] => {
    "output": [
        {
            "country": "abc",
            "destCidr": "10.10.10.10, 10.20.20.20/24",
            "srcCidr": "10.30.20.20/24"
        },
        {
            "country": "abc",
            "destCidr": "10.30.30.30/24",
            "srcCidr": "10.100.100.100, 10.40.20.20/24"
        }
    ]
}

然后,如果需要,您可以将该输出转储到 JSON 文件中:

- copy:
    content: "{{ output | to_nice_json }}"
    dest: output.json