Red Hat Ansible for Networking Automation – 2 of 2

October 16, 2018

Tweet This: 
Share on LinkedIn:  

By Taylor Owen, Kovarus Automation Solution Architect

In part 1 of this blog we talked about Red Hat Ansible at a high-level, how it is quickly being adopted, and ways of potentially increasing the performance of Ansible. In this 2nd part we will dive deeper into Ansible in regard to network automation.

From my professional experiences thus far, Ansible is THE best choice for network automation, especially in a mixed vendor environment. Currently, Ansible supports over 40 different network platforms. Some of those include, Cisco IOS, Cisco NX-OS, Juniper JUNOS, F5 BIG-IP, Palo Alto Networks PAN-OS, etc. You can find the most recent list here https://docs.ansible.com/ansible/latest/modules/list_of_network_modules.html to check to see if your platforms are currently supported.

The amount of effort that the Ansible team is putting towards network automation and configuration management can be seen in the following graph:

Ansible Network Adoption over Releases

As you can see there has been a lot of growth the past two years in terms of Ansible’s support against network devices. I don’t think this is any accident either. More people are seeing the need to automate network devices, I’m sure that’s why you’re reading this now.

There are some nuances when using Ansible for networking versus Ansible for hosts. The first one being the connection to the device. For Ansible to execute tasks directly on the host, the host needs to have Python installed. For most networking devices this is not possible to do. To work around this limitation Ansible uses itself as a proxy for the tasks to be executed against and then eventually executing the action on the remote network device. Here is a visual representation of this.


local vs. remote execution

The way to invoke this connection method depends on the “ansible_connection” variable. The value of this variable depends on the type of network device that is being managed. For managing Cisco devices the value would be “network_cli,” Juniper devices it would be “netconf,” Palo Alto Networks devices “local,” etc. for some examples. There are times when the connection method will have to be changed in the middle of a playbook. We will have an example of this later to refer to.

To make things slightly more confusing there is another Ansible variable that needs to be set so the Ansible connection plugins know what type of device it is trying to configure. This variable name is “ansible_network_os.” Some example values for this are nxos, ios, junos, etc. With these two variables defined and what their roles are, let’s look at an example playbook.

For this example we’re going to be enabling NETCONF and then backing up the device configuration to the Ansible control node’s local disk. The majority of Juniper management using Ansible is done with NETCONF, but if NETCONF isn’t enabled how do I use “netconf” for my “ansible_connection” value? This is where we have to momentarily switch the connection variable during the playbook run. Here is the example playbook:

As you can see in the first task, we have to enable NETCONF. We do this by overriding the connection of “netconf” with “local” for that single task. This allows the Ansible control host to SSH into the Juniper device to enable the NETCONF API prior to issuing commands against the API to dump the configuration. Before executing this playbook there are dependencies needed to be installed. Specifically the role “juniper.junos” needs to be downloaded from Ansible Galaxy and there are some python libraries also needed to support the role execution. These dependencies can be found in the Read Me for the role.

The next thing to discuss is how to provide all of these connection and network variables when there is a mixed environment. This is where the directory layout becomes important. The current best practice for this is found here: https://docs.ansible.com/ansible/latest/user_guide/playbooks_best_practices.html. As you can see there are directories named “group_vars” and “host_vars.” There are also a couple inventory files named “production” and “staging.” First let’s look at an example inventory file which we will name “production”.

In this example file we have 4 groups. The groups “juniper,” “cisco_ios,” and “cisco_nxos” are included in the group named “switches.” These group names can corelate to files under the “group_vars” directory. As such:

group_vars/
├── switches
├── cisco_ios.yml
├── cisco_nxos.yml
└── juniper.yml

These yaml files are where we place the variables needed for each individual switch platform. Here is an example of what the cisco_ios.yml file looks like:

Sorry to throw a little bit of a curve ball here, but as you can see I introduced a couple new variables. If you’re familiar with Cisco, depending on the privilege level a user has, one has to go into “enable” mode to look at or do configurations. The three new variables tell Ansible how to handle this specific use case. The variable “ansible_become” lets Ansible know it has to escalate its privilege after logging in. The variable “ansible_become_method” tells Ansible how to do that, and the “ansible_become_pass” is the password used to protect the enable mode on the switch.

Now if we switch the “hosts” parameter to just “switches” we include all of our individual switches with their associated variables needed to manage that switch.

We also have a way to tell Ansible which tasks are relevant to which switch due to the “ansible_network_os” variable.

When this playbook is run, the tasks are only run on Juniper devices, and all other devices are skipped. As you can see this is where things start to get a little complicated, and typically need to start being refactored into Ansible roles. As an example, I’ve written a role used to backup network devices. It can be found here https://github.com/kovarus/ansible-role-networkbackup. This role can be used to backup configurations on Cisco IOS, Cisco NX-OS, Juniper JUNOS, and Palo Alto Networks PAN-OS devices. If you have issues with the role please feel free to submits issues against the GitHub repository.

I hope that this blog was helpful for getting started with managing network devices. If more help is needed please contact us and let them know that Taylor Owen sent you. Kovarus can help by providing professional services to start guiding you down the path of automation. Please see our website for more details or email us at sales@kovarus.com.