Automating Cisco IOS
By Kirk Byers
I recently started working on a method to automate various tasks in Cisco IOS using Python and Ansible. The general method consists of an SSH control channel and a separate SCP channel to transfer files:
Once you have a reliable, programmatic file transfer mechanism, then there are several interesting automation use cases:
- Loading new software images.
- Loading a device's initial configuration.
- Restoring a configuration (for a failed device).
- Loading configuration changes (configuration merge)
- Loading a completely new configuration file (configure replace).
After some experimentation, I was able to add support into Netmiko for a separate SCP file transfer mechanism. This support consists of two new classes (SCPConn and FileTransfer).
In addition to the new Netmiko classes, I also built an experimental Ansible module that transfers files to Cisco IOS devices using SCP. You can find this new Ansible module here.
The below diagram details the process that the cisco_file_transfer module uses:
Note, additional options including enable_scp and overwrite have been omitted.
What follows are some examples that use the cisco_file_transfer Ansible module.
My lab environment setup is an AWS RedHat7 server with the following installed:
- Ansible 1.8.2
- Python 2.7.5
- Paramiko 1.14.0
- Python scp module 0.10.0
- Netmiko 0.2.0
I also have a Cisco 881 test router that is reachable from the server (pynet-rtr1).
My Ansible inventory file is the following (modified slightly):
[local] localhost ansible_connection=local [cisco] pynet-rtr1 host=10.10.10.227 port=22 username=admin password=password [cisco:vars] ansible_python_interpreter=~/applied_python/bin/python ansible_connection=local
Playbook1 - SCP a configuration file to the Cisco 881
Note, 'ip scp server enable' is not currently configured on the Cisco 881. The 'enable_scp=true' option will enable and disable SCP during playbook execution.
The playbook then executes as expected and transfers the file:
Here you can see the router before and after:
If I execute the playbook again, then no transfer will occur (as the destination file is already correct):
I can also execute the same playbook this time using the '--check' option. The '--check' option lets me perform a dry run on my playbook so that I can see what will change. Note, I removed the cisco_logging.txt file from the router flash before executing the below '--check' run.
Playbook2 - Load an IOS image to flash
This example is similar to playbook1 except 'ip scp server enable' is already configured on the the router. Additionally, I have specified the overwrite=false option in the playbook. This option will prevent an existing file on the router from being overwriten.
Running the playbook transfers the 43MByte IOS image file:
In order to force an overwrite failure, I then copied /dev/null over the ios_image.bin source file and attempted the transfer again.
I am fairly excited about some of the use cases that the SCP side-channel enables including how it can be used to create Cisco-IOS Ansible modules. I have already started preliminary work on Cisco IOS modules for a configuration merge and for configure replace. All of the above is experimental at this point. I have done a reasonable amount of testing on the cisco_file_transfer module and I have detailed some its caveats below.
- The source file must be specified using an absolute path.
- The module currently only supports a destination filesystem of "flash:".
- The username/password provided must have sufficient permissions to transfer files to the device (and potentially to enable/disable SCP).
If you want to learn more about network automation, Python, and Ansible—then join my email-list. I also periodically run a free Python for Network Engineers email course which you can sign-up for here.
CCIE #6243 emeritus