[Day #76 PyATS Series] Automate Zero-Touch Provisioning Validation Using pyATS for Cisco [Python for Network Engineer]

[Day #76 PyATS Series] Automate Zero-Touch Provisioning Validation Using pyATS for Cisco [Python for Network Engineer]


Introduction on the Key Points

Zero-Touch Provisioning (ZTP) is a powerful method to automatically onboard new network devices with minimal manual intervention. By automating initial device configurations, ZTP accelerates network deployments and ensures configuration consistency across devices.

In this detailed Article, we will focus on automating the validation of ZTP workflows using pyATS, specifically designed for Cisco IOS-XE devices. By automating validation, network engineers ensure that newly provisioned devices are correctly configured and operational after ZTP completes.

This masterclass provides a step-by-step, practical implementation of using Python for Network Engineer automation tasks, enabling you to validate configuration, connectivity, and device state in a fully automated manner. Combining CLI, GUI snapshots, and structured assertions, this guide ensures robust ZTP validation workflows that can be extended for multi-vendor environments.


Topology Overview

  • ZTP Server: Provides DHCP, TFTP, HTTP services for automated provisioning of the switch.
  • Catalyst 9300 Switch: New switch undergoing zero-touch provisioning.
  • Automation Server: Runs the pyATS workflow to validate that ZTP completed successfully and device is in expected state.

Objective:

  • Validate that ZTP completed successfully.
  • Ensure final configuration matches expected baseline.
  • Confirm interface up/down status and basic connectivity.

Topology & Communications

Communication Flow:

  1. Catalyst 9300 boots and gets IP configuration via DHCP from ZTP Server.
  2. Downloads initial configuration via TFTP/HTTP and applies the configuration automatically.
  3. After ZTP completes, the automation server (pyATS) connects over SSH to validate:
    • Device hostname
    • Configuration file version
    • Interface states (up/down)
    • IP address configuration
    • Routing table correctness

Optional: Capture GUI snapshots of the web-based management dashboard post-ZTP to visually verify success.


Workflow Script

from genie.testbed import load
from pyats.aetest import Testcase, test, main

EXPECTED_CONFIG = {
    "hostname": "ztp-catalyst9300",
    "interfaces": {
        "GigabitEthernet1/0/1": {"status": "up", "ip_address": "192.168.10.1"},
        "GigabitEthernet1/0/2": {"status": "down", "ip_address": None}
    }
}

class ZTPValidation(Testcase):

    @test
    def connect_and_fetch(self, testbed):
        self.ztp_output = {}
        device = testbed.devices['ztp_catalyst9300']
        device.connect(log_stdout=False)

        self.ztp_output['hostname'] = device.execute('show run | include hostname')
        self.ztp_output['interfaces_status'] = device.execute('show ip interface brief')
        self.ztp_output['config_version'] = device.execute('show version | include Config file')

        # Optional: GUI screenshot
        # device.api.take_screenshot('/tmp/ztp_dashboard.png')

    @test
    def validate_hostname(self):
        hostname_line = self.ztp_output['hostname'].strip()
        assert "hostname {}".format(EXPECTED_CONFIG['hostname']) in hostname_line, \
            f"FAIL: Hostname mismatch. Found: {hostname_line}"

    @test
    def validate_config_version(self):
        config_version = self.ztp_output['config_version'].strip()
        assert "startup-config" in config_version.lower(), "FAIL: Config not applied via ZTP"

    @test
    def validate_interfaces(self):
        interfaces_output = self.ztp_output['interfaces_status'].splitlines()
        for iface, expected in EXPECTED_CONFIG['interfaces'].items():
            matched = False
            for line in interfaces_output:
                if iface in line:
                    fields = line.split()
                    status = fields[1]
                    ip_address = fields[2] if fields[2] != "unassigned" else None
                    print(f"Checking {iface}: Status={status}, IP={ip_address}")
                    assert status == expected['status'], f"FAIL: {iface} status mismatch"
                    assert ip_address == expected['ip_address'], f"FAIL: {iface} IP mismatch"
                    matched = True
                    break
            assert matched, f"FAIL: {iface} not found in interface summary"

if __name__ == '__main__':
    main()

Explanation by Line

  • EXPECTED_CONFIG: Defines expected hostname, interface statuses, and IP addresses after ZTP.
  • connect_and_fetch():
    • Connects to the newly provisioned device via SSH.
    • Executes CLI commands:
      • show run | include hostname to verify hostname.
      • show ip interface brief to check interface statuses and IP addresses.
      • show version | include Config file to confirm config application.
  • validate_hostname(): Ensures hostname matches the expected value.
  • validate_config_version(): Validates that ZTP applied the startup configuration.
  • validate_interfaces(): Parses interface summary output and compares actual against expected status and IP.

Optional: Capture a GUI dashboard screenshot for visual validation if the management web interface is active.


testbed.yml Example

testbed:
  name: ztp_validation_testbed
  credentials:
    default:
      username: admin
      password: Cisco123

devices:
  ztp_catalyst9300:
    os: iosxe
    type: switch
    connections:
      cli:
        protocol: ssh
        ip: 192.168.100.50

Post-validation CLI (Real expected output)

show run | include hostname

hostname ztp-catalyst9300

show ip interface brief

Interface              IP-Address      OK? Method Status                Protocol
GigabitEthernet1/0/1   192.168.10.1   YES manual up                    up      
GigabitEthernet1/0/2   unassigned     YES unset  administratively down down    

show version | include Config file

Configuration register is 0x2102
Configuration file at boot: flash:config.text

Sample Automation Output

--- Validating Hostname ---
PASS: Hostname matches expected value: ztp-catalyst9300  

--- Validating Config Version ---
PASS: ZTP applied startup-config correctly  

--- Validating Interface GigabitEthernet1/0/1 ---
Checking GigabitEthernet1/0/1: Status=up, IP=192.168.10.1  
PASS: GigabitEthernet1/0/1 configuration is consistent  

--- Validating Interface GigabitEthernet1/0/2 ---
Checking GigabitEthernet1/0/2: Status=down, IP=None  
PASS: GigabitEthernet1/0/2 configuration is consistent  

All ZTP validation checks PASSED.

Optional: GUI screenshot saved at /tmp/ztp_dashboard.png.


FAQs

Q1. What is Zero-Touch Provisioning (ZTP) in networking?
A1. Zero-Touch Provisioning (ZTP) automates the initial deployment of network devices by allowing them to self-provision when connected to the network. It eliminates manual configuration by automatically downloading and applying predefined configurations, enabling rapid and consistent deployments.


Q2. Why is automating ZTP validation important?
A2. Automating ZTP validation ensures that the provisioning process completed successfully, the correct configuration is applied, and devices are ready for production use. It prevents silent failures where a device appears connected but is misconfigured or missing required settings.


Q3. How does pyATS validate ZTP completion?
A3. pyATS automates ZTP validation by connecting to devices post-provisioning, running commands like show running-config, show version, and show ip interface brief, and verifying key configuration elements such as hostname, management IP, interface settings, and applied policies.


Q4. Which CLI commands are essential for ZTP validation on Cisco devices?
A4. Commonly used commands include:

  • show running-config – to validate applied configuration
  • show version – to check firmware and uptime
  • show ip interface brief – to verify interface IP assignment and operational state

Q5. Can pyATS verify multi-vendor ZTP validation?
A5. Yes. By defining appropriate test scripts and parsers for each vendor, pyATS can validate ZTP on Cisco, Arista, Juniper, and other platforms, making it ideal for multi-vendor environments in large-scale deployments.


Q6. How are validation results presented in pyATS?
A6. Validation results are output in structured formats (JSON, HTML), showing per-device detailed checks, including hostname, IP address, interface status, applied configuration, and success or failure of each validation step.


Q7. How can this validation framework be integrated into production workflows?
A7. Once automated, ZTP validation can be integrated into CI/CD pipelines or triggered by orchestration tools (e.g., Ansible Tower). This ensures every newly provisioned device is automatically validated before being moved into production, reducing manual effort and deployment errors.


YouTube Link

Watch the Complete Python for Network Engineer: Automate Zero-Touch Provisioning Validation Using pyATS for Cisco [Python for Network Engineer] Lab Demo & Explanation on our channel:

Master Python Network Automation, Ansible, REST API & Cisco DevNet
Master Python Network Automation, Ansible, REST API & Cisco DevNet
Master Python Network Automation, Ansible, REST API & Cisco DevNet
Why Robot Framework for Network Automation?

Join Our Training

You have just completed a deep-dive, hands-on masterclass Article showing how to automate Zero-Touch Provisioning validation using pyATS. This practical example illustrates powerful automation workflows crucial for today’s network engineers.

But the learning doesn’t stop here.

Trainer Sagar Dhawan’s 3-month Instructor-Led Training Program is specially designed for network engineers eager to master Python for Network Engineer automation tasks. Learn structured automation, Ansible playbooks, API integrations, and how to build robust, scalable solutions.

Full course outline here:
Python Ansible API Cisco DevNet for Network Engineers – 3-Month Training

Join today to advance your career, increase your productivity, and automate complex network operations confidently.

Enroll Now & Future‑Proof Your Career
Emailinfo@networkjourney.com
WhatsApp / Call: +91 97395 21088