Jinja syntax for YAML File

20,255

Solution 1

If you can refactor you YAML data, change it like this:

CONT_PLANE_PROT_V4:
  RANGES:
    - 10.193.130.240/28
    - 10.193.135.240/28
  HOSTS:
    - 10.193.131.131
    - 10.196.180.5

This way CONT_PLANE_PROT_V4 is a dictionary with two keys RANGES and HOSTS, which are lists of strings.

Then you can do this:

{% for r in CONT_PLANE_PROT_V4['RANGES'] %}
    Statement1 {{ r }} 
{% endfor %}

{% for h in CONT_PLANE_PROT_V4['HOSTS'] %}
    Statement2 {{ h }}
{% endfor %}

With your original data, you have a list CONT_PLANE_PROT_V4 which contains dictionaries as it's elements and each dictionary has different key inside. You'll have to write a bit more complex template to process this structure.

Solution 2

Based on the @konstantin-suvorov YAML refactoring you could do the following code, so it can be more Dynamic

{% for name, sublist in CONT_PLANE_PROT_V4.items() %}
  List: {{ name}}
  {%for value in sublist %}
    Value: {value}
  {% endfor %}
{% endfor %}

In case you can't change your YAML , base on the output you shown before

Printing Variable
[{u'RANGES': [u'10.193.130.240/28', u'10.193.135.240/28']}, {u'HOSTS': [u'10.193.131.131', u'10.196.180.5']}]

in this case the YAML is processed as an array , so you will need to walk the array first

{% for lists in CONT_PLANE_PROT_V4 %}
  {%for name, sublist in lists.items() %}
   List: {name}
    {%for value in sublist %}
       Value: {value}
    {% endfor %}
  {% endfor %}
{% endfor %}
Share:
20,255
Daniel Macuare
Author by

Daniel Macuare

Updated on February 14, 2020

Comments

  • Daniel Macuare
    Daniel Macuare about 4 years

    I've been reading a lot about loops in python and JINJA but I've not found the right answer for my problem. I'm really new to programming so I must be missing something

    I'hve got the following YAML file

    CONT_PLANE_PROT_V4:
      - RANGES:
        - 10.193.130.240/28
        - 10.193.135.240/28
      - HOSTS:
        - 10.193.131.131
        - 10.196.180.5
    

    I'd like to generate a template with those variables and if I print the variable in Ansible it shows like this:

    Printing Variable

    [{u'RANGES': [u'10.193.130.240/28', u'10.193.135.240/28']}, {u'HOSTS': [u'10.193.131.131', u'10.196.180.5']}]
    

    I'm trying the following in the JINJA template with no success:

    JINJA TEMPLATE

    {% for list in CONT_PLANE_PROT_V4 %}
      {% for ips in CONT_PLANE_PROT_V4[list] %}      
    
        Statement1 {{RANGES_IPs}
    
      {% endfor %}
    {% endfor %}
    
    {% for list in CONT_PLANE_PROT_V4 %}
      {% for ips in CONT_PLANE_PROT_V4[list] %}  
    
        Statement2 {{HOSTS_IPs}}
    
      {% endfor %}
    {% endfor %}
    

    Ansible Error: "AnsibleUndefinedVariable: list object has no element {u'RANGES': [u'10.193.130.240/28', u'10.193.135.240/28', u'10.183.64.240/28', u'10.183.60.240/28', u'10.183.106.240/28', u'10.36.12.240/28', u'10.128.64.240/28', u'10.44.12.240/28', u'10.213.12.240/28', u'10.111.64.240/28', u'10.193.80.240/28']}"}

    Request: Can you please let me know the best way or the easiest way to properly get the value of the 2 lists (4 IPs). I will need to access the values on the "RANGES" and the "HOST" lists. The values on the "RANGES" List will be used on statement 1 and the values on the "HOSTS" list will be used on statement 2.

    Something like this:

    Expected result

    statement1 10.193.130.240/28
    statement1 10.193.135.240/28
    
    statement2 10.193.131.131
    statement2 10.196.180.5
    
    • tedder42
      tedder42 over 6 years
      something's missing here. Show us how you are running this- the command line and the play file, presumably.
    • larsks
      larsks over 6 years
      @ryekayo, you almost never need the leading --- in a YAML file.
  • Daniel Macuare
    Daniel Macuare over 6 years
    That's brilliant Konstantin, that worked for me. I re-arranged my YAML and accessed the variables that way. Thanks!