Lesson 5 of 5

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 ? and show commands 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 hostname and 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 t enters configuration mode so subsequent lines are interpreted as configuration commands.
  • hostname R2 changes the router’s prompt to reflect the new hostname.
  • interface GigabitEthernet0/0 selects the interface to configure.
  • description ... documents the interface (important for operations teams).
  • ip address ... assigns the IPv4 address.
  • no shutdown brings the interface administratively up.
  • wr writes 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/up in show ip interface brief.

Common Mistakes

SymptomCauseFix
Script fails to connectWrong username/password, or device IP incorrectVerify CSV IPs and Netmiko credentials (username khawar, password Lab@123)
Interface shows administratively downno shutdown missing in config fileAdd no shutdown to the per-device config or hand-enter no shutdown
Hostname didn't changehostname line not present in config fileInspect generated file; ensure hostname <name> is present before interface commands
Config file not appliedFile not found or wrong filename passed to send_config_from_fileEnsure 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.