Network automation with Ansible is the key in many IT teams to make recurring switch changes, regular configuration backups and controlled rollbacks reproducible and auditable. This practical how‑to is aimed at administrators, system engineers and operators and explains, step by step, prerequisites, common pitfalls, concrete playbook examples and safe verification and fallback strategies.
Why network automation? Goals and brief definitions
Network automation reduces manual errors, accelerates rollouts and improves traceability. In this article we use Ansible as the orchestration tool. Ansible is an agentless automation tool: the control node (Ansible control node) connects via SSH or specialized network connection plugins to devices and executes declarative tasks (playbooks).
Important terms in one sentence: Playbook (YAML file with tasks), Inventory (device list), Connection plugins (e.g. network_cli for switches), idempotence (repeatability without side effects) and rollback (restoration of a previous configuration).
Brief overview of operational requirements
- Control node: Ansible 2.15+ or a modern 2.x release; Python and the required collections (e.g. ansible.netcommon, community.general, and, if applicable, vendor collections such as cisco.ios).
- Access: SSH access with sufficient privileges (optionally enable/privilege password). Network devices must be reachable from the control node.
- Inventory: Clean inventories and group_vars for credentials; manage secrets via Ansible Vault or a secrets backend (e.g. HashiCorp Vault).
- Test environment: Lab or staging with one or a few devices to validate playbooks before production rollout.
Network automation with Ansible: basic inventory structure
An auditable inventory is the foundation. Here is a simple INI example that many teams still use:
[switches]
sw-core-01 ansible_host=10.0.1.10 ansible_network_os=ios
sw-access-01 ansible_host=10.0.1.20 ansible_network_os=ios
[all:vars]
ansible_user=netadmin
ansible_connection=network_cli
ansible_become=yes
ansible_become_method=enable
Explanation: ansible_network_os helps Ansible select the appropriate module/prompt handling; network_cli is the connection plugin for CLI‑based switches. Sensitive data (passwords, SSH keys) should preferably not be kept in the inventory but managed via Vault or Ansible credential management.
Playbook: collect configuration backups
Backups are the most underestimated component. Here is a robust playbook that retrieves the running configuration and stores it locally on the control node. It uses the generic module ansible.netcommon.cli_command (works with many vendors) and saves the output via a local action.
---
- name: Collect running-config backups from switches
hosts: switches
gather_facts: no
connection: network_cli
tasks:
- name: Get running configuration
ansible.netcommon.cli_command:
command: show running-config
register: running_cfg
- name: Ensure backup directory exists on control node
local_action:
module: file
path: "backups/{{ inventory_hostname }}"
state: directory
mode: '0750'
- name: Save running configuration to control node
local_action:
module: copy
content: "{{ running_cfg.stdout[0] | default('') }}n"
dest: "backups/{{ inventory_hostname }}/{{ inventory_hostname }}-{{ ansible_date_time.iso8601_basic }}.cfg"
mode: '0640'
Why this approach? The playbook separates device data (retrieved via SSH) from backup storage (local on the control node). This simplifies validation, version control and secure archiving. Pay attention to the timestamp format (ISO8601) and secure file modes.
Verify before you start
- Verify test access: run a simple ad-hoc command:
ansible switches -m ansible.netcommon.cli_command -a "command='show version'" -i inventory.iniIf that fails, check: Ansible version, connection plugin, network access, credentials and prompt detection (timeout, enable password).
Playbook: Configuration change (Push) with Diff and Check-Mode
For change playbooks you should use module-based, idempotent approaches where possible. Many vendor collections (e.g. cisco.ios.ios_config) implement idempotent logic. If that’s not possible, use cli_config with –check or diff options.
---
- name: Deploy interface description to access switches
hosts: switches
gather_facts: no
connection: network_cli
tasks:
- name: Apply interface configuration lines
ansible.netcommon.cli_config:
lines:
- interface GigabitEthernet1/0/48
- description "PRD: uplink to router"
- switchport mode access
- switchport access vlan 100
register: cfg_result
- name: Show diff when changed
debug:
var: cfg_result.diff
Run operations first on a single test-device group, then in batches. When testing, use ansible-playbook --check --diff to minimize risk; note that not all network modules fully support check mode.
Rollback strategies: types and implementation
Rollback is not a one-click solution for all devices. There are three pragmatic approaches:
- Vendor-native restore (recommended): Use device-native functions such as configure replace (supported by many Cisco IOS-XE devices) or Junos rollbacks. These are often atomic and minimize inconsistent states.
- Push the last known-good backup: upload the backup file and apply it line by line via cli_config. This is more generally applicable but can produce inconsistent intermediate states.
- Configuration diff and selective revert: identify only the changed lines and apply selective corrections. More effort, but lower risk in heterogeneous environments.
Example: simple rollback (push stored file)
---
- name: Rollback config by pushing saved file content
hosts: switches
gather_facts: no
connection: network_cli
vars:
rollback_file: "backups/{{ inventory_hostname }}/{{ inventory_hostname }}-20260728T120000Z.cfg"
tasks:
- name: Read rollback file on control node
local_action:
module: slurp
src: "{{ rollback_file }}"
register: rollback_raw
- name: Decode rollback content
set_fact:
rollback_text: "{{ rollback_raw.content | b64decode }}"
- name: Apply rollback configuration via CLI
ansible.netcommon.cli_config:
lines: "{{ rollback_text.split('n') }}"
register: rb_result
- name: Debug apply result
debug:
var: rb_result
Warning: This method writes virtually all lines. Test this in a lab environment. Problems occur when the stored backup contains proprietary console commands, temporary interface states, or non-persistent entries.
Operational safety rules and pre-change checklist
Before any change the following checks should be automated or documented:
- Backup available and tested (see Playbook).
- Change window defined and stakeholders informed.
- Test run performed in check mode or on a staging device.
- Serial execution: roll out changes in small batches (serial: 1–5 in Ansible) to avoid mass outages.
- Validation: run automated checks after the change (Ping, BGP neighbors, VLAN membership).
- Rollback Playbook at hand and a tested RESTore procedure in place.
Common pitfalls and how to resolve them
1) Authentication and prompt issues
Symptoms: timeouts, unexpected prompts, missing enable privileges. Causes: incorrect ansible_connection, missing privilege escalation, differing prompt strings. Solution: use group_vars for ansible_become, ansible_become_password or employ SSH keys and an ad-hoc verification test with show version. Configure timeout parameters if necessary and check interactive prompt strings in ansible.cfg.
2) Lack of idempotence
If you use raw CLI commands, actions are often not idempotent (changes on every run). Prefer vendor-specific configuration modules (e.g. cisco.ios.ios_config) that perform state reconciliation. If that is not possible, implement your own comparison logic (diff before/after, hashes).
3) Parallelism leads to network disruptions
Massive simultaneous changes can violate dependencies (e.g. STP, LACP). Use Ansible’s serial in your plays or execute role-based runs via tags. Example:
- hosts: switches
serial: 3
tasks:
- name: Apply change
...
4) Incomplete backups
Some devices provide only parts of the configuration or require special commands to make changes persistent. Verify backups regularly through automated RESTore tests in a lab.
Validation and monitoring after the change
Automated checks are mandatory. Example checks that should run immediately after a change:
- ICMP reachability for critical paths.
- Neighbor status (BGP/OSPF) for adjacent routers.
- VLAN verification and port status for affected access ports.
- Observe SNMP/telemetry metrics (latency, error rates) — anomalies indicate potential issues.
A small example of how to implement a post-change check as a playbook:
---
- name: Post-change validation
hosts: switches
gather_facts: no
connection: network_cli
tasks:
- name: Check interface up status
ansible.netcommon.cli_command:
command: show interfaces status
register: intf_status
- name: Fail if critical port is down
fail:
msg: "Critical interface down on {{ inventory_hostname }}"
when: "'Gi1/0/48' in intf_status.stdout[0] and 'notconnect' in intf_status.stdout[0]"
Audit, Archivierung und Retention
Backups sollten versioniert, geprüft und archiviert werden. Empfehlenswert ist ein Ansatz mit Git‑Repository für Text‑Backups (nur für Konfigurationstexte) kombiniert mit Objekt‑Storage für Langzeitarchiv (z. B. S3). Prüfen Sie folgende Punkte:
- Integrität: regelmäßige Hash‑Checks.
- Retention‑Policy: gesetzliche/fraktionelle Aufbewahrungsfristen definieren.
- Zugriffskontrolle: wer darf RESTore auslösen? (Role‑Based Controls)
Praxisbeispiel: Minimaler Workflow für einen Change
- Playbook in Repo aktualisieren, Merge Request mit Review durchführen.
- Auf Staging‑Switch dry‑run (–check) ausführen.
- Automatisches Backup vor Change erstellen.
- Change in kleinen Batches mit Live‑Monitoring ausrollen.
- Post‑Checks automatisch laufen lassen; bei Fehlern automatisches Rollback triggern.
Troubleshooting: Wichtige Prüfsequenz
- Verbindungstest: ad‑hoc Aufgabe wie oben (show version).
- Logs prüfen: Ansible verbose Mode
-vvvzeigt SSH‑Dialog und Prompt‑Erkennung. - Prompt/Expect‑Probleme: Prüfen, ob Modulprompt (ansible_network_os) korrekt gesetzt ist.
- Timeouts: erhöhen Sie
ansible_connection_timeoutin group_vars falls nötig. - Rollback vorher testen: Spielen Sie RESTore in einer isolierten Umgebung durch.
Netzwerkautomation mit Ansible: CI/CD, Secrets und Telemetrie integrieren
Integration in CI/CD‑Pipelines macht Changes nachvollziehbar und auditierbar. Ein typischer Ablauf ist: Merge Request → automatischer Lint/Unit‑Test der Playbooks → Dry‑Run in einem Lab → Genehmigungsstufe → sequenzielles Rollout. Nutzen Sie für Secrets Ansible Vault oder ein dediziertes Secret‑System (z. B. HashiCorp Vault). Vault erlaubt dynamische Credentials und reduziert das Risiko von long‑lived Passworten.
Telemetry (z. B. gNMI, streaming telemetry, SNMP Traps) ergänzt Automatisierung mit Echtzeit‑Metriken. Nach einem Change sollten Telemetry‑Alerts automatisch mit dem Change‑Context verbunden werden (Change‑ID, Run‑ID) — so erkennen Sie, ob ein Alarm durch die Änderung verursacht wurde.
Beispiel: CI‑Step, der ein Playbook im Check‑Mode ausführt
#!/bin/bash
# CI step: run playbook in check mode and fail on changes
ansible-playbook -i inventory.ini change_playbook.yml --check --diff
if [ $? -ne 0 ]; then
echo "Check mode failed or would change devices" >&2
exit 1
fi
Atomicere Rollbacks: Vendor‑native Replace
Wenn Ihre Plattform configure replace oder ein äquivalentes atomisches Replace‑Verfahren unterstützt, nutzen Sie es. Das reduziert die Gefahr von Zwischenzuständen. Beispiel für Cisco IOS‑XEs mit einem vendor‑Modul (conceptual example):
---
- name: Atomic replace from candidate file (vendor-specific)
hosts: switches
gather_facts: no
connection: network_cli
tasks:
- name: Replace running-config atomically
cisco.ios.ios_config:
src: "backups/{{ inventory_hostname }}/candidate.cfg"
replace: yes
save_when: modified
Note: Parameter names vary by collection. Check the documentation of your vendor collection and test the procedure thoroughly in a lab environment.
Monitoraggio: Checklists, operational knowledge and best practices
Monitoring and verification mechanisms are essential for sustainable operations. Recommendations:
- Automated RESTore tests at least quarterly in an isolated environment.
- Difference checks after each backup: generate a hash (e.g., SHA256) and store it as metadata.
- Attach change context to monitoring: run ID, commit hash, operator, ticket number.
- Alert playbooks: for critical alerts automatic rollback or escalation trigger depending on policy.
Example: hash generation and metadata storage after backup:
sha256sum backups/sw-core-01/sw-core-01-20260728T120000Z.cfg > backups/sw-core-01/metadata.txt
echo "commit: $GIT_COMMIT" >> backups/sw-core-01/metadata.txt
echo "run_id: $CI_RUN_ID" >> backups/sw-core-01/metadata.txt
Emergency runbook: manual recovery and OOB access
If automatic rollback fails, a clear runbook is required. Summary:
- Check OOB console (console server, IPMI/Redfish) — secures access when the network is unreachable.
- Identify the last intact backup (check metadata: timestamp, SW version).
- Load rollback locally on the console or apply via TFTP/USB.
- Basic checks: interfaces up, routing/neighbors, critical ACLs.
- Detailed post-checks and ticket closure after confirmed success.
Conclusion: practical advice for operations
Network automation with Ansible provides transparency and speed — provided you invest in inventory hygiene, backup discipline, tested rollback procedures and a phased rollout strategy. Use vendor-specific modules where appropriate, automate validation scripts and maintain strict access and retention policies. For heterogeneous devices, pragmatic backup and selective rollback strategies are the safest option.
Concrete starting point: create a backup playbook as above, test it against a staging switch, and then expand step by step your change playbooks with check mode, diff outputs and serialized rollouts. Augment this with CI/CD, telemetry integration and regular RESTore tests to sustainably reduce operational risk.
Ansible playbooks and switch configuration are also important for this topic. The article puts these aspects into clear context and shows what matters in day-to-day operations.