Supplemental - Network Configuration with Jinja Templates

Read this in other languages: uk English, japan 日本語, Español Español.

Table of Contents

Objective

Demonstration templating a network configuration and pushing it a device

Guide

Step 1 - Creating group vars

This step will cover creating Ansible variables for use in an Ansible Playbook. This exercise will use the following IP address schema for loopbacks addresses on rtr1 and rtr2:

Device Loopback100 IP ———— ————- rtr1
192.168.100.1/32 rtr2 192.168.100.2/32    

Variable information can be stored in host_vars and group_vars. For this exercise create a folder named group_vars:

The interface and IP address information above must be stored as variables so that the Ansible playbook can use it. Start by making a simple YAML dictionary that stores the table listed above. Use a top level variable (e.g. nodes) so that a lookup can be performed based on the inventory_hostname:

nodes:
  rtr1:
    Loopback100: "192.168.100.1"
  rtr2:
    Loopback100: "192.168.100.2"

Copy the YAML dictionary we created above into the group_vars/all.yml file and save the file.

All devices are part of the group all by default. If we create a group named cisco only network devices belonging to that group would be able to access those variables.

Step 2 - Creating Jinja2 template

Create a new file called template.j2 in the network-workshop directory. Right click on the Explorer toolbar on the left side of Visual Studio Code and select New File. The directory stucture will look like this:

├── group_vars
│   └── all.yml
├── template.j2

Copy the following into the template.j2 file:

{% for interface,ip in nodes[inventory_hostname].items() %}
interface {{interface}}
  ip address {{ip}} 255.255.255.255
{% endfor %}

Save the file.

Step 3 - Exploring the Jinja2 template

This step will explain and elaborate on each part of the newly created template.j2 file.

{% for interface,ip in nodes[inventory_hostname].items() %}

The inventory_hostname variable is considered a magic variable which is automatically provided.

interface {{interface}}
  ip address {{ip}} 255.255.255.255

Finally:

{% endfor %}

Step 4 - Create a playbook

---
- name: configure network devices
  hosts: rtr1,rtr2
  gather_facts: false
  tasks:
    - name: configure device with config
      cli_config:
        config: "{{ lookup('template', 'template.j2') }}"

Step 5 - Execute the Ansible Playbook

Use the ansible-navigator command to execute the playbook:

[student@ansible network-workshop]$ ansible-playbook config.yml

The output will look similar to the following:.

[student@ansible-1 network-workshop]$ ansible-navigator run config.yml --mode stdout

PLAY [configure network devices] ***********************************************

TASK [configure device with config] ********************************************
changed: [rtr1]
changed: [rtr2]

PLAY RECAP *********************************************************************
rtr1                       : ok=1    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
rtr2                       : ok=1    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

Step 6 - Verify configuration

Use the command show ip int br to verify the IP addresses have been confirmed on the network devices.

[student@ansible network-workshop]$ ssh rtr1

rtr1#show ip int br | include Loopback100
Loopback100            192.168.100.1   YES manual up                    up

Takeaways

Solution

The finished Ansible Playbook is provided here for an answer key: config.yml.

The provided Ansible Jinja2 template is provided here: template.j2.

Complete

You have completed this lab exercise


Click here to return to the Ansible Network Automation Workshop