What is Ansible main blog image showing a controller pc and 3 network devices being automated with ansible

What Is Ansible

Right so what is Ansible. It gets mentioned constantly. Job adverts. Conference talks. Every “how do I start automating my network” thread online. And yet ask a lot of network engineers to actually explain what it does and why and you get a fairly vague answer.

I was the same. Kept hearing about it for about a year before I actually sat down and properly got to grips with it. Assumed it was going to be complicated. It really isn’t. Once it clicks it clicks properly.

Let’s sort it out.

Ansible architecture diagram control node with playbook connecting to multiple network devices via SSH agentless design no software on target devices clean professional automation architecture diagram that fits in with what is ansible

What Is Ansible: The Core Idea

Ansible is an automation platform that lets you describe what you want a set of devices to look like, then does the work of making them look that way.

You write a playbook – a YAML file describing the tasks you want to run. You point it at a list of devices. Ansible connects to each one, runs the tasks, reports back what happened. No installation on the target devices. No agents running in the background. Just SSH or an API, and the automation you’ve defined.

That agentless design is what makes it particularly useful for network engineers. You’re not installing software on your routers and switches. Nothing to maintain on the devices themselves. Ansible connects when it needs to, does its work, disconnects.

Open source. Developed by Red Hat. Enormous community. The collection of modules covering networking vendors is comprehensive – Cisco IOS, IOS-XE, NX-OS, Juniper Junos, Arista EOS, Palo Alto, F5. You’re rarely writing from scratch to support a platform.

Key Terms You Need to Know

Get these in your head first. They come up constantly.

Control Node – The machine where Ansible is installed and where you run playbooks from. Linux server or your workstation. Ansible doesn’t run natively on Windows though it runs fine in WSL.

Managed Nodes – The devices Ansible manages. Your routers, switches, firewalls. Nothing installed on these.

Inventory – A file listing your managed nodes organised into groups. Ansible needs to know what devices exist before it can do anything with them.

Playbook – A YAML file containing one or more plays. Where you define what you want to happen.

Play – Maps a set of tasks to a group of hosts.

Task – A single action. Run this command. Push this configuration. Check this state.

Module – The code that performs a specific action. Thousands of them covering everything from running show commands to pushing config. You call modules in your tasks.

Role – A way of organising related tasks, variables, and files into reusable structures. Matters once your playbooks get complex.

The Inventory File

The inventory is where you define what devices Ansible knows about. Simplest form is a plain text INI file:

[routers]
R1-EDGE-RTR ansible_host=192.168.100.1
R2-CORE-RTR ansible_host=192.168.100.2

[switches]

SW1-ACCESS ansible_host=192.168.100.11 SW2-ACCESS ansible_host=192.168.100.12 SW3-ACCESS ansible_host=192.168.100.13

[network:children]

routers switches

[routers:vars]

ansible_network_os=ios ansible_user=netadmin ansible_password=Linux123! ansible_connection=network_cli

[switches:vars]

ansible_network_os=ios ansible_user=netadmin ansible_password=Linux123! ansible_connection=network_cli

Groups let you run tasks against specific subsets of your inventory. children lets you create a parent group that contains other groups. The vars sections define variables applying to all hosts in a group – define credentials once rather than repeating them for every device.

In production you’d store credentials in Ansible Vault rather than plain text. For lab work, plain text is fine.

Writing a Playbook

YAML is indentation-sensitive. Consistent spacing matters. Two spaces or four spaces – just don’t mix them or you’ll get errors that take ages to track down. Learned that the hard way.

Here’s a simple playbook collecting show version output from all routers:

---
- name: Collect device information from routers
  hosts: routers
  gather_facts: no

  tasks:
    - name: Get show version output
      cisco.ios.ios_command:
        commands:
          - show version
      register: version_output

    - name: Display the output
      debug:
        var: version_output.stdout_lines

Walk through what’s happening.

Three dashes at the top – standard YAML document start.

name at play level describes what this play does. hosts tells Ansible which inventory group to target. gather_facts: no tells it not to try collecting system facts before running tasks – important for network devices which handle this differently from Linux servers.

Under tasks, each task has a name and calls a module. cisco.ios.ios_command runs arbitrary commands on Cisco IOS devices. commands is the list of what to run.

register saves the task output into a variable. debug displays it. stdout_lines gives the output as a list of lines rather than one block of text.

Run it:

ansible-playbook -i inventory.ini collect_info.yml

-i specifies the inventory file. Playbook filename follows. That simple.

Configuration Management With ios_config

Gathering output is useful but pushing configuration is where Ansible really earns its place.

Playbook adding a management VLAN to a group of switches:

---
- name: Add management VLAN to access switches
  hosts: switches
  gather_facts: no

  tasks:
    - name: Configure management VLAN
      cisco.ios.ios_config:
        lines:
          - vlan 99
          - name MANAGEMENT

    - name: Configure SVI for management VLAN
      cisco.ios.ios_config:
        lines:
          - ip address 192.168.100.0 255.255.255.0
          - no shutdown
        parents: interface Vlan99

    - name: Save configuration
      cisco.ios.ios_config:
        save_when: always

ios_config is intelligent about changes. It checks whether the configuration already exists before applying it. If VLAN 99 is already correct that task shows as ok rather than changed. Run the same playbook ten times and it only makes changes when something actually needs changing. That’s idempotency and it’s one of the things that makes Ansible safe to run repeatedly.

The parents parameter handles hierarchical configuration. Lines specified apply inside the context defined by parents. ip address and no shutdown get applied inside the interface Vlan99 block, exactly as if you’d typed interface Vlan99 first then the sub-commands.

Variables in Playbooks

Hard-coding values in playbooks causes problems the moment you want to use the same playbook for different environments. Variables sort that.

---
- name: Configure VLANs on switches
  hosts: switches
  gather_facts: no

  vars:
    vlans:
      - id: 10
        name: SALES
      - id: 20
        name: ENGINEERING
      - id: 30
        name: GUEST
      - id: 99
        name: MANAGEMENT

  tasks:
    - name: Create VLANs
      cisco.ios.ios_vlans:
        config:
          - vlan_id: "{{ item.id }}"
            name: "{{ item.name }}"
        state: merged
      loop: "{{ vlans }}"

vars section defines a list of VLANs. loop makes the task run once for each item in the list. Double curly braces are Jinja2 templating – substitutes the variable value at runtime. One task, runs four times, creates four VLANs. Much cleaner than writing four separate tasks.

Templates With Jinja2

For more complex scenarios Ansible uses Jinja2 templates. Create a template file with placeholders, define variable values per device, Ansible generates device-specific configuration by combining the two.

BGP template file (bgp_config.j2):

router bgp {{ bgp_as }}
 bgp router-id {{ router_id }}
 {% for neighbor in bgp_neighbors %}
 neighbor {{ neighbor.ip }} remote-as {{ neighbor.remote_as }}
 neighbor {{ neighbor.ip }} description {{ neighbor.description }}
 {% endfor %}

Host variables for R1-EDGE-RTR:

bgp_as: 65001
router_id: 192.168.100.1
bgp_neighbors:
  - ip: 203.0.113.1
    remote_as: 65002
    description: ISP-PRIMARY

Template gets populated with device-specific variables when the playbook runs. The for loop generates a neighbour statement for each entry in the list. One template, different output for each device. Update the template once and it propagates everywhere on the next run.

What Is Ansible Good At (and Where It Falls Short)

Good at:

  • Pushing the same change to many devices consistently
  • Enforcing a desired configuration state across your estate
  • Generating device-specific config from templates
  • Collecting show command output for auditing
  • Chaining multiple tasks in a specific order

Less ideal for:

  • Real-time monitoring and alerting – it’s pull-based, not event-driven
  • Complex conditional logic that changes significantly based on device state
  • Tasks needing very fast execution – connection handling adds overhead
  • Replacing purpose-built management platforms for day-to-day operations

YAML syntax is also particular about indentation and produces cryptic errors when something’s slightly off. Spent an hour once debugging a playbook that turned out to have one line indented with spaces and the rest with tabs. Looked identical on screen. Wasn’t. That kind of thing is annoying until you get used to checking it.

Getting Started

Install it on Linux or WSL:

pip install ansible
pip install paramiko
ansible-galaxy collection install cisco.ios

That’s enough to start automating Cisco IOS. Create a simple inventory with one or two devices. Write a playbook that runs a show command. Get it working. Add more devices and more complex tasks from there.

The learning investment pays back quickly. Once you’ve got a working playbook for a common task you’ve got it for every future occurrence of that task.


External Link: Ansible Network Automation Documentation – official Ansible docs for network automation covering all major vendor modules


What Is Ansible and How Does It Work

Leave a Reply

Your email address will not be published. Required fields are marked *

Scroll to top