What is Ansible in a network context?

Ansible is an agentless automation tool that connects to network devices over SSH (or NETCONF) and executes tasks defined in YAML files called playbooks. Unlike Python scripts using Netmiko or NAPALM, Ansible does not require any code on the managed device — it uses the device's existing SSH management plane. Playbooks describe the desired state of configuration rather than a list of imperative commands, making them repeatable and idempotent by design. The cisco.ios Ansible collection provides purpose-built modules for Cisco IOS and IOS-XE that understand the platform's configuration syntax natively.

Ansible vs Python for Network Automation

Before choosing Ansible, it's worth understanding where it sits relative to other tools. Python libraries like Netmiko provide SSH transport for sending raw CLI commands. NAPALM adds a multi-vendor abstraction layer and getter methods. Ansible sits a level above — it orchestrates tasks, manages state, and integrates with your wider infrastructure tooling (CI/CD, secrets managers, ticketing systems).

ToolApproachLearning CurveIdempotentBest For
Ansible (cisco.ios)YAML playbooks, declarativeLow–MediumYes (most modules)Config management, bulk changes, multi-team environments
Python + NetmikoSSH scripts, imperativeMediumNo (manual logic required)Custom parsing, one-off scripts, complex logic
n8n workflowsVisual node-based flowsLowDepends on designEvent-driven triggers, alert workflows, API integrations

How to Automate Cisco IOS with Ansible — 6 Steps

1
Install Ansible and the Cisco network collection
Install Ansible core via pip, then add the cisco.ios collection. The collection provides all IOS-specific modules and connection plugins needed for Cisco automation.
2
Build your inventory file with device groups
Define your Cisco devices in an INI or YAML inventory file. Group devices by role (core, distribution, access) and set the connection type to network_cli with ansible_network_os: cisco.ios.ios.
3
Write your first ios_facts playbook
Use cisco.ios.ios_facts to pull structured data from your devices — hostname, interfaces, VLANs, ARP table. This validates your inventory and connectivity before attempting any changes.
4
Use ios_config for configuration pushes
The cisco.ios.ios_config module takes a list of config lines and pushes them to devices. Use the src parameter to push a full config template rendered with Jinja2 variables per device.
5
Add error handling and check mode
Run ansible-playbook --check to preview changes without applying them. Use block and rescue sections to handle unreachable devices gracefully and send alerts on failure.
6
Schedule via cron or trigger from n8n
Wrap your backup playbook in a shell script and schedule with cron (0 2 * * * /usr/local/bin/ansible-playbook backup.yml), or trigger it from an n8n HTTP Request node for event-driven execution on config change alerts.

Inventory File Example

Below is a working INI-format inventory for a typical three-tier Cisco estate. Store credentials in Ansible Vault, not in plain text.

inventory/hosts.ini
[core_switches]
core-sw-01 ansible_host=10.0.1.1
core-sw-02 ansible_host=10.0.1.2

[distribution_switches]
dist-sw-01 ansible_host=10.0.2.1
dist-sw-02 ansible_host=10.0.2.2

[access_switches]
access-sw-01 ansible_host=10.0.3.1
access-sw-02 ansible_host=10.0.3.2
access-sw-03 ansible_host=10.0.3.3

[cisco_ios:children]
core_switches
distribution_switches
access_switches

[cisco_ios:vars]
ansible_network_os=cisco.ios.ios
ansible_connection=network_cli
ansible_user=netadmin
ansible_password={{ vault_ssh_password }}
ansible_become=yes
ansible_become_method=enable
ansible_become_password={{ vault_enable_password }}

Backup Playbook — Full Example

This playbook connects to all Cisco IOS devices, runs show running-config, and saves the output to a timestamped file per device. It's a solid first automation to run in production.

playbooks/backup_configs.yml
---
- name: Backup Cisco IOS running configurations
  hosts: cisco_ios
  gather_facts: false
  vars:
    backup_dir: "/opt/network-backups/{{ ansible_date_time.date }}"

  tasks:
    - name: Create backup directory
      file:
        path: "{{ backup_dir }}"
        state: directory
        mode: '0755'
      delegate_to: localhost
      run_once: true

    - name: Collect running configuration
      cisco.ios.ios_command:
        commands:
          - show running-config
      register: config_output

    - name: Save config to file
      copy:
        content: "{{ config_output.stdout[0] }}"
        dest: "{{ backup_dir }}/{{ inventory_hostname }}_running-config.txt"
      delegate_to: localhost

    - name: Log backup completion
      debug:
        msg: "Backup complete for {{ inventory_hostname }} — saved to {{ backup_dir }}"

ios_config Task Example

Use ios_config to push configuration changes. The module tracks what has changed and only applies lines not already present in the running config.

Example: ios_config task for NTP and logging
- name: Apply NTP and logging baseline
  cisco.ios.ios_config:
    lines:
      - ntp server 10.0.0.10 prefer
      - ntp server 10.0.0.11
      - logging host 10.0.0.20
      - logging buffered 16384
      - logging console critical
      - service timestamps log datetime msec
    save_when: modified  # only write to NVRAM if changes were made

- name: Apply interface description (loop example)
  cisco.ios.ios_config:
    parents: "interface {{ item.name }}"
    lines:
      - "description {{ item.description }}"
  loop:
    - { name: GigabitEthernet0/1, description: "Uplink to Core-SW-01" }
    - { name: GigabitEthernet0/2, description: "Uplink to Core-SW-02" }

Frequently Asked Questions

What Ansible modules work with Cisco IOS?
The main modules are in the cisco.ios collection: ios_facts, ios_command, ios_config, ios_vlans, ios_interfaces, ios_bgp_global, ios_acls, and ios_banner. These cover the vast majority of day-to-day Cisco IOS automation tasks. For IOS-XE, the same collection works. For NX-OS, use cisco.nxos.
Is Ansible better than Python for network automation?
It depends on the task. Ansible is better for idempotent configuration management, bulk changes across many devices, and teams without strong Python skills. Python (Netmiko/NAPALM) is better for complex parsing logic, custom data transformation, and one-off scripts. Many production teams use both — Ansible for config pushes and Python for pre/post validation scripts.
Can Ansible configure Juniper and Cisco from the same playbook?
Yes. Ansible has dedicated collections for both: cisco.ios, cisco.nxos, and cisco.iosxr for Cisco platforms, and junipernetworks.junos for Junos. You can manage mixed-vendor environments from the same control node. Use when: ansible_network_os == 'cisco.ios.ios' conditions to route tasks by platform within a single play.
Does Ansible require an agent on network devices?
No. Ansible is completely agentless. For network devices, it connects via SSH using the network_cli connection plugin, or via NETCONF for devices that support it. No software needs to be installed on your Cisco switches or routers — it uses the device's existing management SSH service.

Free Cisco Config Templates

Download production-ready Cisco IOS configuration templates — hardened baselines, NTP/syslog standards, access layer configs — free from our template catalog.

Browse Free Templates →