Read this in other languages:
English,
日本語,
Español,
Français.
Demonstration templating a network configuration and pushing it a device
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:
Create a new folder called group_vars. Right click on the Explorer
toolbar on the left side of Visual Studio Code and select New Folder

Create a new file called all.yml. Right click on the Explorer toolbar
on the left side of Visual Studio Code and select New File inside the
group_vars directory.

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.
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.
This step will explain and elaborate on each part of the newly created template.j2 file.
{% for interface,ip in nodes[inventory_hostname].items() %}
{% and %}. The
interface,ip breaks down the dictionary into a key named interface and
a value named ip.nodes[inventory_hostname] does a dictionary lookup in the
group_vars/all.yml file. The inventory_hostname is the name of the
hostname as configured in Ansible’s inventory host file. When the
playbook is executed against rtr1 inventory_hostname will be rtr1,
when the playbook is executed against rtr2, the inventory_hostname will
be rtr2 and so forth.The inventory_hostname variable is considered a magic variable which is automatically provided.
items() returns a list of dictionaries. In this case the
dictionary’s key is the interface name (e.g. Loopback100) and the value is
an IP address (e.g. 192.168.100.1)interface {{interface}}
ip address {{ip}} 255.255.255.255
Finally:
{% endfor %}
config.yml. Right click on
the Explorer toolbar on the left side of Visual Studio Code and select New
File . Either copy the playbook below or type this in:---
- name: configure network devices
hosts: rtr1,rtr2
gather_facts: false
tasks:
- name: configure device with config
cli_config:
config: "{{ lookup('template', 'template.j2') }}"
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
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
config (e.g. cisco.ios.config, arista.eos.config) and cli_config
modules can source a jinja2 template file, and push directly to a device.
If you want to just render a configuration locally on the control node,
use the template
module.group_vars and host_vars.
This short example only used group_vars.The finished Ansible Playbook is provided here for an answer key: config.yml.
The provided Ansible Jinja2 template is provided here: template.j2.
You have completed this lab exercise
Click here to return to the Ansible Network Automation Workshop