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.

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
Security Best Practice

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.

  1. Source of Truth: The configuration intent (variables) lives in Git.
  2. 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).
  3. Approval: A senior engineer reviews the "Diff" generated by Ansible.
  4. Deployment: Once merged, the pipeline runs the playbook in production.
  5. 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