Automation is definitely one of many buzz words going around in the networking world. I heard a few things about it, but until recently I didn’t have much idea about how it actually looks and feels. Then, a change came. A few months ago I was introduced to a wonderful configuration management platform called Ansible. The company I work for uses it to manage configuration of VMWare NSX infrastructure in the data centers, but I was more interested in its capabilities to manage hardware network components. And it didn't disappoint me.
Ansible is a simple configuration management software that uses a concept of playbooks which are essentially scripts that run against devices in your environment. It is highly extensible, because it uses modules written in Python, and anyone with some coding skills could write his/her own module for a certain device or enhance the existing module's functionality.
In this post I'd like to just demonstrate how Ansible can be used to automate networks. First, let's try to get an idea of what automation is and where it is applicable. In my humble opinion, automation can save time in performing simple, repetitive, high-volume tasks. For the sake of this particular example, I've chosen VLAN creation as a task. Let's imagine that we've got a simple topology:
Switches SW1 and SW2 are our edge switches, and their ports connect to access switches, where customer devices are connected. Our task is to automate the provisioning of VLANs for new customers. We need to make sure the following is accomplished:
· a VLAN is created on all switches with a customer name as VLAN name
· a VLAN is allowed on all the relevant trunk ports
By default we don't allow any VLANs on any trunk links. The only VLANs that exist in the beginning are VLAN 1 and management VLAN 4094. The IP subnet on management VLAN is 192.168.0.0/24
We've got Ansible command station in VLAN 4094 and configured with the IP address from 192.168.0.0/24 range.
First thing we need of course is access credentials for switches. The username and password are "admin" and "admin". Absolutely unbreakable combination! Ansible uses SSH connection, so it needs to have the credentials for SSH access. I'll create a YAML file, called "creds.yml" and put my credentials in there.
Next, we need an inventory file. Inventory file contains descriptions of your devices. It also allows to group your devices in an arbitrary manner and assign variables to them. For this example, I'll split my switches into groups called "coreswitches" and "edgeswitches". I'll also create a group called "switches," which will include both of the previous groups. That will come in handy if I want to perform some tasks only on core or only on edge switches.
Now to the playbook! The playbooks are written using YAML format. It is a simple markup language that is unlike XML; for example, it is very easily readable. Here is my playbook with comments:
Now, you can see, I'm using a few variables that we haven't defined yet. All these variables will go into the customer configuration files. One file per customer. And here is the first one:
Here are all of our variables and lists of variables:
a separate list for edge switch ports, having two variables per item: "sw" - switch IP address and "port" - the trunk port to add VLAN to. Same format list for coretrunks and variables for VLAN and VLAN name.
Now we've got everything in place to run the playbook. A little tweak to the default Ansible configuration file /etc/ansible/ansible.cfg to accept our local inventory file as default inventory:
And now we are ready to run our playbook:
The command to run a playbook is ansible-playbook [playbook-name]
Last thing to remember is that we still have a single undefined variable in the playbook, which is called "custfile". That is the variable we pass to Ansible during the execution, using option -e like that: ansible-playbook customer-vlan.yml -e "custfile=CUSTOMER1.yml". Let's give it a go now.
Looks promising. Just before running the playbook, I started the ping from CUST1-1 to CUST1-2, and here is the result:
Success! Let's verify our config on SW2.
VLAN is present and allowed on the correct ports. That might seem like quite a lot of work to configure single VLAN and couple of trunk ports, but guess what? To repeat this, all we need is a new customer file, so let's copy the original one and modify just VLAN number and name. Of course we could modify the edge switches and ports or core switches and ports, but since our topology is very limited, all that stays the same.
After running the command "ansible-playbook customer-vlan.yml -e "custfile=CUSTOMER2.yml" here is what we get on SW1:
The beauty of it is that it now takes much less time to execute a task, and also it reduces the error possibility. It also scales very easily to more switches and more ports.
Of course this post is not aimed at getting you proficient with Ansible. I just wanted to demonstrate its capabilities in relation to Cisco devices configuration automation. I've used it to build and re-build IGP and BGP topologies in my lab. Here are some useful links on how to use Ansible: