Skip to main content
Your first session is free. Claim mine
PacketMentor logo
Open menu
Home
Training
CCNA Library (74)
Browse all CCNA topics →
Network (13)
Device Operations (5)
Network Access (12)
Wireless (6)
IP Connectivity (10)
IP Services (11)
Security (10)
Automation (7)
CCNP Library (15)
LabsPricing
Contact 📞 +1 (860) 556-3010 Book a Call
← All topics
Automation & Programmability Foundational

Ansible for Network Engineers

Push configuration to dozens of Cisco devices from one YAML playbook. Covers inventory, modules, idempotency, and why Ansible became the default automation tool for network teams who don't want to write a custom Python script for every change.

TL;DR
  • Ansible is agentless config management — runs from your laptop, pushes to devices over SSH or API.
  • Playbooks are YAML files describing the desired state. Modules know how to make a device match that state.
  • Idempotent: running the same playbook twice doesn't change anything the second time. Safe to re-run.

Mental model

You manage 30 Cisco switches. You need to add VLAN 50 to every one of them. Two options:

  1. SSH into each manually — type the same 4 lines, 30 times, hope you don’t fat-finger anything.
  2. Run an Ansible playbook — describe the change once in YAML, push to all 30 in parallel, get a report.

Ansible is option 2. It’s agentless (you don’t install anything on the switches), declarative (you describe the end state, not the steps), and idempotent (running it twice doesn’t break anything — if VLAN 50 already exists, it just confirms and moves on).

For network engineers in 2026, Ansible is the most common starting point for automation. More approachable than writing custom Python; more powerful than scripting SSH commands.

The four core concepts

  1. Inventory — a file listing all your devices, grouped however you want (by region, by role, etc.)
  2. Playbook — a YAML file describing what you want done
  3. Module — pre-built code that knows how to talk to a specific platform (Cisco IOS, NX-OS, Junos, etc.)
  4. Task — one step in a playbook, calling one module with specific parameters

Inventory — list of devices

# inventory.yml
all:
  children:
    switches:
      hosts:
        sw1:
          ansible_host: 10.0.0.10
        sw2:
          ansible_host: 10.0.0.11
        sw3:
          ansible_host: 10.0.0.12
      vars:
        ansible_network_os: ios
        ansible_user: admin
        ansible_password: cisco123
        ansible_connection: network_cli

Anything you’d repeat (credentials, OS) goes in vars — applied to every host in the group.

Playbook — describe the change

# add-vlan-50.yml
- name: Add VLAN 50 to all switches
  hosts: switches
  gather_facts: no
  tasks:
    - name: Ensure VLAN 50 exists
      cisco.ios.ios_vlans:
        config:
          - vlan_id: 50
            name: GUEST
            state: active
        state: merged

Read aloud: “On every host in the ‘switches’ group, ensure VLAN 50 with name GUEST exists in ‘active’ state.”

Run with:

$ ansible-playbook -i inventory.yml add-vlan-50.yml

Ansible connects to all switches in parallel, checks if VLAN 50 already exists, adds it if not, reports back. Output looks like:

PLAY [Add VLAN 50 to all switches] ******

TASK [Ensure VLAN 50 exists] ************
changed: [sw1]
changed: [sw2]
ok:      [sw3]    ← already had it, no change made

PLAY RECAP *****
sw1 : ok=1  changed=1  unreachable=0  failed=0
sw2 : ok=1  changed=1  unreachable=0  failed=0
sw3 : ok=1  changed=0  unreachable=0  failed=0

Idempotency — the killer feature

Running the playbook a second time:

PLAY RECAP *****
sw1 : ok=1  changed=0
sw2 : ok=1  changed=0
sw3 : ok=1  changed=0

No changes made. The playbook checked, found the state already matched the desired state, and did nothing. This is what makes Ansible safe to re-run — and what makes “drift detection” trivial: run your playbook in --check mode and any changed line tells you the device drifted from intended config.

Common modules for Cisco gear

ModuleWhat it does
cisco.ios.ios_configPush raw config lines (universal but less idempotent)
cisco.ios.ios_vlansManage VLANs declaratively
cisco.ios.ios_interfacesInterface basics (description, enabled, mtu)
cisco.ios.ios_l3_interfacesLayer-3 settings (IP addresses)
cisco.ios.ios_static_routesStatic routes
cisco.ios.ios_commandRun any show command, capture output
cisco.ios.ios_factsGather device info (OS version, hostname, interfaces, etc.)

Prefer the declarative resource modules (ios_vlans, ios_interfaces) over raw ios_config when possible — they’re more idempotent and produce cleaner diffs.

Common mistakes

  1. Hardcoding credentials in the playbook. Use Ansible Vault (ansible-vault encrypt) or environment variables. Never commit ansible_password: secretvalue to Git.

  2. Forgetting gather_facts: no on network playbooks. Default Ansible tries to run a Python module on the target to gather facts. Network devices can’t run Python. Skip facts unless you explicitly need them via ios_facts.

  3. Using ios_config for everything. It works but generates messy diffs and can lose idempotency. Use resource modules where they exist.

  4. Running playbooks without --check first. --check (also called dry-run) shows what would change without making changes. Always preview before applying to production.

  5. Not version-controlling playbooks. Playbooks are infrastructure-as-code. Store them in Git, review changes in PRs. The whole point of automation is removing one-off manual operations.

  6. Misreading the OK count. ok=5 changed=0 means everything matched intended state. ok=5 changed=3 means 3 things were modified. failed=1 means stop and investigate.

Lab to try tonight

  1. Install Ansible on your laptop: pip install ansible (or use the official package for your OS). Also: ansible-galaxy collection install cisco.ios.
  2. Spin up two Cisco IOS devices in CML or grab a DevNet sandbox. Enable SSH + a local user.
  3. Write a minimal inventory.yml listing both devices.
  4. Write a playbook that creates VLAN 100 with name TEST on both. Run with --check first, then for real.
  5. Run the playbook a second time. Verify both hosts report changed=0.
  6. Modify the playbook to also configure an SVI for VLAN 100 with an IP. Re-run.
  7. Bonus: write a playbook that uses ios_facts to gather IOS version from each device and writes a report to a file.

Cheat strip

ConceptPlain English
InventoryList of devices, grouped
PlaybookYAML file describing desired state
ModulePre-built code for a specific task
TaskOne step calling one module
IdempotentRe-running doesn’t change unchanged things
—checkDry-run mode — show changes without applying
ansible-vaultEncrypts sensitive values in playbooks
changedTask modified the device
okTask succeeded (may or may not have changed)
failedTask hit an error — stop and investigate
Master this on a real network

Want this drilled into reflex?

1:1 weekly sessions, live feedback on your labs, and US interview prep — built around the CCNA® exam blueprint. Free first session. No card on file until you decide.

Claim my free session →

One topic per email, every fortnight

VLANs, OSPF, ACLs, subnetting, automation — written like this. Unsubscribe in one click.

We respect your inbox. One email per week, max. Unsubscribe any time.

Start typing — or browse popular topics below.

↑↓ navigate open Searches topics · labs · programs · pages