build new variables in Jinja2 Loop and use it

Question:

I have a file containing a YAML document, with informations about vlans:

#yaml_file.yaml
- vlan: 123
  name: DATEN-VLAN
- vlan: 124
  name: PRINTER-VLAN
- vlan: 125
  name: WLAN-VLAN

Then I created a Jinja2Template to loop through the vlans:

{% for vlan in vlans %}
    interface {{INTERFACE}}.{{vlan['vlan']}}
    description {{vlan['name']}}
    ip address {{'V_VLAN_IP_' ~ vlan['vlan']}}
{% endfor %}

I render the template with the following code in Python:

template = template.render(
    vlans=vlans,
    INTERFACE="Gi0/1",
    V_LAN_IP_123="192.168.100.1",
    V_LAN_IP_124="192.168.200.1",
    V_LAN_IP_125="192.168.300.1"
)

In the loop I am trying to create dynamically a new variable for each loop with the following line:
ip address {{'V_VLAN_IP_' ~ vlan['vlan']}}

The Outuput looks like this:

    interface Gi0/1.123
    description DATEN-VLAN
    ip address V_VLAN_IP_123

    interface Gi0/1.124
    description PRINTER-VLAN
    ip address V_VLAN_IP_124

    interface Gi0/1.125
    description WLAN-VLAN
    ip address V_VLAN_IP_125

But that is not, I am goaling for. I want that the created variable is used and the value is replaced by the given informations in the render call in the python-script.
So "V_VLAN_IP_123" should be replaced by "192.168.100.1", "V_VLAN_IP_124" by "192.168.200.1" and "V_VLAN_IP_125" by "192.168.300.1".

My output should look like this:

    interface Gi0/1.123
    description DATEN-VLAN
    ip address 192.168.100.1

    interface Gi0/1.124
    description PRINTER-VLAN
    ip address 192.168.200.1

    interface Gi0/1.125
    description WLAN-VLAN
    ip address 192.168.300.1

I tried several things to concatenate the variable.

Asked By: Joebel

||

Answers:

Pass the IPs as a dict so you don’t need to think about "variable variables":

import jinja2
import yaml

vlans = yaml.safe_load(
    """
- vlan: 123
  name: DATEN-VLAN
- vlan: 124
  name: PRINTER-VLAN
- vlan: 125
  name: WLAN-VLAN
"""
)

templ = jinja2.Template(
    """
{% for vlan in vlans %}
    interface {{INTERFACE}}.{{vlan['vlan']}}
    description {{vlan['name']}}
    ip address {{ips[vlan['vlan']]}}
{% endfor %}
""".strip()
)

print(
    templ.render(
        INTERFACE="Gi0/1",
        vlans=vlans,
        ips={
            123: "192.168.100.1",
            124: "192.168.200.1",
            125: "192.168.300.1",
        },
    )
)

outputs


    interface Gi0/1.123
    description DATEN-VLAN
    ip address 192.168.100.1

    interface Gi0/1.124
    description PRINTER-VLAN
    ip address 192.168.200.1

    interface Gi0/1.125
    description WLAN-VLAN
    ip address 192.168.300.1
Answered By: AKX
Categories: questions Tags: , , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.