Ansible for Network Engineers
Ansible has become the de-facto standard for network automation in the enterprise. It is agentless, human-readable (YAML), and powerful enough to manage thousands of devices from a single control node.
1. Why Ansible? (The Business Case)
Before diving into the code, it's crucial to understand why enterprises choose Ansible over Python scripts or manual CLI.
- Agentless Architecture: You do not need to install software on your Cisco routers or switches. Ansible connects via standard SSH (NETCONF/CLI).
- Idempotency: A critical concept. If you run a playbook twice, Ansible checks the state first. If the configuration is already present, it does nothing. This prevents downtime caused by re-applying commands.
- Inventory Management: It separates the "What" (Playbooks) from the "Where" (Inventory). You can run the same compliance check against 1 device or 10,000 devices without changing the code.
- Vendor Agnostic: The same playbook structure works for Cisco, Juniper, Arista, and F5. You just swap the modules (e.g.,
cisco.ios.ios_configvsarista.eos.eos_config).
2. Deployment Guide: Setting up the Control Node
Ansible runs on a Linux server (Control Node). It is not officially supported on Windows (though WSL works). Here is how to build a production-ready environment on Ubuntu/Debian.
Step 1: Install System Dependencies
sudo apt update && sudo apt install -y python3-pip python3-venv git sshpass
Step 2: Create a Virtual Environment
Always isolate your Ansible environment to avoid conflicting Python libraries.
python3 -m venv ansible-venv
source ansible-venv/bin/activate
Step 3: Install Ansible & Network Collections
Core Ansible is barebones. You need the specific collections for network gear.
pip install ansible paramiko
ansible-galaxy collection install cisco.ios
ansible-galaxy collection install cisco.nxos
ansible-galaxy collection install vyos.vyos
3. The Inventory File
The inventory defines your network estate. It can be a static file (INI/YAML) or dynamic (pulled from NetBox/ServiceNow).
hosts.yml (Static Example)
all:
children:
core_routers:
hosts:
rtr-core-01:
ansible_host: 192.168.1.1
rtr-core-02:
ansible_host: 192.168.1.2
access_switches:
hosts:
sw-access-01:
ansible_host: 192.168.2.10
vars:
ansible_network_os: cisco.ios.ios
ansible_user: admin
ansible_ssh_pass: SecretPassword123!
ansible_connection: network_cli
Never hardcode passwords in plain text! Use Ansible Vault to encrypt sensitive variables: ansible-vault encrypt_string 'MySecretPass' --name 'ansible_ssh_pass'.
4. Anatomy of a Playbook
Playbooks are written in YAML. They define a list of "Plays", which contain "Tasks".
Example 1: The "Hello World" (Backup Configs)
This playbook logs into every router, runs show run, and saves the output to a file with a timestamp.
---
- name: Daily Configuration Backup
hosts: all
gather_facts: no
tasks:
- name: Gather Running Configuration
cisco.ios.ios_command:
commands: show running-config
register: config_output
- name: Save to File
copy:
content: "{{ config_output.stdout[0] }}"
dest: "./backups/{{ inventory_hostname }}_{{ ansible_date_time.date }}.cfg"
Example 2: Standardizing VLANs (Configuration)
This ensures VLAN 10 and 20 exist on all switches. If they are missing, Ansible creates them. If they exist, Ansible reports "OK".
---
- name: Standardize Critical VLANs
hosts: access_switches
gather_facts: no
tasks:
- name: Ensure VLAN 10 (Voice) Exists
cisco.ios.ios_vlan:
vlan_id: 10
name: VOICE_VLAN
state: present
- name: Ensure VLAN 20 (Data) Exists
cisco.ios.ios_vlan:
vlan_id: 20
name: DATA_VLAN
state: present
5. Enterprise Strategy: "Infrastructure as Code"
Running playbooks manually from a laptop is fine for testing, but in an enterprise, you need a workflow.
- Source of Truth: The configuration intent (variables) lives in Git.
- CI/CD Pipeline: When an engineer commits a change to Git (e.g., updates a VLAN name), a pipeline (GitLab CI / Jenkins) automatically runs a "Dry Run" playbook (check mode).
- Approval: A senior engineer reviews the "Diff" generated by Ansible.
- Deployment: Once merged, the pipeline runs the playbook in production.
- Drift Detection: A nightly cron job runs Ansible to check if the live device matches the Git repo. If someone made a manual CLI change, Ansible detects and reverts it.
6. Advanced Features: Jinja2 Templating
You don't write config commands manually. You create Templates (.j2 files) and feed them variables.
interface_template.j2
interface GigabitEthernet1/0/{{ item.id }}
description {{ item.desc }}
switchport mode access
switchport access vlan {{ item.vlan }}
no shutdown
playbook_variables.yml
interfaces:
- id: 1
desc: Printer_Lobby
vlan: 10
- id: 2
desc: PC_Reception
vlan: 20
Ansible loops through the list and generates the perfect configuration for 48 ports in seconds.
References & Resources
- Ansible Network Documentation - Official RedHat Guide.
- Cisco IOS Collection - Documentation for all IOS modules (ios_config, ios_command).
- Ansible GitHub - Source code and issue tracking.