Ansible for Network Automation

1. What Is Ansible and Why Use It for Networks?

Ansible is an open-source IT automation tool developed by Red Hat that uses a simple, human-readable language (YAML) to describe the desired state of systems and automate their configuration. In a network context, Ansible can log into routers, switches, firewalls, and wireless controllers — execute commands, push configurations, and validate state — across hundreds of devices simultaneously, without a single person typing a single CLI command.

Traditional network management is device-by-device and CLI-driven. An engineer SSHes into each device, types commands, checks the output, and moves on. This approach does not scale. Ansible replaces this with a declarative, repeatable, version-controlled approach: describe what you want, run the playbook, and Ansible ensures every device reaches the desired state — consistently and at scale.

Traditional (Manual) Approach Ansible Automation
SSH into each device individually Run one playbook — Ansible connects to all devices in parallel
Type commands manually — prone to typos YAML playbook defines the desired state — no manual CLI entry
No record of what changed or when Playbooks stored in Git — full version control and change history
Config drift — devices diverge over time Idempotent playbooks re-run regularly — enforce consistent state
One engineer, one device at a time One engineer, hundreds of devices simultaneously

Related pages: Network Automation Overview | Python for Network Automation | JSON, XML & YANG | REST API Overview | NETCONF & RESTCONF | Controller-Based Networking | Ansible IOS Configuration Lab | Postman & Ansible Lab

2. Ansible Architecture – Agentless by Design

Ansible's most important architectural characteristic is that it is agentless — the managed devices (routers, switches) do not need any special software installed. Ansible communicates with network devices over existing management protocols: SSH for Cisco IOS/NX-OS and most network operating systems, or NETCONF/REST APIs for newer platforms.

2.1 Core Components

Component What It Is Where It Lives
Control Node The Linux machine (or VM) where Ansible is installed and playbooks are run from; this is the "brain" — it orchestrates everything Management server, engineer's laptop, or CI/CD pipeline runner
Managed Nodes The network devices being configured — routers, switches, firewalls; no Ansible installation required here Your network infrastructure
Inventory A file (INI or YAML format) listing all managed nodes and groups; the "device database" that Ansible targets Control node — typically hosts or inventory.yml
Playbook A YAML file describing a set of tasks to perform on managed nodes; the "automation script" — what Ansible runs Control node — typically *.yml files
Module A reusable unit of automation code that performs a specific action (e.g., configure a VLAN, push a config block); Ansible ships with thousands and Cisco provides the cisco.ios collection Installed on control node — executed against managed nodes
Collection A bundle of related modules, roles, and plugins; Cisco publishes cisco.ios, cisco.nxos, cisco.asa collections on Ansible Galaxy Installed on control node via ansible-galaxy

2.2 Architecture Diagram

  ┌──────────────────────────────────────────────────────────────────────────┐
  │  Control Node  (Linux / macOS — Ansible installed here)                 │
  │                                                                          │
  │  ┌──────────────┐  ┌──────────────┐  ┌──────────────────────────────┐  │
  │  │  Inventory   │  │  Playbook    │  │  Cisco IOS Collection        │  │
  │  │  hosts.yml   │  │  site.yml    │  │  (cisco.ios modules)         │  │
  │  │  [routers]   │  │  - tasks:    │  │  ios_config, ios_vlans,      │  │
  │  │  R1, R2, R3  │  │    - name:   │  │  ios_hostname, ios_facts...  │  │
  │  └──────────────┘  └──────────────┘  └──────────────────────────────┘  │
  │                           │                                              │
  │                    ansible-playbook site.yml                             │
  └───────────────────────────┼──────────────────────────────────────────────┘
                              │ SSH (port 22) — existing management protocol
              ┌───────────────┼─────────────────────┐
              ▼               ▼                     ▼
       ┌──────────┐    ┌──────────┐          ┌──────────┐
       │  R1      │    │  R2      │    ...    │  SW-50   │
       │ (Cisco   │    │ (Cisco   │           │ (Cisco   │
       │  IOS)    │    │  IOS)    │           │  IOS)    │
       │          │    │          │           │          │
       │ No agent │    │ No agent │           │ No agent │
       │ required │    │ required │           │ required │
       └──────────┘    └──────────┘          └──────────┘

  Ansible connects via SSH → executes tasks → collects results → reports back
Why agentless matters for networks: Network operating systems (Cisco IOS, NX-OS, IOS-XE, IOS-XR) cannot install arbitrary software. An agent-based tool would be incompatible with these platforms. Ansible's agentless SSH approach works with any device that supports SSH — which is virtually every modern network device, including legacy hardware.

3. Inventory Files

The inventory file tells Ansible which devices to target, how to connect to them, and how to organise them into logical groups. Groups allow playbooks to target specific subsets of devices — for example, running a task only against all core switches, or only against branch routers.

3.1 INI Format Inventory

  # hosts  (INI format — simple, widely used)

  [routers]
  R1 ansible_host=192.168.1.1
  R2 ansible_host=192.168.1.2
  R3 ansible_host=192.168.1.3

  [switches]
  SW1 ansible_host=192.168.2.1
  SW2 ansible_host=192.168.2.2

  [core_switches]
  SW1

  [network:children]
  routers
  switches

  [routers:vars]
  ansible_user=admin
  ansible_password=Cisco123
  ansible_network_os=cisco.ios.ios
  ansible_connection=network_cli
  ansible_become=yes
  ansible_become_method=enable
  ansible_become_password=EnablePass

3.2 YAML Format Inventory

  # inventory.yml  (YAML format — more structured, preferred for complex environments)

  all:
    children:
      routers:
        hosts:
          R1:
            ansible_host: 192.168.1.1
          R2:
            ansible_host: 192.168.1.2
        vars:
          ansible_user: admin
          ansible_password: Cisco123
          ansible_network_os: cisco.ios.ios
          ansible_connection: network_cli
          ansible_become: yes
          ansible_become_method: enable
          ansible_become_password: EnablePass

      switches:
        hosts:
          SW1:
            ansible_host: 192.168.2.1
          SW2:
            ansible_host: 192.168.2.2
        vars:
          ansible_user: admin
          ansible_password: Cisco123
          ansible_network_os: cisco.ios.ios
          ansible_connection: network_cli

3.3 Key Inventory Variables for Network Devices

Variable Value (Cisco IOS) Purpose
ansible_host IP address or FQDN The management IP address Ansible connects to
ansible_user admin SSH username for the device
ansible_password Cisco123 SSH password (use Ansible Vault for production)
ansible_network_os cisco.ios.ios Tells Ansible which network OS plugin to use; determines how to parse output and send commands
ansible_connection network_cli Connection type for network devices — uses the device's CLI over SSH
ansible_become yes Enables privilege escalation (equivalent to entering enable)
ansible_become_method enable The method for privilege escalation on Cisco IOS devices
ansible_become_password EnablePass The enable password for privileged EXEC mode

4. YAML Syntax Essentials

Ansible playbooks and inventory files are written in YAML (YAML Ain't Markup Language) — a human-readable data serialisation format that uses indentation (spaces, never tabs) to represent hierarchy. Understanding YAML structure is essential for reading and writing Ansible content.

  YAML Key Concepts:

  # Comments start with hash
  key: value                   # String value
  number: 42                   # Integer
  enabled: true                # Boolean (true/false, yes/no, on/off)

  # List (sequence) — items preceded by dash and space
  vlans:
    - 10
    - 20
    - 30

  # Dictionary (mapping) — key/value pairs
  router:
    hostname: R1
    loopback: 1.1.1.1

  # List of dictionaries (very common in Ansible tasks)
  interfaces:
    - name: GigabitEthernet0/1
      description: Uplink to Core
      enabled: true
    - name: GigabitEthernet0/2
      description: Server port
      enabled: false

  # Multi-line strings
  config_block: |
    interface GigabitEthernet0/1
     description Uplink
     ip address 10.0.0.1 255.255.255.252
     no shutdown

  CRITICAL YAML RULES:
  ✓ Indentation MUST use spaces — NEVER tabs
  ✓ Consistent indentation depth (2 or 4 spaces per level)
  ✓ Colons followed by a space: key: value  (not key:value)
  ✓ Lists use dash-space prefix:  - item  (not -item)
  ✗ Mixing tabs and spaces breaks parsing with cryptic errors

5. Playbook Structure

A playbook is the core Ansible automation file. It defines which devices to run against (the hosts directive), what to do (the tasks list), and optionally variables, handlers, and other configuration. A playbook can contain one or more plays, each targeting a different group of hosts.

  Playbook anatomy:

  ---                          # YAML document start marker
  - name: Play description     # Name of the play (human-readable)
    hosts: routers             # Which inventory group(s) to target
    gather_facts: no           # For network devices: usually 'no'
    connection: network_cli    # Or specified in inventory

    vars:                      # Variables for this play
      ntp_server: 10.0.0.1
      domain_name: corp.local

    tasks:                     # List of tasks to execute in order
      - name: Task description # Human-readable task name (shown in output)
        module_name:           # The Ansible module to call
          parameter1: value1   # Module parameters
          parameter2: value2

      - name: Another task
        another_module:
          parameter: value

    handlers:                  # Tasks triggered by 'notify' in other tasks
      - name: Save configuration
        cisco.ios.ios_command:
          commands: write memory

5.1 Key Playbook Directives

Directive Purpose Example
hosts Specifies which inventory group or host(s) the play runs against hosts: routers or hosts: all or hosts: R1,SW2
gather_facts Controls whether Ansible automatically collects device facts at play start; set to no for network devices to avoid errors gather_facts: no
vars Defines play-level variables — reusable values referenced with {{ variable_name }} syntax throughout the play vars:
  vlan_id: 10
tasks Ordered list of actions to perform; each task calls one module See examples below
when Conditional — task only runs when the condition is true when: ansible_network_os == "cisco.ios.ios"
loop Repeats a task for each item in a list loop: [10, 20, 30]
register Stores a task's output in a variable for use in later tasks register: output
notify Triggers a named handler when the task reports a change notify: Save configuration

6. Cisco IOS Modules

The cisco.ios Ansible collection provides modules specifically designed for Cisco IOS and IOS-XE devices. Each module targets a specific configuration area and understands the IOS data model — rather than parsing raw CLI text, these modules interact with IOS in a structured, idempotent way.

  Install the Cisco IOS collection:
  ansible-galaxy collection install cisco.ios

  Verify installation:
  ansible-galaxy collection list | grep cisco

6.1 Commonly Used Cisco IOS Modules

Module Purpose Key Parameters
cisco.ios.ios_config Push arbitrary IOS configuration lines — the most flexible but least idempotent module; use when no specific module exists lines, parents, before, after, save_when
cisco.ios.ios_command Run exec-mode show commands and return output; does not make configuration changes commands, wait_for, retries
cisco.ios.ios_facts Gather structured facts from a device (hostname, interfaces, version, routing table) for use in later tasks or reports gather_subset (all, min, hardware, config)
cisco.ios.ios_vlans Manage VLANs using a structured resource module — idempotent; can create, modify, and delete VLANs with VLAN name and state config (list of VLAN dicts with name/vlan_id), state (merged/replaced/deleted)
cisco.ios.ios_interfaces Manage interface parameters — description, enabled state, speed, duplex config (list of interface dicts), state
cisco.ios.ios_l3_interfaces Configure Layer 3 IP addresses on interfaces config with ipv4 address list
cisco.ios.ios_banner Configure login banners (MOTD, login, exec) banner (motd/login/exec), text, state
cisco.ios.ios_ntp_global Configure NTP servers and settings — see NTP Configuration for the manual CLI equivalent config with servers list
cisco.ios.ios_hostname Set the device hostname (IOS-XE 17.3+ resource module) config.hostname, state
Resource modules vs ios_config: Resource modules like ios_vlans and ios_interfaces are idempotent — they understand the current state of the device and only make changes when needed. ios_config is more like raw CLI automation — it pushes lines without necessarily understanding the existing config. Prefer resource modules when available; use ios_config as a fallback for features that do not yet have a dedicated module.

7. Idempotency in Ansible

Idempotency is one of the most important concepts in Ansible. An idempotent operation produces the same result whether it is run once or a hundred times — it only makes a change when the current state differs from the desired state. If the desired state already exists, no change is made and no configuration is pushed.

  Idempotency in Practice:

  Desired state (playbook): VLAN 10 named "Sales" should exist

  Run 1: VLAN 10 does not exist → Ansible CREATES it  (changed = yes)
  Run 2: VLAN 10 already exists with name "Sales" → NO CHANGE  (changed = no)
  Run 3: VLAN 10 exists but name is wrong → Ansible UPDATES name  (changed = yes)
  Run 4: VLAN 10 exists with correct name → NO CHANGE  (changed = no)

  Benefit:
  ┌──────────────────────────────────────────────────────────────────────┐
  │ You can run the SAME playbook repeatedly without fear of breaking    │
  │ things or creating duplicate configuration. Idempotent playbooks    │
  │ are safe to schedule, automate, and run as compliance checks.       │
  └──────────────────────────────────────────────────────────────────────┘

  ios_config vs resource modules:
  ios_config:      NOT fully idempotent — pushes lines even if already present
  ios_vlans:       FULLY idempotent — checks state before making changes
  ios_interfaces:  FULLY idempotent — compares current vs desired state

8. Worked Example 1 – Configure Hostname and Domain Name

  # configure-hostname.yml
  ---
  - name: Set hostname and domain name on all routers
    hosts: routers
    gather_facts: no

    vars:
      domain: corp.local

    tasks:
      - name: Set device hostname using ios_config
        cisco.ios.ios_config:
          lines:
            - hostname {{ inventory_hostname }}
            - ip domain-name {{ domain }}

      - name: Verify hostname (optional check)
        cisco.ios.ios_command:
          commands:
            - show running-config | include hostname
        register: hostname_output

      - name: Display hostname output
        debug:
          var: hostname_output.stdout_lines

  # Run with:  ansible-playbook configure-hostname.yml -i hosts

  # What happens:
  # For each host in the [routers] group:
  #   1. Ansible SSHes to the device (using credentials in inventory)
  #   2. Enters privileged EXEC mode (enable)
  #   3. Enters global config mode (conf t)
  #   4. Pushes:  hostname R1  (using inventory_hostname as the value)
  #              ip domain-name corp.local
  #   5. Exits config mode
  #   6. Runs 'show running-config | include hostname' and stores output
  #   7. Displays the stored output in the playbook results

9. Worked Example 2 – Configure VLANs

The cisco.ios.ios_vlans resource module is the preferred way to manage VLANs at scale. See also VLAN Creation and Management for the manual CLI equivalent.

  # configure-vlans.yml
  ---
  - name: Configure VLANs on all switches
    hosts: switches
    gather_facts: no

    tasks:
      # ── Method 1: Resource module (idempotent, preferred) ──
      - name: Create VLANs using ios_vlans resource module
        cisco.ios.ios_vlans:
          config:
            - name: Management
              vlan_id: 10
              state: active
            - name: Sales
              vlan_id: 20
              state: active
            - name: Engineering
              vlan_id: 30
              state: active
            - name: Voice
              vlan_id: 40
              state: active
          state: merged
        notify: Save configuration

      # ── Method 2: ios_config with loop (flexible fallback) ──
      # Uncomment this block if ios_vlans is not available:
      #
      # - name: Create VLANs using ios_config
      #   cisco.ios.ios_config:
      #     lines:
      #       - name {{ item.name }}
      #     parents: vlan {{ item.id }}
      #   loop:
      #     - { id: 10, name: Management }
      #     - { id: 20, name: Sales }
      #     - { id: 30, name: Engineering }
      #     - { id: 40, name: Voice }

      - name: Verify VLANs exist
        cisco.ios.ios_command:
          commands:
            - show vlan brief
        register: vlan_output

      - name: Display VLAN table
        debug:
          var: vlan_output.stdout_lines

    handlers:
      - name: Save configuration
        cisco.ios.ios_command:
          commands:
            - write memory

  # Run with:  ansible-playbook configure-vlans.yml -i hosts

  # Expected output (abbreviated):
  # TASK [Create VLANs using ios_vlans resource module]
  # changed: [SW1]
  # changed: [SW2]
  #
  # TASK [Verify VLANs exist]
  # ok: [SW1]
  # ok: [SW2]
  #
  # TASK [Display VLAN table]
  # SW1: |
  #   VLAN Name         Status    Ports
  #   ---- ------------ --------- ------
  #   10   Management   active
  #   20   Sales        active
  #   30   Engineering  active
  #   40   Voice        active

10. Worked Example 3 – Gather and Display Device Facts

  # gather-facts.yml
  ---
  - name: Gather device facts from all network devices
    hosts: network
    gather_facts: no

    tasks:
      - name: Gather IOS facts
        cisco.ios.ios_facts:
          gather_subset:
            - min          ! hostname, version, serial number
            # - all        ! adds interfaces, routing, config (slower)

      - name: Display device summary
        debug:
          msg: |
            Device: {{ inventory_hostname }}
            Hostname: {{ ansible_net_hostname }}
            IOS Version: {{ ansible_net_version }}
            Model: {{ ansible_net_model }}
            Serial: {{ ansible_net_serialnum }}

      - name: Save facts to a file (optional)
        copy:
          content: "{{ ansible_facts | to_nice_yaml }}"
          dest: "./facts/{{ inventory_hostname }}_facts.yml"
        delegate_to: localhost

  # Useful ansible_net_* variables populated by ios_facts:
  # ansible_net_hostname    — configured hostname
  # ansible_net_version     — IOS software version
  # ansible_net_model       — hardware model (e.g., ISR4331)
  # ansible_net_serialnum   — device serial number
  # ansible_net_interfaces  — dict of all interfaces and their state
  # ansible_net_all_ipv4_addresses — all IPv4 addresses on the device

11. Running Playbooks and Useful Commands

  # Run a playbook:
  ansible-playbook site.yml -i hosts

  # Run with increased verbosity (useful for debugging):
  ansible-playbook site.yml -i hosts -v     ! 1 level verbose
  ansible-playbook site.yml -i hosts -vvv   ! 3 levels — connection detail

  # Dry run — check mode (shows what WOULD change, makes no changes):
  ansible-playbook site.yml -i hosts --check

  # Limit to specific hosts or groups:
  ansible-playbook site.yml -i hosts --limit R1
  ansible-playbook site.yml -i hosts --limit routers

  # Run specific tags only:
  ansible-playbook site.yml -i hosts --tags vlans

  # Prompt for SSH password at runtime (avoids plain text in inventory):
  ansible-playbook site.yml -i hosts --ask-pass --ask-become-pass

  # Test connectivity to all devices (ad-hoc ping):
  ansible all -i hosts -m ping

  # Run a single ad-hoc command (no playbook):
  ansible routers -i hosts -m cisco.ios.ios_command \
    -a "commands='show version'"

  # List all hosts in inventory:
  ansible-inventory -i hosts --list

  # Encrypt sensitive data with Ansible Vault:
  ansible-vault encrypt_string 'Cisco123' --name 'ansible_password'

11.1 Ansible Vault – Protecting Credentials

Storing passwords in plain text in inventory files is a serious security risk. Ansible Vault encrypts sensitive values so they can be safely stored in version control (Git) without exposing credentials. Ensure the devices themselves also use strong SSH credentials — see SSH Configuration and Login Security.

  # Create an encrypted variable file:
  ansible-vault create secrets.yml

  # Encrypt an existing file:
  ansible-vault encrypt inventory/group_vars/all.yml

  # Run playbook with vault password:
  ansible-playbook site.yml -i hosts --vault-password-file vault.pass
  # OR
  ansible-playbook site.yml -i hosts --ask-vault-pass

  # Reference vault-encrypted vars in inventory:
  # group_vars/routers.yml  (encrypted with vault)
  ansible_password: !vault |
          $ANSIBLE_VAULT;1.1;AES256
          6132633362623432643637313934...

12. Ansible vs Other Automation Tools

Feature Ansible Puppet Chef Python Scripts
Architecture Agentless (SSH/API) Agent-based (pull model) Agent-based (pull model) Custom — any method
Language YAML (declarative) Puppet DSL (declarative) Ruby DSL (procedural) Python (procedural)
Network device support Excellent — cisco.ios, nxos, asa, junos, f5, palo alto Limited — primarily server OS Limited — primarily server OS Excellent — Netmiko, NAPALM, RESTCONF, full control
Learning curve Low — YAML is readable; no programming required Medium — Puppet DSL requires learning High — Ruby knowledge needed Medium-High — requires Python knowledge
Idempotency Yes (resource modules) / Partial (ios_config) Yes — enforces desired state on every run Yes — converges to desired state Only if the developer codes it
Best for networks Configuration management, compliance, multi-vendor Server infrastructure; not ideal for network OSes Server infrastructure; not ideal for network OSes Custom scripting, complex logic, one-off tasks — see Python Netmiko Lab

13. Key Terms Quick Reference

Term Definition
Ansible An open-source, agentless IT automation platform by Red Hat; uses YAML playbooks to configure systems via SSH or APIs
Agentless Ansible requires no software to be installed on managed nodes — it connects via SSH (or APIs) using existing protocols; ideal for network OSes that cannot run arbitrary software
Control Node The Linux/macOS machine where Ansible is installed; where playbooks are written and executed from
Managed Node The network device (router, switch) being configured by Ansible; requires no Ansible installation
Inventory File A file (INI or YAML) listing all managed devices and groups; defines connection variables (IP, credentials, OS type) for each device or group
Playbook A YAML file containing one or more plays; each play targets a group of hosts and defines an ordered list of tasks to execute
Play A section of a playbook that maps a set of tasks to a specific group of hosts; a single playbook can contain multiple plays targeting different groups
Task A single action within a play that calls one Ansible module with specific parameters; tasks are executed in order
Module A reusable unit of code that performs a specific action (e.g., configure a VLAN, run a show command); Ansible provides thousands of modules including the Cisco IOS collection
Collection A distributable bundle of modules, roles, and plugins; Cisco publishes cisco.ios, cisco.nxos, cisco.asa collections via Ansible Galaxy
YAML YAML Ain't Markup Language — a human-readable data format using indentation to define structure; the language of Ansible playbooks and inventory; spaces only, no tabs
Idempotency A property of Ansible resource modules where running the same playbook multiple times produces the same result — changes are only made when the current state differs from the desired state
ios_config The most flexible Cisco IOS module — pushes raw config lines to a device; useful for features without a dedicated module but less idempotent than resource modules
ios_vlans A Cisco IOS resource module for VLAN management; fully idempotent — compares desired vs current state and only makes necessary changes
Ansible Vault Ansible's built-in encryption feature for protecting sensitive data (passwords, keys) in playbooks and inventory files so they can be safely stored in version control
network_cli The Ansible connection type used for network devices; establishes an SSH session and interacts with the device CLI, enabling persistent connection and privilege escalation

14. Ansible for Network Automation – Practice Quiz

1. What does "agentless" mean in the context of Ansible, and why is it important for network device automation?

Correct answer is B. Agentless means Ansible communicates with managed nodes using protocols already available on those devices — primarily SSH for Cisco IOS/IOS-XE and APIs (NETCONF, RESTCONF) for newer platforms. No Ansible agent software needs to be installed on the router or switch. This is especially important for network devices because their operating systems (Cisco IOS, NX-OS, Junos) are not general-purpose Linux systems and cannot install arbitrary software packages. Agent-based tools like Puppet and Chef are therefore much less suitable for network automation.

2. In an Ansible inventory file, what is the purpose of the ansible_network_os variable for a Cisco IOS device?

Correct answer is C. ansible_network_os is one of the most important inventory variables for network automation. It identifies the operating system of the managed node so Ansible knows which connection plugin and terminal emulation to use. For Cisco IOS, the value is cisco.ios.ios. This tells Ansible to use the IOS connection plugin — which knows how IOS handles prompts, how to enter configuration mode, what privilege escalation looks like, and how to parse IOS command output. Without this variable, Ansible would not know how to interact with an IOS device properly.

3. What is idempotency in Ansible and why does it matter for network automation?

Correct answer is A. Idempotency is the property that makes infrastructure-as-code playbooks safe to run repeatedly. If you run cisco.ios.ios_vlans to configure VLAN 10 and it already exists with the correct name, Ansible reports ok (no change made) rather than trying to create it again. This matters enormously in network automation — you can schedule playbooks to run every hour as a compliance check, and they will only make changes when something drifts from the desired state. Non-idempotent operations (like appending lines with ios_config) require extra care to avoid duplicate configuration entries.

4. In the following task, what does {{ inventory_hostname }} represent?

- name: Set hostname
  cisco.ios.ios_config:
    lines:
      - hostname {{ inventory_hostname }}

Correct answer is D. inventory_hostname is a special Ansible magic variable that holds the name of the current host as it appears in the inventory file. When Ansible iterates over all hosts in the routers group — R1, R2, R3 — and runs this task on each, the {{ inventory_hostname }} placeholder is replaced with "R1", then "R2", then "R3" respectively. The result: each device gets its own hostname configured automatically, from a single task definition. This is variable templating in action — one of the most powerful features of Ansible playbooks.

5. What is the difference between cisco.ios.ios_config and cisco.ios.ios_vlans when configuring VLANs?

Correct answer is B. This is a key distinction in the Cisco IOS Ansible collection. ios_vlans is a resource module — it has full awareness of the current VLAN database on the device and compares it against the desired state in the playbook. If VLAN 10 already exists, it is not recreated. If a VLAN name needs updating, only that update is made. ios_config is a raw CLI automation tool — it pushes the lines you specify without necessarily checking if they already exist. For operations like adding config lines, repeated runs can result in duplicate entries. Prefer resource modules for their predictability and idempotency; use ios_config as a fallback for features that lack a resource module.

6. What does the following inventory variable combination achieve?

ansible_become: yes
ansible_become_method: enable

Correct answer is C. Cisco IOS SSH sessions log in at user EXEC level (level 1) by default. Configuration commands require privileged EXEC mode (level 15), entered with the enable command. Without privilege escalation, Ansible can run show commands but cannot push configuration. The combination of ansible_become: yes (enable the escalation) and ansible_become_method: enable (use the IOS enable command) tells Ansible to automatically enter enable after logging in. ansible_become_password provides the enable password.

7. An engineer runs an Ansible playbook with ansible-playbook site.yml --check. What does the --check flag do?

Correct answer is A. The --check flag enables "dry run" mode — Ansible goes through all the motions of connecting to devices and evaluating each task, but does not make any actual changes. Instead it reports whether each task would result in changed (a change would be made) or ok (no change needed). This is extremely valuable before running a new playbook on production devices — you can see exactly what would change without risking any disruption. Note: not all modules support check mode fully, and some network modules may show limited check mode output.

8. Why should plain text passwords in Ansible inventory files be replaced with Ansible Vault in production environments?

Correct answer is D. A core practice in infrastructure-as-code is storing configuration in version control (Git). If device passwords are stored in plain text in inventory files or variable files, anyone with read access to the Git repository can see those credentials — including shared repositories and CI/CD pipelines. Ansible Vault encrypts sensitive values using AES-256, producing an encrypted string that can be safely committed to Git. The decryption key (vault password) is kept separately, never committed to the repository. This is the production standard for Ansible credential management.

9. A playbook task uses register: output after running cisco.ios.ios_command. What is the purpose of register?

Correct answer is B. The register directive saves the entire return value of a task into a named variable. For ios_command, this includes the command output in output.stdout (a list of strings) and output.stdout_lines (a list of lists, one per command). This allows subsequent tasks to use the captured output — for example, a debug task to display it, a when condition to check whether a specific string appears in the output, or a copy task to write it to a file. It is the primary mechanism for building conditional logic based on device state in Ansible playbooks.

10. A network team needs to configure 200 switches with the same set of VLANs, NTP servers, and banner messages after a new security policy. They want to be able to run the same configuration again monthly as a compliance check without impacting devices that are already compliant. Which Ansible feature makes this safe?

Correct answer is C. This is the perfect use case for idempotent resource modules. The team writes a playbook using cisco.ios.ios_vlans, cisco.ios.ios_ntp_global, and cisco.ios.ios_banner. They schedule it to run monthly. On each run: switches that are already fully compliant get all-ok results — no changes, no risk. Switches that have drifted (someone manually deleted a VLAN, or a switch was replaced and not fully configured) get the specific missing configuration pushed. Option A is wrong because check mode never actually fixes anything. Option B requires manual identification of non-compliant devices. Option D prevents access rather than enabling safe repeated execution.

← Back to Home