Mastering Cisco IOS Configuration Automation with Ansible ios_config

The automation of network infrastructure has transitioned from a luxury to a fundamental requirement for modern enterprise environments. Within the Cisco ecosystem, the Cisco IOS (Internetwork Operating System) remains the most widely deployed network operating system globally, powering everything from small branch office routers to massive campus switches. The integration of Ansible into this environment allows network engineers to transition from manual, error-prone Command Line Interface (CLI) entries to a rigorous, repeatable, and fully auditable Infrastructure as Code (IaC) model. Central to this transformation is the cisco.ios.ios_config module, a powerful tool designed specifically to manage the configuration state of Cisco devices. By leveraging this module, organizations can push configuration changes, enforce compliance, and ensure consistency across their entire fleet in a fraction of the time required for manual implementation.

Architectural Overview of the cisco.ios Collection

The cisco.ios collection provides a suite of purpose-built modules tailored for the nuances of Cisco IOS. To begin utilizing these capabilities, the collection must be installed via the Ansible Galaxy CLI using the following command:

ansible-galaxy collection install cisco.ios

The operational foundation of this collection relies on a properly configured inventory. An inventory file, such as inventory/ios-devices.ini, must define the device groups and the specific connection variables required for Ansible to communicate with the hardware.

Inventory Configuration and Connection Variables

A robust inventory structure ensures that playbooks are applied to the correct sets of devices, such as core routers versus access switches. The following table outlines the critical variables required for successful Cisco IOS connectivity.

Variable Description Required Value/Example
ansible_network_os Defines the target operating system cisco.ios.ios
ansible_connection Specifies the connection plugin ansible.netcommon.network_cli
ansible_user The SSH username for authentication admin
ansible_password The encrypted password for the user {{ vault_ios_password }}
ansible_become Enables privilege escalation yes
ansible_become_method Specifies the method to enter privileged mode enable
ansible_become_password The password for the enable secret {{ vault_enable_password }}

The use of ansible_become is essential because the majority of configuration commands in Cisco IOS require privileged EXEC mode. By setting the ansible_become_method to enable, Ansible automatically handles the transition into the privileged state, ensuring that the subsequent configuration commands are executed with the necessary authority.

Deep Dive into the ios_config Module

The cisco.ios.ios_config module serves as the primary engine for configuration management. Its primary responsibility is to send a set of configuration commands to the device. A critical functional aspect of this module is that it automatically handles the entry into global configuration mode (configure terminal) and the subsequent exit from that mode (end), removing the need for the user to manually include these commands in their playbooks.

The Lines and Commands Parameters

In the evolution of Ansible, specifically starting with version 2.1, the ios_config module introduced flexibility in how commands are passed. The commands parameter is an alias for the lines parameter. This means that any functionality attributed to lines can be achieved using commands.

The lines parameter is defined as an ordered set of commands that should be configured in a specific section of the device configuration. When Ansible processes these lines, it ensures they are sent to the device in the exact order specified, which is critical for commands where sequence matters, such as Access Control List (ACL) entries or complex policy maps.

Configuration Contexts and the Parents Parameter

One of the most sophisticated features of the ios_config module is the parents parameter. In Cisco IOS, many commands are context-specific; for example, a description or an IP address cannot be applied in global configuration mode but must be applied within an interface configuration mode.

The parents parameter allows the user to specify the configuration context. When a value is provided to parents, Ansible enters that specific context before sending the lines.

For example, to configure an interface, the playbook would look like this:

yaml - name: Configure interface settings cisco.ios.ios_config: lines: - description test interface - ip address 172.31.1.1 255.255.255.0 parents: interface Ethernet1

This mechanism can be scaled using Ansible loops (with_items) to apply the same set of commands across multiple interfaces.

yaml - name: Configure ip helpers on multiple interfaces cisco.ios.ios_config: lines: - ip helper-address 172.26.1.10 - ip helper-address 172.26.3.8 parents: "{{ item }}" with_items: - interface Ethernet1 - interface Ethernet2 - interface GigabitEthernet1

The parents parameter also supports a list of strings to handle deeply nested configurations, such as policy maps and class maps. This is essential for implementing Quality of Service (QoS) settings.

yaml - name: Configure policer in Scavenger class cisco.ios.ios_config: lines: - conform-action transmit - exceed-action drop parents: - policy-map Foo - class Scavenger - police cir 64000

Advanced Configuration Logic and State Management

The ios_config module provides several advanced parameters to ensure that configurations are applied accurately and that the device state remains consistent.

Handling ACLs and the Before Parameter

When managing Access Control Lists (ACLs), simply adding lines may not be sufficient if the existing ACL needs to be completely replaced. The before parameter allows the user to execute a command prior to the main configuration lines. This is frequently used to delete an existing ACL before applying a new one to ensure a clean state.

yaml - name: Load new acl into device cisco.ios.ios_config: lines: - 10 permit ip host 192.0.2.1 any log - 20 permit ip host 192.0.2.2 any log - 30 permit ip host 192.0.2.3 any log - 40 permit ip host 192.0.2.4 any log - 50 permit ip host 192.0.2.5 any log parents: ip access-list extended test before: no ip access-list extended test match: exact

The match: exact parameter ensures that Ansible compares the desired state with the actual state precisely. If a discrepancy is found, Ansible will perform the necessary actions to align the device configuration with the specified lines.

Configuration Validation and Comparison

To prevent accidental outages, Ansible provides mechanisms to validate changes before they are committed.

  • Diff Mode: Using the --check and --diff flags during playbook execution allows operators to see exactly which lines would be added or removed from the configuration. This provides a critical layer of safety and auditability.
  • Comparison Against Master: The diff_against parameter can be used to compare the current running configuration against an intended configuration file.

yaml - name: Check the running-config against master config cisco.ios.ios_config: diff_against: intended intended_config: "{{ lookup('file', 'master.cfg') }}"

Complementary Modules and Resource-Based Management

While ios_config is the "workhorse" for general settings, it is a generic tool. For specific network entities, Cisco provides "resource modules" that offer a declarative approach to management.

The ios_facts Module

Before applying configurations, it is often necessary to gather the current state of the device. The cisco.ios.ios_facts module collects structured data, which can then be used for conditional logic in playbooks.

yaml - name: Gather Cisco IOS facts cisco.ios.ios_facts: gather_subset: - all register: facts

The gathered facts include:
- ansible_net_hostname: The device hostname.
- ansible_net_model: The hardware model.
- ansible_net_version: The IOS version.
- ansible_net_serialnum: The hardware serial number.
- ansible_net_image: The image file used to boot the device.

Specialized Resource Modules

Resource modules like ios_interfaces, ios_vlans, and ios_acls should be used whenever possible instead of ios_config because they provide a structured way to manage specific features.

For example, managing VLANs is more efficient using the ios_vlans module:

yaml - name: Create VLANs cisco.ios.ios_vlans: config: - vlan_id: 10 name: SERVERS - vlan_id: 20 name: WORKSTATIONS state: merged

Similarly, interface management can be handled via ios_interfaces to define speed, duplex, and enabled status without writing raw CLI commands.

Operational Best Practices and Troubleshooting

To maximize the reliability of Cisco IOS automation, engineers should adhere to specific operational patterns.

Handling Confirmation Prompts

Certain IOS commands, such as crypto key generate rsa, trigger interactive confirmation prompts. Since ios_config is designed for non-interactive configuration, these prompts can cause the module to hang or fail. In such cases, the ios_command module should be used, as it includes a prompt parameter specifically designed to handle these interactions.

Persistence and the Startup Config

Changes made via ios_config are applied to the running configuration. In Cisco IOS, the running configuration is stored in volatile memory (RAM). If the device reboots, these changes are lost unless they are saved to the startup configuration (NVRAM).

A best practice is to use a handler that executes a save command only when changes have actually been made. This prevents unnecessary writes to the NVRAM, which can prolong the lifespan of the hardware flash memory.

Comparison of Configuration Methods

Method Module Approach Best Use Case
Generic Config ios_config Imperative/Lines Unique settings, banners, global config
Resource Config ios_vlans / ios_interfaces Declarative/Structured VLANs, IP addresses, Interface states
Fact Gathering ios_facts Read-only Audit, Inventory, Conditional logic
Direct Command ios_command Interaction show commands, prompt-based config

Conclusion

The cisco.ios.ios_config module, when combined with the broader cisco.ios collection, transforms the management of Cisco network devices from a manual task into a scalable software process. By utilizing the lines and parents parameters, engineers can precisely control the configuration context of their devices, while tools like diff_against and match: exact ensure that the actual state of the network perfectly mirrors the intended state. While resource modules should be prioritized for standard entities like VLANs and interfaces, ios_config remains an indispensable tool for all other configuration requirements. The ability to test changes with --check and --diff and to automate the enable process through ansible_become allows for a level of speed, safety, and auditability that is impossible to achieve through manual CLI management.

Sources

  1. Network Lore - Ansible ios_config
  2. OneUptime - How to use Ansible with Cisco IOS Devices
  3. Ansible Collections - cisco.ios.ios_config Documentation

Related Posts