Automation Challenge
Lab Objectives
- Automate configuring device hostnames and interface IPs on multiple routers using a CSV input file and Netmiko.
- Learn how to convert CSV rows into device-specific configuration files and push them with Netmiko’s ConnectHandler and send_config_from_file.
- Verify configuration with device show commands and understand why automation reduces errors in production environments.
Lab Tasks (Try It Yourself First!)
Complete these tasks WITHOUT looking at the solution below. Use
?andshowcommands to figure it out.
Task 1: Create CSV input file
Create a CSV file named devices.csv containing columns: device_ip, hostname, interface, ip_address, subnet_mask. Populate one line per router using the base topology IPs.
Task 2: Write an automation script
Write a Python script that:
- Reads
devices.csv. - For each row, generates a short configuration file containing
hostnameand the interface configuration (description, ip address, no shutdown). - Connects to each router with Netmiko using ConnectHandler and applies the configuration file using
send_config_from_file.
Login Username: khawar
Password: Lab@123
Task 3: Verify configuration on the routers
After running the script, log into each router and verify the hostname and the interface IP with show ip interface brief.
Think About It: Why is it safer in production to generate device-specific config files and push them (one file per device) rather than issuing many ad-hoc CLI commands interactively?
Lab Solution
Reference ASCII Topology (use this EXACT topology)
(Exact IPs on every interface shown)
[Internet]
203.0.113.1
|
R1 (Gateway)
Gi0/0: 10.10.10.1
Gi0/1: 10.10.20.1
Gi0/2: 10.10.30.1
/ | \
R2 R3 R4
Gi0/0: 10.10.10.2 Gi0/0: 10.10.20.2 Gi0/0: 10.10.30.2
Gi0/1: 10.10.40.1
/ \ |
S1 S2 S3
/ \ | /
PC1 PC2 PC3 PC4 PC5
Real-world insight: In production networks the gateway router typically has multiple uplinks; automating repetitive configuration across many routers avoids human typo errors and ensures consistent descriptions and IPing schemes across all devices.
CSV Example (devices.csv)
Create devices.csv with these exact rows (no headers required or include headers and adjust script accordingly). Example with headers (preferred):
device_ip,hostname,interface,ip_address,subnet_mask
10.10.10.1,R1,GigabitEthernet0/0,10.10.10.1,255.255.255.0
10.10.10.2,R2,GigabitEthernet0/0,10.10.10.2,255.255.255.0
10.10.20.2,R3,GigabitEthernet0/0,10.10.20.2,255.255.255.0
10.10.30.2,R4,GigabitEthernet0/0,10.10.30.2,255.255.255.0
Tip: Using headers makes the CSV more readable and safer to parse.
The Python automation script (automation_challenge.py)
This script follows the Netmiko usage shown in earlier examples: it uses ConnectHandler and send_config_from_file. It reads the CSV, writes a device-specific temporary config file (e.g., R2.txt), then applies it.
from netmiko import ConnectHandler
import csv
import os
CSV_FILE = 'devices.csv'
USERNAME = 'khawar'
PASSWORD = 'Lab@123'
with open(CSV_FILE) as csvfile:
reader = csv.DictReader(csvfile)
for row in reader:
device_ip = row['device_ip'].strip()
hostname = row['hostname'].strip()
interface = row['interface'].strip()
ip_addr = row['ip_address'].strip()
mask = row['subnet_mask'].strip()
# Build config file content
cfg_filename = f"{hostname}.txt"
with open(cfg_filename, 'w') as cfg:
cfg.write('config terminal\n')
cfg.write(f'hostname {hostname}\n')
cfg.write(f'interface {interface}\n')
cfg.write(f' description Configured by automation for {hostname}\n')
cfg.write(f' ip address {ip_addr} {mask}\n')
cfg.write(' no shutdown\n')
cfg.write('exit\n')
cfg.write('wr\n')
# Netmiko connection params
Router = {
'device_type': 'cisco_ios',
'ip': device_ip,
'username': USERNAME,
'password': PASSWORD,
'port': 22
}
print(f"Connecting to {device_ip} ({hostname})")
net_connect = ConnectHandler(**Router)
# Push the config file to the device
net_connect.send_config_from_file(cfg_filename)
print(f"Applied configuration from {cfg_filename} to {hostname}")
net_connect.disconnect()
# Optional cleanup of the local file
os.remove(cfg_filename)
What this script does and why it matters:
- Reads structured CSV rows so the script can be reused with many devices (scalable).
- Creates a per-device configuration file (easier to review and version-control).
- Uses Netmiko's
send_config_from_file(...)— this is shown in the reference material and applies a file of configuration commands exactly as if typed in CLI. - Removes the transient config file locally to keep workspace clean (optional).
Real-world context: In a data center, teams generate device-specific config files from templates and inventories; pushing one file per device integrates cleanly with configuration management and audit trails.
Task 1 Solution: Create CSV input file
What we are doing: Creating the CSV input that drives the automation.
No router CLI commands — create a text file named devices.csv with the content shown above.
Why this matters: The CSV defines the inventory and desired state for each device; automation scripts should always be driven by an auditable input source.
Verify (local):
# (This is a local filesystem check, not a device command)
# On Linux/macOS:
$ cat devices.csv
device_ip,hostname,interface,ip_address,subnet_mask
10.10.10.1,R1,GigabitEthernet0/0,10.10.10.1,255.255.255.0
10.10.10.2,R2,GigabitEthernet0/0,10.10.10.2,255.255.255.0
10.10.20.2,R3,GigabitEthernet0/0,10.10.20.2,255.255.255.0
10.10.30.2,R4,GigabitEthernet0/0,10.10.30.2,255.255.255.0
Task 2 Solution: Push configs via Python / Netmiko
What we are doing: The Python script builds a per-device .txt configuration file and uses Netmiko to push it with send_config_from_file.
Key router configuration applied by the script (example for R2):
conf t
hostname R2
interface GigabitEthernet0/0
description Configured by automation for R2
ip address 10.10.10.2 255.255.255.0
no shutdown
exit
wr
What just happened:
conf tenters configuration mode so subsequent lines are interpreted as configuration commands.hostname R2changes the router’s prompt to reflect the new hostname.interface GigabitEthernet0/0selects the interface to configure.description ...documents the interface (important for operations teams).ip address ...assigns the IPv4 address.no shutdownbrings the interface administratively up.wrwrites the running configuration to NVRAM so the config persists after reboot.
Verify (on the device after the script runs):
show ip interface brief
Expected partial output for R2:
Interface IP-Address OK? Method Status Protocol
GigabitEthernet0/0 10.10.10.2 YES manual up up
GigabitEthernet0/1 10.10.40.1 YES manual up up
Loopback0 unassigned YES unset administratively down down
(Exact additional interfaces will vary per device; ensure the interface configured shows the assigned IP and Status up.)
Task 3 Solution: Verify hostname and interface
After running the script, confirm hostname and interface IP:
Verify hostname:
show running-config | include hostname
Expected output on R2:
hostname R2
Verify interface:
show ip interface brief
Expected line for the configured interface:
GigabitEthernet0/0 10.10.10.2 YES manual up up
Why these verifications matter: show running-config | include hostname confirms the running configuration contains the hostname — the best way to know the prompt wasn’t just changed locally. show ip interface brief gives a quick view of address and admin/operational state.
Troubleshooting Scenario
Scenario: R3 interface still shows administratively down after running the script
Symptom: show ip interface brief on R3 shows GigabitEthernet0/0 as unassigned administratively down.
Your task: Find and fix the issue.
Hint: Automation wrote the file but the interface command may have been mistyped or not applied.
Solution: Reconnect to R3, examine the last configuration pushed, and manually issue the no shutdown command if missing. Example fix:
configure terminal
interface GigabitEthernet0/0
no shutdown
exit
wr
Why: If no shutdown was omitted or a typo in the interface name occurred, the interface stays administratively down even if IP was set in the file.
Verification Checklist
- devices.csv exists and contains device IPs and desired settings.
- automation_challenge.py connects to each device and reports success.
- Each router shows the new hostname in its running-config.
- Each configured interface shows the correct IP and
up/upinshow ip interface brief.
Common Mistakes
| Symptom | Cause | Fix |
|---|---|---|
| Script fails to connect | Wrong username/password, or device IP incorrect | Verify CSV IPs and Netmiko credentials (username khawar, password Lab@123) |
Interface shows administratively down | no shutdown missing in config file | Add no shutdown to the per-device config or hand-enter no shutdown |
| Hostname didn't change | hostname line not present in config file | Inspect generated file; ensure hostname <name> is present before interface commands |
| Config file not applied | File not found or wrong filename passed to send_config_from_file | Ensure the filename matches the device hostname (script creates <hostname>.txt) |
Challenge Task
Extend the script so that, in addition to hostname and interface IP, it also configures a loopback interface on each router with /32 addresses (e.g., R1 -> 192.0.2.1/32, R2 -> 192.0.2.2/32). Produce and apply per-device files with both physical interface and loopback configuration, and verify with show ip interface brief.
Important: Work through the challenge without step-by-step instructions to practice mapping inventory data into device configuration files.