Book Image

Network Automation Cookbook

By : Karim Okasha
Book Image

Network Automation Cookbook

By: Karim Okasha

Overview of this book

Network Automation Cookbook is designed to help system administrators, network engineers, and infrastructure automation engineers to centrally manage switches, routers, and other devices in their organization's network. This book will help you gain hands-on experience in automating enterprise networks and take you through core network automation techniques using the latest version of Ansible and Python. With the help of practical recipes, you'll learn how to build a network infrastructure that can be easily managed and updated as it scales through a large number of devices. You'll also cover topics related to security automation and get to grips with essential techniques to maintain network robustness. As you make progress, the book will show you how to automate networks on public cloud providers such as AWS, Google Cloud Platform, and Azure. Finally, you will get up and running with Ansible 2.9 and discover troubleshooting techniques and network automation best practices. By the end of this book, you'll be able to use Ansible to automate modern network devices and integrate third-party tools such as NAPALM, NetBox, and Batfish easily to build robust network automation solutions.
Table of Contents (15 chapters)

Retrieving operational data from IOS devices

In this recipe, we will outline how to execute operational commands on IOS devices and store these outputs to text files for further processing. This allows us to capture any operational commands from IOS devices during pre- or post-validation after we perform any deployment so that we can compare the results.

Getting ready

In order to follow along with this recipe, an Ansible inventory file should be in place and the network should already be set up as per the previous recipes.

How to do it...

  1. Create a new playbook called pb_op_cmds.yml and populate it with the following tasks to create the directory structure to save the output from the devices:
---
- name: "Play 1: Execute Operational Commands"
hosts: network
vars:
config_folder: "configs"
op_folder: "op_data"
op_cmds:
- show ip ospf neighbor
- show ip route
tasks:
- name: "P1T1: Build Directories to Store Data"
block:
- name: "Create folder to store Device config"
file:
path: "{{ config_folder }}"
state: directory
- name: "Create Folder to store operational commands"
file:
path: "{{ op_folder }}"
state: directory
run_once: yes
delegate_to: localhost
  1. Update the pb_op_cmds.yml playbook and populate it with the following tasks to retrieve the running configuration from the devices:
      - name: "P1T2: Get Running configs from Devices"
ios_command:
commands: show running-config
register: show_run
- name: "P1T3: Save Running Config per Device"
copy:
content: "{{ show_run.stdout[0] }}"
dest: "{{ config_folder }}/{{ inventory_hostname }}.cfg"
  1. Update the playbook and populate it with the following tasks to retrieve the operational commands from the devices and save it:
      - name: "P1T4: Create Folder per Device"
file:
path: "{{ op_folder}}/{{ inventory_hostname }}"
state: directory
delegate_to: localhost
- name: "P1T5: Get Operational Data from Devices"
ios_command:
commands: "{{ item }}"
register: op_output
loop: "{{ op_cmds }}"
- name: "P1T6: Save output per each node"
copy:
content: "{{ item.stdout[0] }}"
dest: "{{ op_folder}}/{{ inventory_hostname }}/{{item.item | replace(' ', '_')}}.txt"
loop: "{{ op_output.results }}"

How it works...

In this recipe, we are using the ios_command module in order to execute operational commands on the IOS devices, and saving them to text files. In order to achieve this goal, we perform the following steps:

  • We create the folders that we will store the output to, and we create a folder called configs to store the running config of all the devices. We also create an op_data file to store the output of the operational commands that we will get from the devices.
  • We then execute the show running command on all the IOS devices in our inventory and we register the output in a new variable called show_run.
  • We use the copy module to save the output from the previous task to a file for each device. The output from the command run is saved in the stdout variable. As we executed a single command, the stdout variable only has a single item (stdout[0]).

Once we execute this task, we can see that the configs folder is populated as shown in the following output:

$ tree configs/
configs/
├── access01.cfg
├── access02.cfg
├── core01.cfg
├── core02.cfg
├── isp01.cfg
├── wan01.cfg
└── wan02.cfg

For the next part, we create a folder for each node to store the output from the multiple show commands that we will execute on the IOS devices.

We use the ios_command module to execute the show commands on the devices, and save all the output in a new variable called op_output. We use the copy execute command, show ip route, and we create a file for the output of this command with the name show_ip_route.txt.

After running this task, we can see that this is the current structure of the op_data folder:

$ tree op_data/
op_data/
├── access01
│ ├── show_ip_ospf_neighbor.txt
│ └── show_ip_route.txt
├── access02
│ ├── show_ip_ospf_neighbor.txt
│ └── show_ip_route.txt
├── core01
│ ├── show_ip_ospf_neighbor.txt
│ └── show_ip_route.txt
├── core02
│ ├── show_ip_ospf_neighbor.txt
│ └── show_ip_route.txt
├── isp01
│ ├── show_ip_ospf_neighbor.txt
│ └── show_ip_route.txt
├── wan01
│ ├── show_ip_ospf_neighbor.txt
│ └── show_ip_route.txt
└── wan02
├── show_ip_ospf_neighbor.txt
└── show_ip_route.txt

We can check the content of one of the files to confirm that all the data has been stored:

$ head op_data/core01/show_ip_ospf_neighbor.txt

Neighbor ID Pri State Dead Time Address Interface
10.100.1.3 0 FULL/ - 00:00:37 10.3.1.2 Ethernet1/0
10.100.1.2 0 FULL/ - 00:00:36 10.1.200.2 Vlan200