1

I would like to match a particular keyword(destCidr) from abc.yml and input.yml(subnetname) and fetch the pertaining id value from input.yml and create a new JSON. I am trying to get the expected result as mentioned below, but i dont know where i am doing wrong.

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([]) 
          }}

Expected Result

[
    {
        "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 "
    }
]
Vinny
  • 302
  • 2
  • 11

2 Answers2

2

Read the list from the file input.yml

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

gives

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

Create a dictionary from the list

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

gives

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

Create the required variables and include the list rules from the file abc.yml

    - set_fact:
        DNS: "{{ sn_id_dict.DNS }}"
        NET: "{{ sn_id_dict.NET }}"
        NTP: "{{ sn_id_dict.NTP }}"
    - include_vars: abc.yml

gives the expected result

  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'
Vladimir Botka
  • 58,131
  • 4
  • 32
  • 63
  • Thanks for the solution. But how can i handle the task successfully if any of the variable like DNS/NTP/NET is not available in the input.yml. So if my **destCidr = OBJ([]), 10.33.33.0/24**, how can i remove the empty part and make it like **destCidr = 10.33.33.0/24**. Let me know if you want me to post this as a separate question.Appreciate if you can give me a hint on that. – Vinny Feb 17 '22 at 08:19
  • 1
    In fact, your question is ``How do I remove 'OBJ([]), '?``. See [replace](https://docs.ansible.com/ansible/latest/collections/ansible/builtin/replace_module.html#ansible-builtin-replace-replace-all-instances-of-a-particular-string-in-a-file-using-a-back-referenced-regular-expression). And yes, if you have troubles open a new question. – Vladimir Botka Feb 17 '22 at 09:19
0

YAML supports anchors and aliases, but this feature does not support the arbitrary placement of placeholders and expressions anywhere in the YAML text. They only work with YAML nodes.

You will need to use a YAML extension library or process this .yml in some programming language to replace these placeholders.

You can find more details in this related question: Use placeholders in yaml.