Using Python, YAML and Jinja2 to Generate Config Files

You will need three things:

  1. Jinja2 template with your configuration “skeleton”
  2. YAML file with data you want to insert into your configuration
  3. A Python script that feeds data taken from YAML file into Jinja2 template

Now some details. Jinja2 is a template engine designed to be used with Python. It’s similar to Django but is able to employ Python-like expressions. Here is an example for Cisco IOS-style config:

hostname {{ name }}

interface Loopback0
ip address 10.0.0.{{ id }}

{% for vlan, name in vlans.items() %}
vlan {{ vlan }}
name {{ name }}
{% endfor %}

router ospf 1
router-id 10.0.0.{{ id }}
auto-cost reference-bandwidth 10000
{% for networks in ospf %}
network {{ }} area {{ networks.area }}
{% endfor %}

The parts marked with {{ }} are variables and expressions. Here Hostname and the last octet of Loopback0 IP-address are to be substituted with variables but VLANs and OSPF network statements part contain Python-like For loops. These make you able to insert various VLAN and network statements getting data from YAML data file. Here is an example of such data file (I have taken a screenshot from Notepad++ to preserve all the text formatting):

Now a Python script that reads YAML file into dictionary and feeds it’s data into Jinja2 template:

#Import necessary functions from Jinja2 module
from jinja2 import Environment, FileSystemLoader

#Import YAML module
import yaml

#Load data from YAML into Python dictionary
config_data = yaml.load(open('./data_files/data_to_feed.yml'))

#Load Jinja2 template
env = Environment(loader = FileSystemLoader('./templates'), trim_blocks=True, lstrip_blocks=True)
template = env.get_template('template.txt')

#Render the template with data and print the output

This script just prints the result, but it pretty straitforward to write the result into text file that you may load to your device. In my case the result looks like this:

hostname R1

interface Loopback0
  ip address

vlan 10
  name Users

vlan 20
  name Voice

vlan 30
  name Management

router ospf 1
  auto-cost reference-bandwidth 10000
  network area 0
  network area 2
  network area 0

You may use loops in your script, feed it with YAML-serialized data for multiple devices and make it generate multiple config files at a time all based on the same Jinja2-formatted template. All data is nicely stored and there is no need for hard-to-read string concatenation expressions!