Network Computing is part of the Informa Tech Division of Informa PLC

This site is operated by a business or businesses owned by Informa PLC and all copyright resides with them. Informa PLC's registered office is 5 Howick Place, London SW1P 1WG. Registered in England and Wales. Number 8860726.

Ansible for Network Automation Tutorial

Ansible is an automation tool or platform, which is available as open source, and used to configure devices such as routers, switches, and various types of servers. Ansible's primary purpose is to configure three main type of tasks:

  • Configuration management: This is used to fetch and push configs on various devices that we call as inventory in Ansible. Based upon the type of inventory, Ansible is capable of pushing in bulk specific or full configs.
  • Application deployment: In server scenarios, many a time we need to bulk deploy some specific applications or patches. Ansible takes care of that as well as bulk uploading patches or applications on the server, installing on them, and even configuring the applications of a particular task. Ansible can also take care of customizing settings based upon the devices in the inventory.
  • Task automation: This is a feature of Ansible that performs a certain written task on a single device or a group of devices. The tasks can be written and Ansible can be configured to run those tasks once or on a periodic basis.

Another powerful feature of Ansible is IT or infrastructure orchestration. To explain this in detail, let us say we need to code upgrade certain routers or network devices. Ansible can perform sequential steps to isolate the particular router, push code, update code, and then move on to next router based upon the return values of the previous result or task.

Basic requirements of Ansible

Ansible is very easy to install and set up. It works on a controller and managed nodes model. In this model, Ansible is installed on a controller, which is a Linux server, and has access to all the inventory or nodes that we want to manage. As we have seen, Ansible is supported on Linux (there is a beta version out there for the Windows controller but it's not yet fully supported), and it relies on the SSH protocol to communicate with nodes. So, apart from the configuration of the controller, we need to ensure the nodes that are going to be managed are SSH capable.

There is an additional requirement of Python being installed on the managed nodes, since multiple Ansible modules are written in Python and Ansible copies the module locally to the client and executes it from the node itself. In servers running Linux this is already met, however, in network devices such as Cisco IOS, this might not be a possibility as Python is not available on the Cisco node.

To overcome this limitation, there is something called a raw module that executes raw commands, like show version to fetch the output from the Cisco device. This might not help a lot, but there is another way in which Ansible can be made to run its modules on the server itself, rather than executing those modules on the client (or managed node). This ensures that modules use the resources of the Ansible server (including Python), and they can call the SSH or HTTP APIs of Cisco vendors to perform tasks that are configured locally on the server. Even SNMP can also be used for devices that don't have a good set of APIs (such as Cisco IOS), to perform our tasks.

As we have seen earlier, SNMP can be used in both read and write mode, so using Ansible and running the module locally, we can even configure old IOS devices with the assistance of the SNMP protocol.

Installation of Ansible

An Ansible controller (the main component that manages the nodes), is supported on multiple flavors of Linux, but it cannot be installed on Windows.

For managed nodes, the core requirement is anything with Python 2.6 and above. Additionally, since Ansible uses SSH to communicate with managed nodes, the node must be able to be accessed from SSH. For any file transfers, the default is SSH File Transfer Protocol (SFTP), but there is always an option to use scp for the default file transfer protocol. This being said, as mentioned earlier, if Python installation is not possible, then we would be using the raw modules of Ansible running from the server itself.

Going back to controller machine installation, Python 2 (2.6 or above) needs to be installed. In our case, we are using Ubuntu as our OS, hence our focus would be on working with Ansible using Ubuntu as the underlying OS. A way of installing Ansible is to use the Advanced Packaging Tool (APT) in Ubuntu. The following commands will configure the Personal Package Archives (PPA) and install Ansible.

Here are the basic commands, in the same order they are needed for the installation of Ansible:

$ sudo apt-get update

$ sudo apt-get install software-properties-common

$ sudo apt-add-repository ppa:ansible/ansible

$ sudo apt-get update

$ sudo apt-get install ansible

In our case Ansible is already installed. Here is a sample output that we get if we run the command sudo apt-get install ansible again. In this case if there is a new update available, Ansible will upgrade to the latest version, otherwise it would exit out of the command stating that we already have the newest version as shown in the following screenshot):

 

Another way of installing Ansible is by using our well known Python library installation command pip. The command for this will be:

pip install --user ansible

Once the installation is done, here is the information about the folder:

 

The hosts file is the inventory file where we add our managed nodes to be controlled by Ansible. ansible.cfg is the actual configuration file used to tweak Ansible parameters. Once the installation is done, we need to add some nodes in the hosts file. In our case as a fresh installation, we need to add our localhost (127.0.0.1). This node is accessible from SSH with the username abhishek and password abhishek.

Here is a sample output of our /etc/hosts file:

 

Note: The line 127.0.0.1 ansible_connection=ssh ansible_user=abhishek ansible_ssh_pass=abhishek is where we specify the parameters that are needed to access this system.

We can use any text editor (in our case we are using nano or the vi editor) to add or modify the changes to these files. To modify the hosts file, we use the following command:

$ sudo nano /etc/ansible/hosts

The next step is to verify the accessibility/reachability of the nodes that we added into the hosts file, which can be done using the ansible all -m ping command as shown in the following screenshot:

 

As we can see in the previous screenshot, the command ansible all -m ping pings all the configured nodes in the hosts file and responds with a ping. Additionally, in the same output, if we use the command ansible all -m ping --ask-pass, this asks for a password to be accessed for that particular node. In our case, we give the password, and then we get the response back. Now, you might ask: I am performing a simple ping, so what is the need for SSH now in this case?

Let us add the global DNS server (4.2.2.2) in our hosts file and then test it as shown in the following screenshot. As mentioned earlier, we invoke the nano editor using sudo nano /etc/ansible/hosts:

(Click on image for larger view)

Once done, we try to perform the same ping test again:

(Click on image for larger view)

What do we see now? Even though I can easily ping 4.2.2.2 from my machine, Ansible returns the value of false, since Ansible first tries to log in to the device using SSH and then tries to ping the IP. In this case, 4.2.2.2 SSH is not open, and we get a failure message for that specific IP address from Ansible. Additionally, we can group the managed objects under a specific name, such as routers, switches, servers, or whatever name we like in the hosts file.

Consider the following example:

We group our current IPs (localhost and 4.2.2.2) under a new group, myrouters. We go back and modify the file /etc/ansible/hosts for this:

 

Notice the addition of the myrouters group in the file. Once we save it, let's now use the group to perform a ping task:

(Click on image for larger view)

As we see now, instead of pinging all, we just ping the group myrouters, which in our case is the loopback IP and 4.2.2.2.

Of course, results will be the same as earlier, but now we have the added flexibility of ensuring that we perform our tasks based upon either individual nodes or a group of nodes under a specific name.

This tutorial is an excerpt from "Practical Network Automation" by Abhishek Ratan and published by Packt. Use the code ORNCB50 at checkout to save 50% on the recommended ebook retail price until March 11.