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 using ios_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!