从 yaml 文件中获取一个变量值,然后在 Ansible 中以不同的格式替换该值

Fetch a variable value from a yaml file and then replace the value in a different format in Ansible

我想匹配来自 abc.yml 和 input.yml(子网名) 的特定关键字 (destCidr) 并从 input.yml 获取相关的 id 值并创建一个新的 JSON.我正在尝试获得如下所述的预期结果,但我不知道我哪里做错了。

abc.yml

rules:
         -    rule number: "1" 
              destCidr: "OBJ({{DNS}}) , 10.22.22.0/24"
                  

         -    rule number: "2"
              destCidr: "OBJ({{ NTP }}) , 10.33.33.0/24"
              

         -    rule number: "3"
              destCidr: "OBJ({{ NET }}), GRP({{ NTP }}) , 10.33.33.0/24"

input.yml

[
    {
        
        "id": "11155588779966",
        "subnetname": "DNS"
        
    },
    {  
        "id": "99996688778855",
        "subnetname": "NTP"
    },
    {
        "id": "123456789101112",
        "subnetname": "NET"
        
    }
]

playbook.yml

- include_vars:
        file: "{{ item }}.yml"
      loop:
        - abc
    - name:
      set_fact:
        rule: >-
            {{
              rule | default([])          
               + [ item | combine({'destCidr': dest_po_map[0]})]
            }}
      loop: "{{ rules | list}}"
      vars:
        dest_po_map: >-
          {{ 
            input 
            | selectattr('subnetname', 'in' , item.destCidr | string)
            | map(attribute='id')
            | default([]) 
          }}

预期结果

[
    {
        "rule number": "1",
        "destCidr": "OBJ(11155588779966), 10.22.22.0/24 "
    },
    {
        "rule number": "2",
        "destCidr": "OBJ(99996688778855), 10.33.33.0/24"
    },
    {    
        "rule number": "3",
        "destCidr": "OBJ(123456789101112), GRP(99996688778855), 10.33.33.0/24 "
    }
]

YAML 支持锚点和别名,但此功能不支持在 YAML 文本中的任意位置任意放置占位符和表达式。它们仅适用于 YAML 节点。

您将需要使用 YAML 扩展库或以某种编程语言处理此 .yml 以替换这些占位符。

您可以在这个相关问题中找到更多详细信息:

从文件中读取列表input.yml

    - set_fact:
        sn_id_list: "{{ lookup('file', 'input.yml') }}"

给予

  sn_id_list:
  - id: '11155588779966'
    subnetname: DNS
  - id: '99996688778855'
    subnetname: NTP
  - id: '123456789101112'
    subnetname: NET

根据列表创建字典

    - set_fact:
        sn_id_dict: "{{ sn_id_list|items2dict(key_name='subnetname',
                                              value_name='id') }}"

给予

  sn_id_dict:
    DNS: '11155588779966'
    NET: '123456789101112'
    NTP: '99996688778855'

创建所需的变量并包含文件 abc.yml

中的列表 rules
    - set_fact:
        DNS: "{{ sn_id_dict.DNS }}"
        NET: "{{ sn_id_dict.NET }}"
        NTP: "{{ sn_id_dict.NTP }}"
    - include_vars: abc.yml

给出了预期的结果

  rules:
  - destCidr: OBJ(11155588779966) , 10.22.22.0/24
    rule number: '1'
  - destCidr: OBJ(99996688778855) , 10.33.33.0/24
    rule number: '2'
  - destCidr: OBJ(123456789101112), GRP(99996688778855) , 10.33.33.0/24
    rule number: '3'