Ansible & Cisco | Network automation
Large scale automated disasters ;)
Configuring network equipment has always been somewhat of a tedious affair. Copy and pasting a configuration file through the console port doesn’t scale (or you need a lot of interns!) and other solutions like Cisco Prime are slightly overkill if you only want to change a few lines of configuration.
This is where Ansible comes to the rescue. Originally built as a Linux Configuration Management Tool, in the vein of Chef/Puppet/Salt, it’s built around an SSH agent-less push model. Directly using the SSH connection, it’s remotely executing command you define in “Playbooks” This is why it’s a great fit when it comes to network devices as those are still telnet/SSH based. API/Netconf are starting to be more and more common, but SSH is still present. Especially on older network equipment.
Recently, Ansible has been augmented with a series of module that allow a network operator to leverage Ansible to deploy configuration to remote equipment. For example, if you just realized that your template is mysteriously missing NTP, Syslog and SNMP configuration and there are about 40 pieces of equipment deployed – I’m not saying this totally happened to us – Ansible is here to help.
The following playbook does the following :
- Define a role : cisco-ios-common – which holds all the default configuration that is used by our devices.
- In our case, the SSH connection is initiated from the sysadmin computer running the playbook – but it can be adapted to run from a bastion host.
- No need to gather facts.
- Create the variable holding the credentials necessary for accessing the equipment.
---
- hosts: axs-switches
roles:
- cisco-ios-common
gather_facts: false
connection: local
vars:
ssh:
username: sysadmin
password: r00tm3
---
- name: Enable the SNMP server with a given community. READ ONLY
ios_config:
lines:
- snmp-server community {{ SNMP_COMMUNITY }} RO
backup: yes
provider: "{{ ssh }}"
- name: Configure the ntp server.
ios_config:
lines:
- ntp server {{ NTP_SERVER }}
backup: yes
provider: "{{ ssh }}"
This is literally lines that are parsed from the “show running-config” command and compared to each task. If it’s not there, it’s added or changed . In this case, we configure the RO SNMP community and the NTP server. To be extra careful, we also take a backup of the running-config before applying the changes. Using the “provider” statement, we are referencing the variables defined in the playbook file. All other private variables can be stored in an Ansible vault file and encrypted.
With the appropriate inventory file I was able to quickly fix our deployment mistake without manually connecting to every single switch.