Kahibaro
Discord Login Register

21.6 Ansible

Introduction

Ansible is a tool that lets you describe how systems should look, then automatically makes them match that description. Instead of logging into devices one by one and typing commands, you write simple text files and let Ansible do the work for many machines at once. It is very popular in networking because it is agentless, which means network devices do not need any special software installed to be managed.

This chapter focuses on what is unique to Ansible in the context of network automation, how it works at a high level, and how you describe network configuration using Ansible concepts.

Core Ideas of Ansible

Ansible is built around a few key ideas. You connect to devices over common protocols like SSH or API, you describe the desired state in YAML files, and Ansible translates those descriptions into actions on the devices.

From a networking perspective, the most important idea is that Ansible is state based. You say “this VLAN should exist” or “this route should be present” rather than giving a long list of commands. Ansible checks the current state of the device and only changes what is necessary.

Key idea: With Ansible you describe desired state, not just commands. Ansible then makes the actual configuration match that desired state, and does so idempotently.

Idempotent means that running the same play multiple times results in the same configuration without adding duplicates or breaking things.

Inventory and Groups

Ansible needs to know which devices to manage. It gets this information from an inventory. For networks, the inventory usually contains routers, switches, firewalls, load balancers, wireless controllers, and sometimes servers that participate in the network.

A very simple inventory file in INI style might look like:

ini
[core_switches]
core-sw1 ansible_host=192.0.2.10
core-sw2 ansible_host=192.0.2.11
[edge_routers]
edge-r1 ansible_host=198.51.100.1
edge-r2 ansible_host=198.51.100.2

Here the names like core-sw1 are logical hostnames used by Ansible. The variable ansible_host gives the IP to connect to. You can group devices logically by role or location, which makes it easy to target a whole class of devices in one operation, for example “all core switches” or “all edge routers.”

In network automation, inventories are often hierarchical. You can nest groups such as “all routers,” inside that “edge routers” and “core routers,” or “datacenter1-switches” and “datacenter2-switches.” This structure allows you to assign variables at different levels, such as a common NTP server for all network devices, but different VLAN lists per site.

Dynamic inventories are also common in more advanced setups. These are inventories that Ansible builds on the fly by querying controllers, IPAM systems, clouds, or source of truth databases. For a beginner, it is enough to understand that the inventory is where Ansible discovers which network devices to manage and how to connect to them.

Playbooks and Plays

Ansible executes actions through playbooks. A playbook is a YAML file that describes one or more plays. A play answers two questions: which hosts should be targeted, and what should be done on them.

A minimal example targeting core switches might look like:

yaml
- name: Configure core switches
  hosts: core_switches
  gather_facts: no
  tasks:
    - name: Ensure VLAN 10 exists
      cisco.ios.ios_vlans:
        vlan_id: 10
        name: USERS
        state: present

You can see that the play has a name, specifies hosts: core_switches, and has a list of tasks. Each task calls a module with parameters. Even though this example uses a Cisco specific module, the pattern is the same for other vendors.

The key point for networking is that you usually turn off default system fact gathering, because network devices are not standard servers. Instead, you may gather device specific facts with dedicated network modules when needed.

In practice, network playbooks are often structured by function, for example one playbook for “base configuration,” another for “routing configuration,” another for “access ports,” and so on. This keeps your network automation clear and easier to maintain.

Modules for Network Devices

Ansible does actual work through modules. A module is a piece of code that performs a specific function, such as configuring interfaces, VLANs, routing protocols, or ACLs. For networks, there are two broad categories: network vendor specific modules, and generic network modules.

Vendor specific collections include modules like cisco.ios.ios_interfaces, arista.eos.eos_l3_interfaces, junipernetworks.junos.junos_config, and many others. Each one understands the syntax and behavior of a particular network operating system.

Generic modules such as ansible.netcommon.cli_config or ansible.netcommon.network_cli can push configuration or run commands in a more general way, often used when a dedicated module does not exist or when you need to run show commands and collect output.

A crucial benefit of network modules is that they try to be idempotent. For example, a VLAN module will check if the VLAN already exists and only add it if needed. A route module will compare the existing routing table entries and apply only missing routes.

Always prefer network aware modules over raw command pushes. Network modules understand current state, avoid duplicate changes, and help keep playbooks idempotent.

Because every vendor is different, you usually work with specific collections that include all the modules, connection plugins, and utilities for that platform.

Variables and Templates in Network Context

Variables in Ansible allow you to describe network configuration in a flexible way. Instead of hardcoding IP addresses, VLAN IDs, or interface names inside tasks, you place them into variables and reuse them.

For example, you might define variables for a site like:

yaml
site_name: branch1
vlans:
  - id: 10
    name: USERS
  - id: 20
    name: VOICE
ntp_servers:
  - 192.0.2.50

Then your tasks loop over these variables to create VLANs or apply NTP settings on multiple devices at that site. This makes it trivial to create another site with similar structure but different IDs and addresses, without rewriting logic.

Jinja2 templates are heavily used with network devices. A template is a text file that mixes static content with variable placeholders and simple logic such as loops and conditionals. For example, you can generate an interface configuration section by looping over a list of interfaces and inserting descriptions, VLANs, or IP addresses.

The typical pattern in network automation is to use templates when you need to generate configuration blocks that follow a structured and repeating pattern, such as access interfaces, port channels, or BGP neighbors. Ansible then pushes the rendered configuration to the device using a module that supports configuration updates.

Connection Methods Specific to Networks

Unlike servers where SSH is almost always enough, network devices use a mix of CLI over SSH, NETCONF, REST APIs, and vendor specific protocols. Ansible supports these through connection plugins.

Some common network connection types include:

Connection typeTypical use
network_cliCLI over SSH for many vendors
netconfNETCONF based devices
httpapiDevice or controller REST or HTTP APIs
localIndirect calls, for example to controllers

In your inventory or play, you tell Ansible which connection to use. For example:

yaml
- name: Configure IOS switches
  hosts: core_switches
  connection: network_cli
  tasks:
    ...

Network automation often requires extra variables such as ansible_network_os to indicate the device platform, which lets Ansible load the correct set of modules and behaviors. You usually need to configure device accounts, privilege levels, and possibly command prompts so Ansible can recognize when a command has completed.

Idempotence and Check Mode for Network Changes

Idempotence is especially important in networking, since small mistakes can have large impact. Ansible modules for network devices are designed to run multiple times without causing repeated changes or duplicate lines, as long as you use them correctly.

Many modules also support check mode. In check mode, Ansible simulates changes and shows what it would do, without actually changing the configuration. This is very useful before executing large, wide reaching changes on core devices.

You can run a playbook in check mode with:

bash
ansible-playbook playbook.yml --check

For network devices, check mode may not be perfect, and some modules do not support it fully, but it is still an important safety feature.

Before wide or risky network changes, run playbooks in check mode where supported. Use idempotent, state aware modules to avoid repeated or conflicting configuration.

In addition to check mode, you can use diff mode for modules that support it, in order to see the difference between current and desired configuration. This helps to understand exactly what Ansible will change on each device.

Organizing Network Automation with Roles

As your network automation grows, a single playbook becomes hard to maintain. Ansible introduces roles to structure your configuration. A role bundles related tasks, variables, templates, and files into a well defined directory layout.

For example, you might have roles such as base_config, routing, access_switch, core_switch, or firewall_policy. Each role contains the specific logic to configure that function. A playbook then simply assigns roles to host groups, such as applying the core_switch role to all core switches.

This layout is especially useful in networking, since many devices share base configuration like management interfaces, logging, NTP, and AAA, while having unique parts like different VLANs or routing peers. You can put common behavior in shared roles and fine tune with per group or per host variables.

Roles also make it easier to reuse your network automation across projects or customers, because they form portable building blocks that can be shared and version controlled.

Ansible Collections for Network Vendors

In modern Ansible, vendor specific content is packaged into collections. A collection is a bundle of modules, plugins, roles, and documentation for a particular family of devices or a specific domain.

For network engineers, collections such as cisco.ios, cisco.nxos, arista.eos, junipernetworks.junos, and many others provide the primary tools for interacting with those platforms. Each collection defines the right modules, connection types, and data models for its target devices.

Installing a collection is usually done with a command like:

bash
ansible-galaxy collection install cisco.ios

In your playbooks you then refer to modules using their fully qualified names, for example cisco.ios.ios_interfaces. This keeps things clear and consistent, especially when you use multiple vendors in the same automation environment.

Collections also help with versioning and compatibility. You can pin a particular collection version that you know works with your devices and your Ansible version, which is an important aspect of stable network automation.

Testing and Safety for Network Playbooks

Network changes can affect many users at once, so safe practices with Ansible are crucial. Before running playbooks on production devices, it is common to test them in a lab or virtual environment that mimics the real network as closely as possible.

You might use virtual network devices, emulators, or software labs to run your Ansible playbooks and verify that configurations are correct. Once validated, you apply them to production devices in stages, for example one site at a time or a subset of devices first.

Ansible supports tags, which let you run only a subset of tasks, such as ntp or vlans. This is useful when you want to make very targeted changes without touching other parts of the configuration. You can also combine tags with inventory groups to carefully control where a change is applied.

Version control for playbooks, roles, and inventory is also common. By storing your Ansible content in a system like Git, you can track changes, roll back versions, and review modifications through pull requests, which provides extra safety and visibility for network teams.

Conclusion

Ansible gives network engineers a way to describe network configuration as code in simple, readable files, then apply those configurations repeatedly and consistently across many devices. The key elements are the inventory that lists devices, playbooks that describe actions, modules that implement vendor specific logic, variables and templates that make configurations flexible, and collections that package vendor ecosystems.

By understanding these Ansible fundamentals in a networking context, you gain a foundation for building more advanced, automated workflows that reduce manual effort, increase reliability, and help keep network configurations consistent and predictable.

Views: 44

Comments

Please login to add a comment.

Don't have an account? Register now!