Every network engineering course runs into the same wall eventually: students spend more time proving their configuration is correct than actually learning why it should look that way. ping, traceroute, and squinting at show run output only get you so far, and once the lab session ends, so does your visibility into what the student actually did.
A few years ago I attempted implementing CI/CD concepts in my labs. Not only because networking in general is going in this direction, but also because the problem CI/CD solves: how do you know a change is correct, consistently, without a human checking every line by hand, is exactly the problem a networking classroom has too.
Here’s what building that pipeline for a graduate network design course taught me, what I’d do differently now, and where the idea went next.
Why bring CI/CD into a classroom at all
CI/CD pipelines have been introduced into network operations for a while, and for good reason: they let network teams validate changes automatically and repeatably before they ever touch production. A typical pipeline runs through configuration changes, pre-deployment checks, a dry-run against the live network, deployment, and post-deployment validation, with tools like Batfish for static analysis and Ansible for the check/diff/deploy cycle itself.
That production pipeline doesn’t map onto a classroom cleanly, though. There’s no production network to protect in a lab, students are supposed to make mistakes and retry, and the whole environment resets at the end of the session. So rather than import the production model wholesale, I stripped it down to what a lab actually needs:
- Configuration generation: students build device configs, manually or with automation tools, per the lab instructions.
- Configuration checks: students push to a shared GitHub repo any time they want, and get immediate automated feedback.
- Assessment checks: a pull request triggers the checks instructors actually grade against.
- Deployment checks: instructors optionally deploy the submitted configs to real infrastructure to validate the design further.
The point isn’t to simulate a production deployment pipeline. It’s to give students the same tight feedback loop network engineers rely on, without needing an instructor standing over their shoulder.
The problem this was actually solving
On the student side, the pain was familiar to anyone who’s TA’d a networking lab: verifying your own config is time-consuming with only manual tools, lab time is limited, and in a large class you can’t always get an instructor’s attention when you’re stuck.
On the instructor side, it’s arguably worse. Once the lab session ends, you’re often grading from submitted config files with no access to the live network state. Keeping evaluation consistent across multiple instructors, or across students who complete asynchronous work at different times, is genuinely hard. And it only gets harder as class sizes grow.
None of this requires a CI/CD pipeline specifically. Students and instructors could use the same verification tools directly, by hand. What the pipeline buys you is automation, consistency, and parallelism: the same tests run for every student, checks execute in parallel instead of queued behind an instructor’s attention, and every submission gets an automatically generated report to give feedback from. That last part matters more than it sounds. It turns “your OSPF adjacency is down” from something a TA has to notice into something the system tells the student directly.
How it worked in practice
During a lab, students configure their devices toward a set objective (say, connecting each device to a monitoring station over SNMP and Syslog) using whatever mix of manual and automated methods they want. To check their work, they clone the course repo, create a branch named for their lab (e.g. lab5_...), commit their device configs, and push.
That push triggers two kinds of checks: lightweight parsing tests that confirm specific config lines are present, and Batfish-driven configuration tests that validate actual network behavior. Because the branch name encodes the lab number, the pipeline knows exactly which test suite to run. Results come back as pass, fail, or warn. Instructors can choose whether an error should hard-stop the pipeline or just flag a warning and keep going. If something fails, the student fixes it and pushes again. Instructors, meanwhile, get a live view of every student’s commits and check results across the whole class, which is useful during the session and even more useful afterward when the ephemeral lab network is long gone.
Running it for real
This started as a proof of concept, deployed voluntarily in one course in two semesters. To avoid disrupting the normal lab flow, students used it once, after finishing the regular lab work, on the two labs that involved manual router configuration.
The goal at that stage was narrower than proving pedagogical value. The goal was finding what would break and a few things did. GitHub’s plain UI has no bulk way to add collaborators, which is a real headache when you’re onboarding a full class roster by hand every term. That one didn’t stay unsolved for long: a colleague later rebuilt the onboarding side on GitHub Classroom and moved the checks over to GitHub Actions, which is the obvious fix in hindsight and is genuinely what I’d recommend starting with today rather than a hand-rolled repo-and-collaborators setup.
I didn’t collect formal data on learning outcomes in that first pass; that was never the point of a proof of concept, but the qualitative signal was clear enough to act on: students were enthusiastic about getting instant feedback instead of waiting on a TA.
Where it falls short
It’s worth noting the trade-offs, because “add CI/CD to your course” is not without problems:
- It adds a skills requirement. Students and instructors need at least a working knowledge of Git and enough scripting comfort to make sense of pipeline output; that’s an extra thing to teach on top of the networking content itself.
- It’s only as good as the tools underneath it. Batfish, Ansible, and whatever else you wire in have to actually fit the assignment, or the checks give false confidence.
- It’s an upfront investment. Building the test suite for each lab assignment takes real time, and that cost doesn’t show up until you’re maintaining it across multiple terms.
- Not everything should be automated. Some things: design judgment, understanding why a configuration works, not just that it passes, still need a human evaluator in the loop.
What this turned into
The version described above was the starting point, not the end state. Since then, the same underlying idea: give students immediate, automated, consistent feedback on network configuration workm has kept showing up in other projects:
- The network automation tutorial walks through NETCONF, gNMI, and YANG using Containerlab-based labs with Nokia SR Linux and Arista cEOS, which is a lot of the same infrastructure this pipeline was built on top of.
- yang-automation-framework took the automation half much further: an intent → orchestration → translation → transport pipeline that provisions real devices over NETCONF and gNMI, with a GUI on top so students can author intents without hand-writing YANG.
- CI/CD itself now has a dedicated place in the redesigned network automation course, alongside Git, containers, YANG, NETCONF/RESTCONF, gRPC/gNMI, Ansible, and intent-based networking, rather than being a one-off experiment in a different course.
The takeaway
The original motivation still holds up: network configuration is code, and code that isn’t verified automatically gets verified inconsistently, slowly, or not at all. A CI/CD pipeline built for a classroom doesn’t need to look like a production one; it needs to give students a tight feedback loop and give instructors a consistent, low-effort way to evaluate work that would otherwise vanish the moment the lab session ends. That idea held up well enough to outlive the original proof of concept and become a fixture of how I teach network automation now.
