Configuration templates with Jinja2

Automation everywhere

It happened so fast, network automation is everywhere in every context. One of the core functions of network automation is the ability to build and generate configurations. This only can happen with pre-defined models and templates.

I assume that all network engineers nowadays has at least the basic knowledge to deal with python scripts, if not, there is no better time than now to start. You can find a plenty of Youtube videos or even dedicated courses for network engineers on Udemy & Coursera.

What is a template?

To understand what is a template, you have to look around, whenever you sign up on a website, or ask for a service in an hotel or the town hall or even the hospital. First thing you will be handed an application to fill. This application is a basic form of a template. All what you need is to fill the gaps to generate a meaningful piece of data.

Why using templates with configurations?

Think in a task where you are required to configure a cisco router set of 100 interfaces with [IP address, mask , interface description], what can be static and what might change from interface to another.

Configuration example:
interface GigabitEthernet0/0
  description Interface_Number_1
  ip address
interface GigabitEthernet0/1
  description Interface_Number_2
  ip address

We can easily break this apart and define the variables by surrounding them with brackets, as below:

interface <GigabitEthernet0/0>
  ip address <> <>
interface <GigabitEthernet0/1>
  ip address <> <>

Meanwhile, you can witness the birth of our template. We can just fill the variables and generate the config for as many as interfaces we want.

interface <$interface name>
  description <$interface description>
  ip address <$prefix> <$subnetmask>

Now we have a valid template which we can be rendered by a small script. That script can take the variables from a file or a database or even an excel sheet, and then build the configuration. 

Why Jinja?

According to Wikipedia, Jinja is defined as web template engine for python language, however, we use it for much more than web.

Jinja has a specific format used to build a valid template, and can render data written in both Yaml or JSON.

Lets convert the previous configuration to Jinja2 format:

interface {{ name }}
  description {{ description }}
  ip address {{ prefix }} {{ subnetmask }}
Yaml data:
name: GigaEthernet0/1
description: My_first_interface prefix:

But as you might ask, this is similar of what I would do if I am generating the configuration without a template, but yet I didn’t mention the power of Jinja that it can run loops and conditions within a template.

Loop example:
{% for interface in interfaces %}
interface {{ interface['name'] }}
  description {{ interface['description']|upper }}
  ip address {{ interface['ip'] }} {{ interface['mask'] }}
{% endfor %}
Simply, this for loop will run across the YAML and build as many as interfaces in the Yaml. Lets have a look on how Yaml looks like in this case:
- name: Giga0/1
description: my first interface
- name: Giga0/2
description: my second interface

Fill the gaps with Python

Here comes the python script to make this magic happen within a matter of a second. To do that you will need to work with OS, Jinja2 and Pyyaml libraries.

Altogether, using OS to open the files and load they yaml data into pyyaml , then jinja2 to render the yaml data through the template to generate the final configuration. Once the configuration is ready,  you can push manually or even through a piece of script that can do the job on behalf of you.

Finally, I invite you to play with Jinja and Yaml through my python web tool: PyVold Render tool.

I hope this was helpful to everyone.