Read this in other languages: English, 日本語, Español.
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