EVE-NG Linux VM SSH troubleshooting
September 20, 2025
Automating Cisco devices with Ansible
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 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:
- display running configuration;
- add servers included in the configuration list;
- 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
andvoice_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).