[Day #63 Pyats Series] Config drift detection with pyATS + Git diff using pyATS for Cisco [Python for Network Engineer]
Table of Contents
Introduction on the Key Points
Configuration drift is one of the most underrated problems in network operations. You configure a router today, and a few days later—someone changes an ACL, tweaks a BGP neighbor statement, or modifies an interface description—without telling anyone. The result? Unexpected behavior, outages, and an endless blame game in war rooms.
In this Day #63 of our 101 Days of pyATS (Vendor-Agnostic) series, we’re focusing on Config Drift Detection using pyATS combined with Git diff.
If you’re a Python for Network Engineer enthusiast or someone aiming to automate audits across Cisco (and multi-vendor) environments, this method is a game changer. You’ll learn:
- How to capture and store baseline configurations.
- How to use pyATS to collect current configs from devices.
- How to store configs in Git for version control.
- How to use
git diff
to detect changes instantly. - How to schedule this process for continuous drift monitoring.
By the end of this article, you’ll have a fully working workflow to detect even the smallest change in your network configs—before they become a problem.
Topology Overview
For today’s lab, we’re using a simple but realistic topology.

- CSR1 – Cisco CSR1000v acting as core router.
- CSR2 – Cisco CSR1000v acting as distribution.
- CSR3 – Cisco CSR1000v acting as edge router.
All devices are reachable via management IPs (out-of-band). We will store configurations in a Git repository and run drift detection scripts from our automation server (Ubuntu VM).
Topology & Communications
- Management Protocol: SSH (Netmiko/pyATS)
- Config Storage: Local Git repository (
/opt/network-configs
) - Automation Host: Ubuntu 22.04 VM with Python 3.10+ and pyATS installed.
- Version Control: Git with branches for production baseline tracking.
Workflow:
- Baseline Capture – Pull configs from all devices and store in
baseline/
folder in Git repo. - Scheduled Run – Pull fresh configs daily into
current/
folder. - Git Diff – Compare
current/
withbaseline/
to see changes. - Alerts – Email or Slack notification on drift.
Workflow Script
Here’s a clean and reusable pyATS + Git workflow script.
#!/usr/bin/env python3 """ Config Drift Detection with pyATS + Git Diff Author: Trainer Sagar Dhawan """ import os import subprocess from datetime import datetime from genie.testbed import load # Load pyATS testbed TESTBED = "testbed.yml" BASELINE_DIR = "baseline" CURRENT_DIR = "current" def fetch_configs(output_dir): """Fetch running configs from all devices and store in output_dir""" testbed = load(TESTBED) os.makedirs(output_dir, exist_ok=True) for device in testbed.devices.values(): print(f"Connecting to {device.name}...") device.connect(log_stdout=False) running_config = device.execute("show running-config") filepath = os.path.join(output_dir, f"{device.name}.cfg") with open(filepath, "w") as f: f.write(running_config) device.disconnect() print(f"Config saved for {device.name} at {filepath}") def git_diff(): """Run git diff to detect drift""" print("\nRunning Git Diff...") result = subprocess.run(["git", "diff", "--no-pager", BASELINE_DIR, CURRENT_DIR], capture_output=True, text=True) print(result.stdout if result.stdout else "No drift detected!") def main(): timestamp = datetime.now().strftime("%Y%m%d_%H%M%S") run_dir = os.path.join(CURRENT_DIR, timestamp) # Fetch current configs fetch_configs(run_dir) # Stage new configs to Git subprocess.run(["git", "add", "."], check=True) # Show differences git_diff() if __name__ == "__main__": main()
Explanation by Line
Let’s break it down for full clarity:
- Imports – We use
os
for file paths,subprocess
for Git commands, anddatetime
for timestamped folders. - TESTBED – Points to our
testbed.yml
file describing devices. - fetch_configs() –
- Loads the testbed.
- Creates output directory.
- Iterates through devices, connects via SSH, executes
show running-config
, and writes to file.
- git_diff() –
- Runs
git diff
betweenbaseline/
andcurrent/
. - If there’s drift, prints changes; otherwise prints “No drift detected!”
- Runs
- main() –
- Creates timestamped directory in
current/
for new configs. - Fetches configs.
- Adds them to Git staging area.
- Runs diff check.
- Creates timestamped directory in
testbed.yml Example
testbed: name: drift_detection_lab credentials: default: username: admin password: cisco123 devices: CSR1: os: iosxe type: router connections: cli: protocol: ssh ip: 192.168.1.11 CSR2: os: iosxe type: router connections: cli: protocol: ssh ip: 192.168.1.12 CSR3: os: iosxe type: router connections: cli: protocol: ssh ip: 192.168.1.13
Post-validation CLI (Real Expected Output)
Sample Git Diff Output:
$ python3 drift_detect.py Connecting to CSR1... Config saved for CSR1 at current/20250808/CSR1.cfg Connecting to CSR2... Config saved for CSR2 at current/20250808/CSR2.cfg Connecting to CSR3... Config saved for CSR3 at current/20250808/CSR3.cfg Running Git Diff... diff --git a/baseline/CSR2.cfg b/current/20250808/CSR2.cfg - router bgp 65001 - neighbor 10.0.12.2 remote-as 65002 + router bgp 65001 + neighbor 10.0.12.2 remote-as 65003
This output clearly shows BGP neighbor’s remote AS changed from 65002 to 65003 — a perfect example of drift detection catching unauthorized or accidental changes.
FAQs
1. What is configuration drift, and why should network engineers care about it?
Configuration drift happens when the running configuration of a network device changes over time without proper documentation or change control. This could be due to emergency fixes, human error, or even malicious changes. If left unchecked, config drift can lead to:
- Security vulnerabilities
- Compliance failures
- Network outages
Using pyATS with Git diff helps detect these drifts early by comparing the latest device configs with a trusted baseline stored in Git.
2. How does pyATS help in detecting configuration drift?
pyATS can automatically connect to devices, retrieve the current configuration, and save it as a text file. When these files are version-controlled in Git, you can run git diff
to see exactly what changed, line-by-line. This allows you to:
- Identify unauthorized changes
- Automate daily or weekly drift checks
- Keep a historical record of configurations
3. Why use Git for drift detection instead of manual comparison?
Git acts as a time machine for your configs.
- Every change is recorded with timestamps, authors, and commit messages.
git diff
clearly highlights changes in a human-readable format.- You can roll back to any previous version instantly.
When paired with pyATS automation, it eliminates the manual “copy-paste-compare” headache.
4. Can pyATS + Git detect both intentional and unintentional changes?
Yes. Whether it’s a planned change (e.g., VLAN addition) or an accidental one (e.g., ACL line deletion), pyATS will capture the current state and Git will show the delta from the last approved version. You can then review commit messages to verify if the change was authorized.
5. How often should I run config drift detection?
- Mission-critical networks: Daily or even hourly checks via a scheduled job (e.g., cron, Jenkins).
- Standard enterprise networks: Weekly is often enough.
- After major deployments or security incidents, run an on-demand drift check to ensure no unexpected changes were introduced.
6. Does this process work for multi-vendor networks?
Yes. pyATS is vendor-agnostic if used with appropriate parsers and connection methods. You can pull configs from Cisco, Arista, Juniper, Palo Alto, Fortinet, etc., and still store them in Git. Git doesn’t care about the vendor—it only tracks text differences.
7. What’s the biggest advantage of automating drift detection vs. doing it manually?
Automation:
- Reduces human error
- Saves hours of manual work
- Ensures consistency
- Integrates easily with CI/CD pipelines for proactive detection
This means you catch problems before they break production.
8. How do I start implementing pyATS + Git drift detection in my network?
- Create a pyATS testbed YAML with device details.
- Write a pyATS script to pull device configurations.
- Save these configs in a Git repository.
- Schedule the script (cron/Jenkins) to run regularly.
- Use
git diff
or automated notifications (e.g., Slack/Email) to report changes.
Over time, you’ll have a full audit trail of every configuration change in your network.
YouTube Link
Watch the Complete Python for Network Engineer: Config drift detection with pyATS + Git diff using pyATS for Cisco [Python for Network Engineer] Lab Demo & Explanation on our channel:
Join Our Training
If this drift detection workflow got you excited, imagine what you could achieve with structured, instructor-led training.
Trainer Sagar Dhawan is running a 3-month hands-on program — Python, Ansible, APIs & Cisco DevNet for Network Engineers — designed to take you from zero to fully automating multi-vendor networks.
You’ll learn:
- pyATS from basics to advanced.
- Building automation pipelines with Python & Ansible.
- API integrations (RESTCONF, NETCONF, Webex Bots).
- GitOps for network automation.
Reserve your seat now → Course Details & Registration
Stop waiting for “someday” — the best time to become a Python for Network Engineer is now.
Enroll Now & Future‑Proof Your Career
Email: info@networkjourney.com
WhatsApp / Call: +91 97395 21088