Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Problems with Jinja2 and ansible making a sub dict

I need to read a csv file with diferent IPs and make a dictionary with a jinja2 filter for modificate the IP depending the IPNumber value. The yml file is like:

- read_csv:
    path: vms.csv
    key: Number
    fieldnames: Name,IP1,IP2,IP3,IP4,IPNumber 
    delimiter: ';'
  register: vms

- name: vms to dict
  debug:
    msg:
      - {{'Name':{{ item.value.Name }},
          {% if item.value.IPNumber == "1" %}
          'IP':{{ item.value.IP1 }},
          {% endif %}
          {% if item.value.IPNumber ==  "2"%}
          'IP':{{ item.value.IP2 }},
          {% endif %}
          {% if item.value.IPNumber ==  "3"%}
          'IP':{{ item.value.IP3 }},
          {% endif %}
          {% if item.value.IPNumber ==  "4"%}
          'IP':{{ item.value.IP4 }},
          {% endif %}}}
  loop: "{{ vms.dict | dict2items }}"
  register: vms2

But I get the error:

The error appears to be in '/etc/ansible/roles/vms.yml': line 17, column 16, but may
be elsewhere in the file depending on the exact syntax problem.

The offending line appears to be:

              'Name':{{ item.value.Name}},
              {% if item.value.IPNumber == "1" %}
               ^ here

I know is a syntax problem but I dont guess where the problem is.

I need some help.

like image 605
Coren Avatar asked Dec 10 '25 01:12

Coren


2 Answers

The following task should create your dictionary as per your requirement inside a var you can reuse elsewhere. Rename my_ip_dict to whatever suits your project better.

- name: Create my IP dictionary
  set_fact:
    my_ip_dict: >-
      {{
        my_ip_dict | default({})
        | combine({item.value.Name: item.value['IP' + item.value.IPNumber]})
      }}
  loop: "{{ vms.dict | dict2items }}"

- name: Check the result:
  debug:
    var: my_ip_dict

Note that I have dropped all the if/else structures by calling directly the correct field depending on IPNumber. I took for granted it always has a value in the valid scope or the other existing IP* fields. If this is not the case, you can always default that value e.g. item.value['IP' + item.value.IPNumber] | default('N/A')

like image 122
Zeitounator Avatar answered Dec 11 '25 15:12

Zeitounator


You should put only variables/expressions within {{ or {%. To me 'Name' looks like normal text and should be outside.

Example:

# Notice the quotes `"` symbol at the beginning and end of debug message

- debug:
    msg:
    - "Name: {{ item.value.Name }},
       {% if item.value.IPNumber == "1" %}
       IP: {{ item.value.IP1 }}
        # and so on... 
       {% endif %}"

This at least should address the error message.

like image 24
seshadri_c Avatar answered Dec 11 '25 13:12

seshadri_c



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!