Automating Cisco IOS-XE Interface Configuration with Ansible Loops


In this blog, I'll show how to use Ansible to automate interface configuration across multiple Cisco IOS-XE routers using a loop. This is especially useful for bulk interface provisioning and ensuring consistency across your edge routers.
Objective
Configure 2 WAN Edge routers (IOS-XE) with multiple interfaces (WAN + OSPF) using a single playbook, leveraging:
Grouped hosts in inventory
Per-host variables stored in
host_vars
Ansible loop to iterate through interfaces
Topology
Project Layout
ansible/
├── cisco-config.yml # Main playbook
├── inventory/
│ └── hosts # Inventory file listing the IOS-XE devices
├── host_vars/
│ ├── 10.1.1.181.yml # Host-specific variables for router 10.1.1.181
│ └── 10.1.1.184.yml # Host-specific variables for router 10.1.1.184
Inventory Structure
We maintain a structured inventory and variable layout:
# inventory/hosts
[ios-xe]
10.1.1.181
10.1.1.184
Per-host variables:
📁 host_vars/10.1.1.181.yml
interfaces:
- { wan_interface: "GigabitEthernet1", wan_description: "WAN1", wan_ip: "192.168.1.1", wan_mask: "255.255.255.0" }
- { wan_interface: "GigabitEthernet2", wan_description: "OSPF-INTERFACE", wan_ip: "192.168.20.1", wan_mask: "255.255.255.0" }
📁 host_vars/10.1.1.184.yml
interfaces:
- { wan_interface: "GigabitEthernet1", wan_description: "WAN1", wan_ip: "192.168.2.1", wan_mask: "255.255.255.0" }
- { wan_interface: "GigabitEthernet2", wan_description: "OSPF-INTERFACE", wan_ip: "192.168.20.2", wan_mask: "255.255.255.0" }
The Ansible Playbook
cisco-config.yml
:
---
- name: Configure 2 WAN Edges connected and OSPF
hosts: ios-xe
gather_facts: no
connection: network_cli
tasks:
- name: Interface Configurations
cisco.ios.ios_config:
lines:
- description {{ item.wan_description }}
- no shutdown
- ip address {{ item.wan_ip }} {{ item.wan_mask }}
parents: interface {{ item.wan_interface }}
loop: "{{ interfaces }}"
Run the Playbook
#ansible-playbook -i inventory/hosts cisco-config.yml
Output Highlights
PLAY RECAP *********************************************************************
10.1.1.181 : ok=1 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
10.1.1.184 : ok=1 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Each router receives the interface configuration defined in its own host_vars
YAML file.
Running configuration of 10.1.1.181
interface GigabitEthernet1
description WAN1
ip address 192.168.1.1 255.255.255.0
negotiation auto
!
interface GigabitEthernet2
description OSPF-INTERFACE
ip address 192.168.20.1 255.255.255.0
negotiation auto
!
Running configuration of 10.1.1.184
interface GigabitEthernet1
description WAN1
ip address 192.168.1.1 255.255.255.0
negotiation auto
!
interface GigabitEthernet2
description OSPF-INTERFACE
ip address 192.168.20.1 255.255.255.0
negotiation auto
!
This is achieved through a loop, ensuring scalability and flexibility when configuring multiple routers or interfaces.
Tips
Use
network_cli
for Cisco IOS devices, and ensure SSH + privilege access is enabled.Store variables per device in
host_vars/
for modularity.Validate results with
show running-config
or collect configs usingios_command
.
Feel free to clone, adapt, and expand this example to suit your network automation workflows. Automation doesn't have to be complex — start small, and grow from there!
Subscribe to my newsletter
Read articles from Nam Nguyen directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by

Nam Nguyen
Nam Nguyen
Visit to see more: https://linktr.ee/nddnam I am an enthusiastic Network Engineer with 7+ years of experience working on MPLS L3VPN Network projects, Cisco SDWAN Deployment, and Enterprise Networks. I love to automate every daily task and think Dev-Ops as always. Thus, I am entering the DevNet world.