Jinja2 Basics
Usually, as network engineers, we use Jinja2 to store configuration templates, so let us check the structures, thinking of a practical approach for our daily jobs.
You might want to follow up with some testing for the following blog. Packet Coders have a J2 Render that is quite useful for quick testing.
Data Structures
Variables
{# THIS IS A COMMENT #}
{% set interface = "loopback0" %}
{% set interface = ["loopback0", "loopback1"] %}
{% set interface = {"Name":"loopback0","ip": "10.10.10.10"} %}
{{ interface }}
{{ interface[0] }}
{{ interface["ip"] }} or {{ interface.ip }}
Filters
Jinja allows us to create and use built-in filters to enrich and facilitate dealing with our variables.
Refer to the link whenever needed, as it contains many helpful filters and explanations. The ones I commonly use are:
{# CHECK FILTERS #}
{{ interface|default('DEFAULT_VALUE') }}
{{ interface|replace('ip','ipaddress') }}
Loops
{# LIST #}
{% for server in ntp_servers %}
ntp server {{ server }}
{%- endfor %}
{# DICTIONARY #}
{% for iname, idata in interfaces.items() %}
interface {{ iname }}
description {{ idata.description }}
ip address {{ idata.ipv4addr }} {{idata.subnet}}
{% endfor %}
If Statement
An example of one of my J2 file template configurations for SNMP for Arista EOS devices.
Some of them are configured in the mgt vrf and others are not. This would lead to different configuration commands, so an IF statement fits well.
SNMP_CONFIGURATION.J2
{% if not host.mgmt_vrf|default('default') == 'default'%}
snmp-server host 10.10.10.10 traps version 2c COMMUNITY
{% else %}
snmp-server host {{ host.primary_ip4.address }} vrf {{ host.mgmt_vrf }} traps version 2c COMMUNITY
snmp-server vrf {{ host.mgmt_vrf }}
{% endif %}
snmp-server local-interface {{ host.mgmt_interface }}
snmp-server source-interface {{ host.mgmt_interface }}
snmp-server enable traps snmp
snmp-server enable traps entity
snmp-server enable traps bgp
snmp enable traps switchover
Quick Tips and Tricks
Here are some tips and tricks I like to keep in mind when writing templates that are usually quite handy.
{% if subscribed_if is iterable %}
{% set sub_if = subscribed_if | length %}
{% set grp = loop.index %}
{% if not loop.last %},{% endif %}
Subscribe to my newsletter
Read articles from Pedro D directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by