Automating Cisco devices with Ansible

Andrea Dainese
January 13, 2022
Post cover

I spent a few Twitch sessions speaking about the automation of Cisco devices with Ansible. I don’t think Ansible is the best tool and the best way to automate tasks on Cisco devices, but a well-designed and well-documented Ansible playbook can be maintained by non NetDevOps guys too. That’s the reason why I decided to design some Ansible playbooks for a service provider a few years ago. During the few Twitch sessions, I reviewed why and how I designed the playbooks to provision brand new Cisco routers and customer lines.

Ansible with Cisco

Ansible with Cisco devices

Ansible automates Cisco devices via SSH connection. Ansible sends (types) command, retrieved and parses the output. I call this approach “screen scraping”. You can find more in a previous post . Today screen scraping is the only approach you can use with many devices, but mind that:

  • It’s required that you learn how to debug errors on parsing.
  • If the vendor changes something in the output, your automation playbook/scripts could start failing.

I developed a few Ansible playbooks to give you reusable recipes. In the references, you will find all commands and playbooks I used during the Twitch sessions.

Static and dynamic inventory

In our tests I used a static inventory containing all interesting parameters and credentials. In production you won’t do that; there are specific solutions you should evaluate (Ansible vault or external vaults like the one from HashiCorp . I suggest two more approaches: user personal assigned credentials or use environment variables.

We also discussed dynamic inventory. If the inventory file is executable , Ansible executes the file and uses the output as an inventory. The inventory format differs from static and dynamic inventory so I played a few to make both works.

Checking if the configuration has been saved

The first playbook I presented is used to check if the running configuration differs from the startup configuration.

The playbook can be used to check if the configuration has been saved.

Basic router configuration and playbook optimization

The Ansible Cisco IOS modules retrieve the running configuration every time it’s invoked. In a complex playbook, the module could be invoked many times and the result could be very very slow.

The second playbook I presented optimizes this behavior: the running configuration is retrieved once, saved into a variable and used later.

Configuration modeling

In my designing tasks, I’m used to spending a lot of time modeling. The third playbook reads parameters from a configuration file . That file should define the entire infrastructure automated by Ansible.

Roles

Designing complex Ansible playbooks requires understanding roles. In short, roles are groups of sub-tasks. In the second Twitch session I provided some Ansible roles for Cisco devices .

Deleting legacy configurations

I develop Ansible playbooks with the idempotency in mind. This property is often guaranteed by Ansible modules, but there are some cases you should double-check. Moreover, there are some cases Ansible cannot allow you to set a specific list of items, because the present items won’t be deleted.

There are two major examples: DNS and NTP servers. How can we delete unused servers? The manual workflow would be:

  1. display running configuration;
  2. add servers included in the configuration list;
  3. delete servers only if they are not included in the configuration list.

The role translate this workflow into the Ansible language. The regex_findall function captures lines starting with ip name-server and regex_replace function maintains DNS only in a list format.

The when clause checks if all configured servers are in the configuration file.

QoS modeling and configuration

As we did in configuration modeling, we discussed how to model QoS configurations. I provided an example in a dedicated configuration file .

In short:

  • each customer line has a limited bandwidth (the internet_profiles list);
  • each customer line has a guaranteed bandwidth for voice traffic (the voice_profiles list);
  • the name of internet_profiles and voice_profiles are in the form of <DOWNSTREAM>_<UPSTREAM>;
  • bandwidth is defined by a specific CIR (Committed Information Rate) configuration (the cir dictionary, using the <DOWNSTREAM> and the <UPSTREAM> as keys);
  • traffic is matched by class_maps using COS (Class Of Service).

Finally the QoS role configures class and policy maps on the target routers.

Interface modeling and configuration

The previous paragraph prepared the bricks used by the QoS policies applied to the interface. The example configuration file describes how an interface should be configured:

  • interface name;
  • if the interface is enabled;
  • the reserved bandwidth for voice traffic (inbound/outbound);
  • the maximum bandwidth available (inbound/outbound);
  • the customer ID.

Because of the huge number of configured interfaces, the Ansible playbook is not targeting all interfaces of all CPEs but it’s limited to specific interfaces that changed in the last 24 hours.

The interface provisioning role execute some tasks per each interface.

Nested loops in Ansible are not so easy to understand: they require to include external task files and because the inner loop overwrites the outer loop variables, it has to be manually stored in a different name. The main task file should be self-explanatory.

Every time one or more interfaces must be configured, the Ansible playbook can be executed using a specific interface configuration file:

./playbook-2-port_provisioning.yml -i hosts.py --extra-vars config_file=port-config.yml

A real case scenario

The approach described in this post can be used to automate Internet line provisioning in an Internet provider:

  • a dynamic inventory script could get the list of all available CPEs;
  • a daily task could prepare a file containing the list of the interfaces to be provisioned;
  • the Ansible interface provisioning playbook could configure or deconfigure all interfaces changed during the last 24 hours.

Two more playbooks are available:

  • the Ansible device provisioning playbook to provision and verify the configuration of CPEs;
  • the Ansible interface provisioning playbook targeting all interfaces of all CPEs to verify the configuration (it will take hours to complete).

References