Network Automation with Ansible: A Practical Starting Point

Most network automation tutorials start with a playbook that configures a VLAN. That’s fine, but it skips the part where you understand why Ansible is structured the way it is and when you should reach for something else.

Here’s a practical foundation.

Why Ansible for Networks?

Ansible uses an agentless model — it connects via SSH (or NETCONF, or HTTPS depending on the platform). No agent to install. For network devices, this is almost always the right model.

 1# inventory.yml
 2all:
 3  children:
 4    core:
 5      hosts:
 6        core-01:
 7          ansible_host: 10.0.0.1
 8          ansible_network_os: cisco.ios.ios
 9          ansible_connection: network_cli
10          ansible_user: admin

A Real Task: Collecting Interface State

 1- name: Gather interface state from core switches
 2  hosts: core
 3  gather_facts: false
 4
 5  tasks:
 6    - name: Collect interface data
 7      cisco.ios.ios_facts:
 8        gather_subset:
 9          - interfaces
10
11    - name: Show interfaces that are up
12      debug:
13        msg: "{{ item.key }}: {{ item.value.operstatus }}"
14      loop: "{{ ansible_network_resources.interfaces | dict2items }}"
15      when: item.value.operstatus == 'up'

Templates with Jinja2

Configuration rendering is where Ansible shines for networks. Keep your logic in inventory/vars, your structure in templates.

1{# templates/bgp.j2 #}
2router bgp {{ bgp_asn }}
3 bgp router-id {{ router_id }}
4 bgp log-neighbor-changes
5{% for peer in bgp_peers %}
6 neighbor {{ peer.ip }} remote-as {{ peer.asn }}
7 neighbor {{ peer.ip }} description {{ peer.description }}
8{% endfor %}
1# host_vars/core-01.yml
2bgp_asn: 65001
3router_id: 10.0.0.1
4bgp_peers:
5  - ip: 10.0.0.2
6    asn: 65002
7    description: "upstream-1"

When to Use Something Else

Ansible is great for push-based config management. It’s not great for:

  • Real-time state queries — use NAPALM or direct API calls
  • Event-driven response — use Ansible EDA or a proper event bus
  • Complex diffs with rollback — look at Nornir + NAPALM

The Mental Model

Think of Ansible for networks as: declarative intent → rendered config → pushed to device. Keep your vars clean, your templates readable, and your playbooks idempotent.