Read this in other languages: English,
日本語,
Français.
- Exercise 4: Ansible Network Resource Modules - Cisco Example
Demonstration use of Ansible Network Resource Modules
Ansible network resource modules simplify and standardize how you manage different network devices. Network devices separate configuration into sections (such as interfaces and VLANs) that apply to a network service.
Network resource modules provide a consistent experience across different network devices. This means you will get an identical experience across multiple vendors. For example the snmp_server module will work identically for the following modules:
arista.eos.snmp_server
cisco.ios.snmp_server
cisco.nxos.snmp_server
cisco.iosxr.snmp_server
junipernetworks.junos.snmp_server
Configuring SNMP on network devices is an extremely common task, and mis-configurations can cause headaches and monitoring issues. SNMP configurations also tend to be identical across multiple network switches resulting in a perfect use case for automation.
This exercise will cover:
- Configuring SNMP on Cisco IOS
- Building an Ansible Playbook using the cisco.ios.snmp_server module.
- Understanding the
state: merged
- Understanding the
state: gathered
-
Login to an Cisco IOS router and verify the current SNMP configuration.
-
From the control node terminal, you can
ssh rtr2
and typeenable
[student@ansible-1 ~]$ ssh rtr1 rtr1#
-
Use the command
show snmp
to examine the SNMP configuration:rtr1#show snmp %SNMP agent not enabled
-
Use the
show run | s snmp
to examine the SNMP running-configuration on the Cisco device:rtr1#sh run | s snmp rtr1#
As you can see in the output above there is no SNMP configuration on the Cisco router.
-
Create a new file in Visual Studio Code named
resource.yml
-
Copy the following Ansible Playbook into your
resource.yml
--- - name: Configure SNMP hosts: cisco gather_facts: false tasks: - name: Use snmp resource module cisco.ios.ios_snmp_server: state: merged config: location: 'Durham' packet_size: 500 communities: - acl_v4: acl_uq name: Durham-community rw: true - acl_v4: acl_uq name: ChapelHill-community rw: true
-
First lets examine the first four lines:
--- - name: configure SNMP hosts: cisco gather_facts: false
- The
---
designates this is a YAML file which is what we write playbooks in. name
is the description of what this playbook does.hosts: cisco
will execute this playbook only on the Cisco network devices.cisco
is a group name.gather_facts: false
this will disable fact gathering for this play, by default this is turned on.
- The
-
For the second part we have one task that uses the
cisco.ios.snmp_server
tasks: - name: Use snmp resource module cisco.ios.ios_snmp_server: state: merged config: location: 'Durham' packet_size: 500 communities: - acl_v4: acl_uq name: Durham-community rw: true - acl_v4: acl_uq name: ChapelHill-community rw: true
-
name:
- just like the play, each task has a description for that particular task -
state: merged
- This is the default behavior of resource modules. This will simply enforce that the supplied configuration exists on the network device. There is actually seven parameters possible for resource modules:- merged
- replaced
- overridden
- deleted
- rendered
- gathered
- parsed
Only two of these parameters will be covered in this exercise, but additional are available in the supplemental exercises.
-
config:
- this is the supplied SNMP configuration. It is a list of dictionaries. The most important takeaway is that if the module was change fromcisco.ios.snmp_server
tojunipernetworks.junos.snmp_server
it would work identically. This allows network engineers to focus on the network (e.g. SNMP configuration) versus the vendor syntax and implementation.
-
-
Execute the playbook using the
ansible-navigator run
. Since there is just one task we can use the--mode stdout
$ ansible-navigator run resource.yml --mode stdout
-
The output will look similar to the following:
$ ansible-navigator run resource.yml --mode stdout PLAY [Configure SNMP] ********************************************************** TASK [Use snmp resource module] *************************** changed: [rtr1] PLAY RECAP ********************************************************************* rtr1 : ok=1 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
-
Re-running the playbook will demonstrate the concept of idempotency
$ ansible-navigator run resource.yml --mode stdout PLAY [Configure SNMP] ********************************************************** TASK [Override commands with provided configuration] *************************** ok: [rtr1] PLAY RECAP ********************************************************************* rtr1 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
-
As you can see in the output, everything will return
ok=1
indiciating that no changes were taken place.
-
Login to an Cisco switch and verify the current SNMP configuration.
-
From the control node terminal, you can
ssh rtr1
-
Use the command
show snmp
to examine the SNMP configuration:rtr1#show snmp Chassis: 99SDJQ9I6WK Location: Durham 0 SNMP packets input 0 Bad SNMP version errors 0 Unknown community name 0 Illegal operation for community name supplied 0 Encoding errors 0 Number of requested variables 0 Number of altered variables 0 Get-request PDUs 0 Get-next PDUs 0 Set-request PDUs 0 Input queue packet drops (Maximum queue size 1000) 0 SNMP packets output 0 Too big errors (Maximum packet size 500) 0 No such name errors 0 Bad values errors 0 General errors 0 Response PDUs 0 Trap PDUs Packets currently in SNMP process input queue: 0 SNMP global trap: disabled SNMP logging: disabled
-
Use the
show run | s snmp
to examine the SNMP running-confgiuration on the Cisco device:rtr1#show run | s snmp snmp-server community Durham-community RW acl_uq snmp-server community ChapelHill-community RW acl_uq snmp-server packetsize 500 snmp-server location Durham
As you can see, the resource module configured the Cisco IOS-XE network device with the supplied configuration. There are now two total SNMP communities.
- Create a new playbook named
gathered.yml
---
- name: Retrieve SNMP config
hosts: cisco
gather_facts: false
tasks:
- name: Use SNMP resource module
cisco.ios.ios_snmp_server:
state: gathered
register: snmp_config
- name: Copy snmp_config to file
ansible.builtin.copy:
content: "{{ snmp_config | to_nice_yaml }}"
dest: "{{ playbook_dir }}/{{ inventory_hostname }}_snmp.yml"
mode: "644"
-
The first task is identical except the
state: merged
has been switched togathered
, theconfig
is no longer needed since we are reading in the configuration (versus applying it to the network device), and we are using theregister
to save the output from the module into a variable namedsnmp_config
-
The second task is copying the
snmp_config
variable to a flat-file. The double curly brackets denotes that this is a variable. -
The
| to_nice_yaml
is a filter, that will transform the JSON output (default) to YAML. -
The
playbook_dir
andinventory_hostname
are special variables also referred to as magic variables. Theplaybook_dir
simply means the directory we executed the playbook from, and theinventory_hostname
is the name of the device in our inventory. This means the file will be saved as~/network-workshop/rtr1_snmp.yml
for the cisco device(s).
-
Execute the playbook using the
ansible-navigator run
.$ ansible-navigator run gathered.yml --mode stdout
-
The output will look similar to the following:
$ ansible-navigator run gathered.yml --mode stdout PLAY [Retrieve SNMP config] **************************************************** TASK [Use SNMP resource module] ************************************************ ok: [rtr1] TASK [Copy snmp_config to file] ************************************************ changed: [rtr1] PLAY RECAP ********************************************************************* rtr1 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
-
Open the newly created files that
gathered
the SNMP configuration from the Cisco network device(s). -
The files were stored under the device name, for example for rtr1: `~/network-workshop/rtr1_snmp.yml.
$ cat rtr1_snmp.yml
changed: false
failed: false
gathered:
communities:
- acl_v4: acl_uq
name: ChapelHill-community
rw: true
- acl_v4: acl_uq
name: Durham-community
rw: true
location: Durham
packet_size: 500
- Resource modules have a simple data structure that can be transformed to the network device syntax. In this case the SNMP dictionary is transformed into the Cisco IOS-XE network device syntax.
- Resource modules are Idempotent, and can be configured to check device state.
- Resource Modules are bi-directional, meaning that they can gather facts for that specific resource, as well as apply configuration. Even if you are not using resource modules to configure network devices, there is a lot of value for checking resource states.
- The bi-directional behavior also allows brown-field networks (existing networks) to quickly turn their running-configuration into structured data. This allows network engineers to get automation up running more quickly and get quick automation victories.
The finished Ansible Playbook is provided here for an answer key:
You have completed this lab exercise.
Click here to return to the Ansible Network Automation Workshop