Skip to content

Network Automation

My journey with Network & Cloud Automation

Menu
  • Beginner
  • DevOps-NetDevOps
  • Network Automation
    • Docker
    • Python Libraries
      • NAPALM
      • Netmiko
      • Jinja2
      • Scrapli
      • Yang
  • Cloud Automation
    • Terraform
  • Python 🐍 Tips and Tricks
Menu
jinja2

Basics of Python Jinja2 Templating Library.

Posted on September 20, 2021August 29, 2021 by Gurpreet Kochar

In the previous Jinja2 post, we have seen a basic use case for network configuration automation. In this post, let’s dive into the basics of Python Jinja2 templating library. The intent is to cover fundaments of jinja2 that most of the time are overlooked because tend to dive directly into the “how to use jinja2” aspect. This post is going to deal with the syntax and semantics of Jinja2

Python Jinja2 For Network Engineers
  1. {# …… #} text between this is regarded as comment.
  2. {{ …….. }} variables you want to substitute go in here.
  3. {% …. %} conditional blocks. If, else, for etc

For example:-

{# this is a comment and will not be included in
the rendered output of jinja2 template 
#}
hostname {{ hostname }}  {# {{hostname}} is a variable that will be substituted here #}
!
interface Loopback0
 ip address {{ loopback }}
!
{# {%..%} below is the conditional block #}
{% for vlan, name in vlans.items() %}
vlan {{ vlan }}
 name {{ name }}
! 
{% endfor %} {# end of conditional block for loop #}

To the above jinja2 template, if we pass in the below dictionary as an example:-

{
    'hostname': 'my-rtr-01',
    'loopback': '1.1.1.1 255.255.255.255',
    'vlans': {'data': 10, 'voice': 20, 'mgmt': 30},
    'interfaces' : ['Fa0/1', 'Fa0/2', 'Gig0/1', 'Gig0/2', 'Gig0/3']
}

you can reference the attributes of this dictionary inside Jinja2 as {{hostname}}, {{loopback}}, {{vlans}} but if you want to reference data VLAN specifically, then you can say {{vlans.data}} or {{vlans[‘data’]}}. Both of these notations work fine, it’s just a matter of preference. The only limitation being you cant use the dot notation to access variables with space in the name


Control Statements / Control Structures / Conditional blocks / Conditional Statements


  1. FOR – used to iterate over an interable. For example:-
{# iterate over a list of interfaces as in above dictionary and print interface #}

{% for interface in data.interfaces %}
    {{ interface }}
{% endfor %}


─ python3 main.py                                                                                                                                                                 ─╯


    Fa0/1

    Fa0/2

    Gig0/1

    Gig0/2

    Gig0/3

2. IF – validate a condition before proceeding

{% for interface in data.interfaces %}
 {% if 'Fa' in interface %}
   FA Interface {{interface }}
 {% elif "Gig" in interface %}
   GIG Interface {{ interface }}
 {% endif %}
{% endfor %}


╰─ python3 main.py                                                                                                                                                                 ─╯

 
   FA Interface Fa0/1
 
   FA Interface Fa0/2 
 
   GIG Interface Gig0/1
  
   GIG Interface Gig0/2
  
   GIG Interface Gig0/3
 

If you see, Jinja is introducing a lot of blank lines and empty white spaces in the output. There is a way to get around this problem, rather a couple of ways to get around this problem.

  • First solution, also the easiest
# add lstrip_blocks = True
# trim_blocks = True
# these strip off spaces and lines from blocks.
env = Environment(loader = FileSystemLoader('./'), lstrip_blocks=True, trim_blocks=True)
  • Second solution is the usage of {%- at the begining of the block or ending the block with -%}. If you would like to strip the white space before the block, use ‘-‘ minus sign at the beginning of the block or if you want to strip white spaces after the end of the block, use ‘-‘ at the end of the block.
  • No usage of ‘-‘
  • Usage of ‘-‘ at the start of for block remove leading white spaces and new line
  • Usage of ‘-‘ end of each
  • Combined usage of ‘-‘ at the start and end of each for block
  • Using ‘-‘ with the internal IF block to remove leading and trailing space
  • ‘-‘ at end of top IF block remove spaces between line
  • Putting ‘-‘ at then od elif block

You could also use shorthand notation for the conditional blocks. Instead of using a separate line for the start and end of the block, each block can be done inline. For example:-

{%- for interface in data.interfaces -%}
 {{interface}}
{%- endfor %}

could also be written as 

{%- for interface in data.interfaces -%}{{interface}}{%- endfor %}

Inside Jinja2 syntax, you could also use all operators as you would do in python language. Operators like

  1. Maths operators like +,-,*,/ etc
  2. Logic operators like for, if, and, or, not, in, is, not in etc
  3. Comparison operators like =, !=,,>, <, >= etc etc

{{ 3 – 2 }}

{{ 3 + 2 }}

Let’s take another example:-

{% set variable1 = 30 %}
{% if variable1 > 50 %}
Hello
{% else %}
Jinja2
{% endif %}

Explanation:-

  1. set variable1 = 30
  2. check if variable1 > 50
  3. If yes, print Hello
  4. otherwise print Jinja2

Read more here

https://jinja.palletsprojects.com/en/3.0.x/templates/

Next up is an advanced topic of understanding Jinja2 Template Inheritance. This is the most useful feature of Jinja2 should you wish to use jinja in a project and realize its full potential.

Know someone who may benefit? Share this:

  • Tweet
  • Click to share on Telegram (Opens in new window) Telegram
  • Click to share on WhatsApp (Opens in new window) WhatsApp
  • Click to email a link to a friend (Opens in new window) Email
  • More
  • Click to print (Opens in new window) Print
  • Click to share on Reddit (Opens in new window) Reddit
  • Share on Tumblr
  • Pocket

Like this:

Like Loading...

Related

Leave a ReplyCancel reply

All Blog Posts
My Resume

Upcoming Posts

Sorry - nothing planned yet!

Recent Posts

  • How to backup configuration to TFTP Server using Ansible – Part II
  • How to backup network devices using Ansible – Part I
  • Netmiko SSH Proxy/JumpServer
  • A short note on SASE
  • Understanding Ansible

Recent Comments

  1. Jack on Multithreading with Python for Network Engineers
  2. LifeCanvas on [Theory] Multithreading vs Multiprocessing vs AsyncIO
  3. Jasper Horng on Netmiko SSH Proxy/JumpServer
  4. asdfasdf on Python API Using FASTAPI – UPDATE – PUT – PATCH – Part V
  5. Gurpreet Kochar on Python Scrapli AsyncIO Usage

Archives

  • September 2022
  • February 2022
  • January 2022
  • December 2021
  • November 2021
  • October 2021
  • September 2021
  • August 2021
  • July 2021
Topic Request / Suggestion
Loading
© 2025 Network Automation | Powered by Minimalist Blog WordPress Theme
%d