O'Reilly logo

Network Automation with Ansible by Jason Edelman

Stay ahead with the world's most comprehensive technology and business learning platform.

With Safari, you learn the way you learn best. Get unlimited access to videos, live online training, learning paths, books, tutorials, and more.

Start Free Trial

No credit card required

Chapter 4. Network Task Automation with Ansible

This report is gradually getting more technical in two areas. The first area is around the details and architecture of Ansible, and the second area is about exactly what types of tasks can be automated from a network perspective with Ansible. The latter is what we’ll take a look at in this chapter.

Automation is commonly equated with speed, and considering that some network tasks don’t require speed, it’s easy to see why some IT teams don’t see the value in automation. VLAN configuration is a great example because you may be thinking, “How fast does a VLAN really need to get created? Just how many VLANs are being added on a daily basis? Do I really need automation?”

In this section, we are going to focus on several other tasks where automation makes sense such as device provisioning, data collection, reporting, and compliance. But remember, as we stated earlier, automation is much more than speed and agility as it’s offering you, your team, and your business more predictable and more deterministic outcomes.

Device Provisioning

One of the easiest and fastest ways to get started using Ansible for network automation is creating device configuration files that are used for initial device provisioning and pushing them to network devices.

If we take this process and break it down into two steps, the first step is creating the configuration file, and the second is pushing the configuration onto the device.

First, we need to decouple the inputs from the underlying vendor proprietary syntax (CLI) of the config file. This means we’ll have separate files with values for the configuration parameters such as VLANs, domain information, interfaces, routing, and everything else, and then, of course, a configuration template file(s). For this example, this is our standard golden template that’s used for all devices getting deployed. Ansible helps bridge the gap between rendering the inputs and values with the configuration template. In less than a few seconds, Ansible can generate hundreds of configuration files predictably and reliably.

Let’s take a quick look at an example of taking a current configuration and decomposing it into a template and separate variables (inputs) file.

Here is an example of a configuration file snippet:

hostname leaf1
ip domain-name ntc.com
!
vlan 10
   name web
!
vlan 20
   name app
!
vlan 30
   name db
!
vlan 40
   name test
!
vlan 50
   name misc

If we extract the input values, this file is transformed into a template.

Note

Ansible uses the Python-based Jinja2 templating language, thus the template called leaf.j2 is a Jinja2 template.

Note that in the following example the double curly braces denote a variable.

The resulting template looks like this and is given the filename leaf.j2:

!
hostname {{ inventory_hostname }}
ip domain-name {{ domain_name }}
!
!
{% for vlan in vlans %}
vlan {{ vlan.id }}
  name {{ vlan.name }}
{% endfor %}
!

Since the double curly braces denote variables, and we see those values are not in the template, they need to be stored somewhere. They get stored in a variables file. A matching variables file for the previously shown template looks like this:

---
hostname: leaf1
domain_name: ntc.com
vlans:
  - { id: 10, name: web }
  - { id: 20, name: app }
  - { id: 30, name: db }
  - { id: 40, name: test }
  - { id: 50, name: misc }

This means if the team that controls VLANs wants to add a VLAN to the network devices, no problem. Have them change it in the variables file and regenerate a new config file using the Ansible module called template. This whole process is idempotent too; only if there is a change to the template or values being entered will a new configuration file be generated.

Once the configuration is generated, it needs to be pushed to the network device. One such method to push configuration files to network devices is using the open source Ansible module called napalm_install_config.

The next example is a sample playbook to build and push a configuration to network devices. Again, this playbook uses the template module to build the configuration files and the napalm_install_config to push them and activate them as the new running configurations on the devices.

Even though every line isn’t reviewed in the example, you can still make out what is actually happening.

Note

The following playbook introduces new concepts such as the built-in variable inventory_hostname. These concepts are covered in Chapter 6.

---

  - name: BUILD AND PUSH NETWORK CONFIGURATION FILES
    hosts: leaves
    connection: local
    gather_facts: no

    tasks:
      - name: BUILD CONFIGS
      template:
        src=templates/leaf.j2
        dest=configs/{{inventory_hostname }}.conf

      - name: PUSH CONFIGS
        napalm_install_config:
          hostname={{ inventory_hostname }}
          username={{ un }}
          password={{ pwd }}
          dev_os={{ os }}
          config_file=configs/{{ inventory_hostname }}.conf
          commit_changes=1
          replace_config=0

This two-step process is the simplest way to get started with network automation using Ansible. You simply template your configs, build config files, and push them to the network device—otherwise known as the BUILD and PUSH method.

Note

Another example like this is reviewed in much more detail in “Ansible Network Integrations”.

Data Collection and Monitoring

Monitoring tools typically use SNMP—these tools poll certain management information bases (MIBs) and return data to the monitoring tool. Based on the data being returned, it may be more or less than you actually need. What if interface stats are being polled? You are likely getting back every counter that is displayed in a show interface command. What if you only need interface resets and wish to see these resets correlated to the interfaces that have CDP/LLDP neighbors on them? Of course, this is possible with current technology; it could be you are running multiple show commands and parsing the output manually, or you’re using an SNMP-based tool but going between tabs in the GUI trying to find the data you actually need. How does Ansible help with this?

Being that Ansible is totally open and extensible, it’s possible to collect and monitor the exact counters or values needed. This may require some up-front custom work but is totally worth it in the end, because the data being gathered is what you need, not what the vendor is providing you. Ansible also provides intuitive ways to perform certain tasks conditionally, which means based on data being returned, you can perform subsequent tasks, which may be to collect more data or to make a configuration change.

Network devices have A LOT of static and ephemeral data buried inside, and Ansible helps extract the bits you need.

You can even use Ansible modules that use SNMP behind the scenes, such as a module called snmp_device_version. This is another open source module that exists within the community:

  - name: GET SNMP DATA
    snmp_device_version:
      host=spine
      community=public
      version=2c

Running the preceding task returns great information about a device and adds some level of discovery capabilities to Ansible. For example, that task returns the following data:

{"ansible_facts": {"ansible_device_os": "nxos", "ansible_device_vendor": "cisco", "ansible_device_version": "7.0(3)I2(1)"}, "changed": false}

You can now determine what type of device something is without knowing up front. All you need to know is the read-only community string of the device.

Migrations

Migrating from one platform to the next is never an easy task. This may be from the same vendor or from different vendors. Vendors may offer a script or a tool to help with migrations. Ansible can be used to build out configuration templates for all types of network devices and operating systems in such a way that you could generate a configuration file for all vendors given a defined and common set of inputs (common data model). Of course, if there are vendor proprietary extensions, they’ll need to be accounted for, too. Having this type of flexibility helps with not only migrations, but also disaster recovery (DR), as it’s very common to have different switch models in the production and DR data centers, maybe even different vendors.

Configuration Management

As stated, configuration management is the most common type of automation. What Ansible allows you to do fairly easily is create roles to streamline the consumption of task-based automation. From a high level, a role is a logical grouping of reusable tasks that are automated against a particular group of devices. Another way to think about roles is to think about workflows. First and foremost, workflows and processes need to be understood before automation is going to start adding value. It’s always important to start small and expand from there.

For example, a set of tasks that automate the configuration of routers and switches is very common and is a great place to start. But where do the IP addresses come from that are configured on network devices? Maybe an IP address management solution? Once the IP addresses are allocated for a given function and deployed, does DNS need to be updated too? Do DHCP scopes need to be created?

Can you see how the workflow can start small and gradually expand across different IT systems? As the workflow continues to expand, so would the role.

Compliance

As with many forms of automation, making configuration changes with any type of automation tool is seen as a risk. While making manual changes could arguably be riskier, as you’ve read and may have experienced firsthand, Ansible has capabilities to automate data collection, monitoring, and configuration building, which are all “read-only” and “low risk” actions. One low risk use case that can use the data being gathered is configuration compliance checks and configuration validation. Does the deployed configuration meet security requirements? Are the required networks configured? Is protocol XYZ disabled? Since each module, or integration, with Ansible returns data, it is quite simple to assert that something is TRUE or FALSE. And again, based on it being TRUE or FALSE, it’s up to you to determine what happens next—maybe it just gets logged, or maybe a complex operation is performed.

Reporting

We now understand that Ansible can also be used to collect data and perform compliance checks. The data being returned and collected from the device by way of Ansible is up for grabs in terms of what you want to do with it. Maybe the data being returned becomes inputs to other tasks, or maybe you just want to create reports. Being that reports are generated from templates combined with the actual important data to be inserted into the template, the process to create and use reporting templates is the same process used to create configuration templates.

From a reporting perspective, these templates may be flat text files, markdown files that are viewed on GitHub, HTML files that get dynamically placed on a web server, and the list goes on. The user has the power to create the exact type of report she wishes, inserting the exact data she needs to be part of that report.

It is powerful to create reports not only for executive management, but also for the ops engineers, since there are usually different metrics both teams need.

With Safari, you learn the way you learn best. Get unlimited access to videos, live online training, learning paths, books, interactive tutorials, and more.

Start Free Trial

No credit card required