When I use Ansible, it is not just to pull info by running show commands, as we did in the previous post. One of the most useful features I rely on, is to generate configurations.  A powerful templating engine I use is Jinja.

The combination of Ansible and Jinja will enhance your workflow, both in terms of speed and accuracy, reducing human errors and the pain which comes with it. In this tech post, we will go through few examples on how to use the combination.

Template variables

My starting point is the template I plan to use, and start building my variables and relations based on that. On this topology, I wish to configure interface E0/1 on both R1 and R2, with IP addresses, and descriptions.

I should end up automating the creation of below template for R1:

interface Ethernet0/1
 description ### LINK to R2 ###
 ip address 10.1.1.0 255.255.255.254

Based on the final template, I can build the headers for my variables CSV files, which should be standardised as this:

interface Ethernet0/1
 description ### <DESCRIPTION> ### 
 ip address < IPADDR > 255.255.255.254

HOSTNAME and Mngt represent will be useful when logging in the device, then creating the file for each config, using the Mngt IP address.

Creating csv file where variable unde headings must match my jinja tempate.

HOSTNAME,Mngt,DESCRIPTION,IPADDR 
R1,192.168.86.24,LINK to R2,10.1.1.0 
R2,192.168.86.25,LINK to R1,10.1.1.1

Creating the Jinja template

Now that we have the variables and the config template, let's create the Jinja based template and save it as NL.j2. We use to define each variable in the configuration.

interface Ethernet0/1
 description ###  ###
 ip address  255.255.255.254

Creating the Ansible playbook

Now that our csv file devices.csv, and Jinja template NL_interfaces.j2 are created on our folder, we create and save following Ansible playbook, which would generate config files, based on the standard template, and apply variables listed for each device, respevctively.

# Ansible playbook to generate Cisco configs from CSV and Jinja2 template
---
# Generate Cisco configuration files from CSV data and template
- hosts: localhost
  gather_facts: no
  tasks:
    # Read CSV file with device information
    - name: Read devices CSV file
      read_csv:
        path: devices.csv
        fieldnames: ['HOSTNAME', 'Mngt', 'DESCRIPTION', 'IPADDR']
      register: device_list

    # Generate config file for each device using template
    - name: Generate config files from template
      template:
        src: NL_interfaces.j2           # Source template file
        dest: "./.txt"  # Output file: HOSTNAME.txt
      vars:
        HOSTNAME: ""     # Pass hostname to template
        DESCRIPTION: "" # Pass description to template  
        IPADDR: ""         # Pass IP address to template
      loop: ""       # Process each CSV row

The end result is 2 files R1.txt & R2.txt were created, as per below

R1 R2
interface Ethernet0/1
 description ### LINK to R2 ###
 ip address 10.1.1.0 255.255.255.254
interface Ethernet0/1
 description ### LINK to R1 ###
 ip address 10.1.1.1 255.255.255.254

Conclusion

Based on the method and approach described in this this tech blog, generating configuration templates based on Ansible and Jinja offer limitless possibilities. As long as you list all your variables in a smart way, and set them correctly in the base template, your configurations will be 100% consistent and accurate.

Wouldn’t be great to be able to push the created template file per device, immediately after creating them? This will be the tech blog.