Ansible Network Engine and NTC Templates
In this post we will talk about primarily three components that will work together to get structured data out of the command line of a Cisco device. The three pieces are:
Why this Post?#
I'm writing this post because I was initially hesitant to start using the Ansible role originally when I was doing everything pretty well with the generic modules that come available with Ansible. I was challenged to migrate a Python script that was using TextFSM and Netmiko to be in Ansible. So I was originally aware of Ansible Network Engine, but had not done anything with it. So what better time than to put it to practice than when it is needed.
Ansible Network Engine#
The Ansible network engine is an Ansible role that is being developed by the Red Hat Ansible team. From the Github page:
This role provides the foundation for building network roles by providing modules and plug-ins that are common to all Ansible Network roles.
Within Ansible Network Engine you have the ability to parse
the output of text. You can write your
own parser, or leverage some work that has been done by others (and willing to put the work out for
the good of the community - not stealing it).
I'm going to recommend to read more on Ansible Network Engine parser with your own text parsing to go to this site - https://termlen0.github.io/2018/06/26/observations/ This post is more about using already existing TextFSM parsers with the help from NTC than the parser itself.
A second link found recently is from the Ansible linklight (learning) team. Take a look here if wanting to do more with Parsers. https://github.com/ansible/workshops/tree/master/exercises/ansible_network/supplemental/3-1-parser
TextFSM#
From the Github page:
TextFSM is a Python module which implements a template based state machine for parsing semi-formatted text. Originally developed to allow programmatic access to information returned from the command line interface (CLI) of networking devices.
Basically the gist of things is that TextFSM takes text that is output from a show command and puts it into structured data. It does this using a regex pattern matching setup under the hood. This can be helpful for grabbing information out of a text blob issues to networking devices.
You must first install the textfsm python module for this to work. To install, I recommend installing on both Python2 and Python3 in case the Ansible version is still using Python2:
TextFSM Parser#
Digging into the code on the Ansible Network Engine Github page you will find the file: https://github.com/ansible-network/network-engine/blob/devel/library/textfsm_parser.py
This is the TextFSM parser engine that is able to be leveraged. Looking at the Python file and the
EXAMPLES
section you can find much more information about how to leverage the particular module.
From the Python file it has the following section:
- name: store returned facts into a key call output
textfsm_parser:
file: files/parser_templates/show_interface.yaml
content: "{{ lookup('file', 'output/show_interfaces.txt') }}"
name: output
Breaking this down further helps to get to the point.
Line 1: This is the name of the Ansible task, nothing new here
Line 2: Calls the plugin textfsm_parser
Line 3: File
, this is the parsing file that you are leveraging in the task, and where you would
call the file location for the ntc template
Line 4: Content
, this is what you are going to send through the parser. In the example given it is
a file, but you can also have a variable of say output from a previous command run put in here
Line 5: name
, this is where you will store the output data, it will be in a structured format
This will not get into reading the output of the structured data. For more on that please take a look back at my previous post on working without output
The original tricky part was the part about the File
. Originally a lot of posts related to having
a parser file all set to go. My original thinking was I don't see those parsers, but they are in the
examples. I decided to try to point the textfsm parser at an NTC template that had been downloaded.
After this, success.
Content
is the text that you want to send through the parser. So a variable or a text file
The name
portion is what you are registering as facts that can be accessed underneath
ansible_facts
.
NTC Templates#
NTC (Network to Code) has a community environment with a significant number of parsers available. I have found these particularly helpful in the Cisco environment. To install - checkout the Github page.
These are files, so the best methodology I have found is to download these to your machine using the
git process of cloning. There are updates made regularly, so make sure to do git pull
to get the
most recent version.
Pro tip: You may want to install these to your home directory. This is the default directory if memory serves me right that Netmiko will look for the textfsm templates as well
Sample#
Here is the playbook that I will run against the lab environment.
---
# yamllint disable rule:truthy
# yamllint disable rule:line-length
- name: Switch config
connection: network_cli
hosts: switches
gather_facts: no
become: yes
become_method: enable
roles:
- ansible-network.network-engine
tasks:
- name: CLI >> Get CDP neighbors
ios_command:
commands:
- show cdp neighbors
register: command_output
- name: SYS >> Parse CDP Information
textfsm_parser:
file: "/opt/ntc-templates/templates/cisco_ios_show_cdp_neighbors.template"
content: "{{ command_output.stdout[0] }}"
name: cdp_facts
- name: DEBUG >> Print output
debug:
msg: "{{ ansible_facts.cdp_facts }}"
Task 1: Get CDP Neighbor information#
This task is going to log in and get the CDP neighbor information from the device and register it to
a fact command_output
Task 2: Send through the parser#
This is where the parser comes in, it will take the command output taken in the first task and send
it through the textfsm parser. This then registers the information underneath ansible_facts
. The
next task is where you will see that output.
Task 3: Prints the output#
You will see the information underneath the ansible_facts
to get at the information as it sits
parsed.
Sample Output#
Summary#
Putting all of these together into a playbook you can more easily get at information presented from a network device command line. Let's say you wanted to get CDP neighbors. The CDP neighbor command output is tough to work with, other than seeing if something is in the output.
Share on Share on Share on Share on Share on