netlab: virtual network labs described as YAML intent
Making virtual networking labs suck less
At a glance
- What is it?
- netlab turns a high level topology description into containerlab or Vagrant configuration, Ansible inventory, addressing plans and device configurations. Its latest release is 26.10, and the project ships a custom licence that GitHub cannot classify.
- Who is it for?
- netlab is worth adopting for network engineers who rebuild the same lab repeatedly, who need dual stack addressing and a dozen routing protocols in one place, and who would rather describe intent in YAML than click through a GUI. It is the wrong tool for a single quick topology, and for a team that cannot host Docker containers or libvirt KVM guests, since those are the two execution back ends it generates for.
- Can I use it commercially?
- Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
- Is it still maintained?
- Yes. The repository last received commits 1 day ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 24, 2026, and from our analysis. They are not legal advice.
Editorial analysis
A YAML file replaces the topology drawing
netlab exists to remove the part of lab work that does not need thought. The project description is blunt about the problem: building a topology in a graphical tool and then configuring the tedious details by hand wastes hours that could go into the part of the experiment you actually care about. The approach netlab takes is to let you write down the high level topology and the routing design in a YAML file, and then generate everything that follows from it.
The audience is network engineers and their teams, working on anything from a routing protocol interop test to a data centre fabric with VRFs, MPLS and EVPN. The unit of work is a lab, and the unit of input is a file that describes intent rather than configuration. A user of netlab should be able to open one topology file and see, in one place, which devices exist, how they are connected and which protocols run between them.
That design has a direct consequence for how the tool is used. The YAML file becomes the source of truth, and the generated lab is disposable. When a lab is wrong, the usual instinct to hand edit a running device is the wrong move, because the edit disappears the next time the file is applied.
One topology file becomes containerlab, Vagrant and Ansible artifacts
The generation step is what makes netlab more than a template engine. From the same topology file the tools produce a containerlab configuration file for running Docker containers, or a Vagrantfile for a libvirt / KVM environment, plus an Ansible inventory and configuration file, plus an IPv4 and IPv6 addressing plan and the routing design for it.
The choice between containerlab and Vagrant is therefore a deployment decision rather than a modelling decision, and the same YAML describes either. That matters because the two back ends have very different footprints. Containers start in seconds and are cheap, while KVM guests need a hypervisor and more memory, and a lab that mixes both, which netlab supports, inherits the cost of the slower one.
The repository layout matches that structure. The code lives in a `netsim/` package with the CLI entry point declared in `pyproject.toml`, and the project also ships `setup.sh`, a `tests/` directory and a `docs/` tree. The Python side is packaged under the name `networklab`, and it needs Python 3.10 or newer, with classifiers covering Python 3.10 through 3.14 on Linux and macOS.
The dependency list is short and conventional for a transformation tool:
Jinja2 >= 3.1.4
PyYAML >= 5.0.0
netaddr >= 0.8.0
python-box ~= 7.2,!=7.3.1Jinja2 does the templating of device configuration, netaddr does the address arithmetic, and the box library is used for the nested data structures the transformation produces.
The protocol surface is wide enough to need intent
The list of things netlab can configure is the clearest argument for the intent based approach. On the interface side it handles IPv4, IPv6, DHCP, DHCPv6, VLANs, VRFs, VXLAN, GRE tunnels and WireGuard tunnels. On the control plane it configures LLDP, BFD, OSPFv2, OSPFv3, EIGRP, IS-IS, RIPv2, RIPng and BGP.
Then come the features that separate a lab from a demonstration: VRRP, LACP, LAG, MLAG, link bonding, STP, anycast gateways, static routes, route maps, prefix lists, AS-path prefix lists, route redistribution, default route origination, MPLS, BGP-LU, L3VPN with VPNv4 and VPNv6, 6PE, EVPN, SR-MPLS and SRv6.
Configuring any of that by hand, for a topology with a dozen devices, is a day of work that has to be repeated every time a device is added. Writing it as intent lets the same file describe a two node OSPF test and a three site MPLS interop lab, and the addressing plan is derived rather than typed. The project also creates graphs and reports of the lab topology and of BGP, IS-IS and OSPF routing, which is a quick way to see whether the topology you described is the topology you got.
The command set splits into lifecycle, configuration and inspection
netlab is driven by a command line with a clear division of labour. The lifecycle commands are `netlab up`, which calls netlab create to make the configuration files, starts the virtual lab and then runs netlab initial to deploy device configurations including IP addressing and the routing protocols you asked for; `netlab down`, which destroys the lab; and `netlab restart`, which restarts or reconfigures it.
Configuration management is handled by `netlab config`, which applies additional Jinja2 configuration templates to the network devices, and `netlab collect`, which uses Ansible fact gathering or other device specific Ansible modules to collect device configurations and saves them in a chosen directory, `config` by default. `netlab create` is the command that creates device configurations in the `node_files` directory together with the virtualization configuration and the automation inventory, and it can also be used on its own to inspect the transformed data and produce graphs or reports.
Working with a running lab is a separate family: `netlab connect` and `netlab exec` reach a device over SSH or with docker exec, using device names, the management network address, the SSH port and credentials taken from the topology or from netlab device defaults. `netlab status` shows lab and device status. The console script is declared in the packaging metadata:
[project.scripts]
netlab = "netsim.cli:main"Capture and link impairment turn a lab into a testbed
Two commands exist to break things on purpose, and they are what separate netlab from a topology viewer. `netlab capture` performs packet capture on virtual machine and container interfaces, and `netlab tc` disables, enables, displays or modifies link impairment parameters.
Those two together let you reproduce a real failure. Delay, loss and reordering can be injected on a specific link to reproduce a routing convergence problem, and then a capture on the neighbouring interface shows exactly what the devices sent while the impairment was in place. Neither of those steps is available in a GUI, and both are the reason labs are worth automating in the first place.
The interesting part is where the impairment is configured. It is described as link impairment rather than as a per node setting, which means the topology file can say that a particular link is slow and the tool applies it to that link. The same applies to capture, where the target is a device interface rather than a whole device.
The documentation for the command reference is separate from the overview, and the README links the netlab command reference page for the full list of supported commands, since the set here is only a selection of the common ones.
Reports, graphs and the transformed data model
netlab keeps the data it computed, and the commands around it make that data visible. `netlab report` creates a report from the transformed lab topology data. `netlab graph` creates a topology graph description in Graphviz or D2 format, so the diagram can be rendered with either toolchain.
`netlab show` displays system settings in tabular, text or YAML format, and `netlab defaults` displays and manages the system defaults, which is where device credentials, management addressing and per device overrides live. `netlab usage` displays and manages usage statistics.
The defaults mechanism deserves attention because it is where the intent model pays off. A lab file that says a device is an Arista EOS box does not need to repeat the SSH port, the management address or the username for that device type, because those come from the defaults. Overriding one value in the topology file changes that instance only, and the rest of the file stays about intent.
Graphs and reports are also a review tool. A topology that nobody else on the team can read is a topology that only its author can maintain, and a generated graph gives a second, independent view of the file.
Release 26.10 ships with 26.09 as the documented fallback
The README says the latest release is release 26.10, that it should be pretty stable, and that if you encounter bugs you should report them as GitHub issues and use release 26.09 instead. A previous release link to 1.8.4-post2 is left in a comment, and the comment also mentions downgrading to 1.6.4 if you hit bugs in the 1.7.x series.
The commit record and the release process agree with each other. The last push was on 2026-10-22, the default branch is `dev`, and the README points at a release tag rather than a branch, so the working copy and the released code are separate things. The upgrade path is a change of release tag, not a merge of branches, which is a comfortable model for a tool that a team runs on shared infrastructure.
The licensing needs its own note. GitHub reports the licence of this repository as a custom one that it cannot classify, and the project ships a `LICENSE.md` file. Whatever the terms are, they are in that file rather than in a standard identifier, so a team that needs a clear open source grant should read it before depending on the tool rather than assume one.
The packaging metadata also shows the supported runtime, which is the practical prerequisite for installation:
requires-python = ">=3.10"Where a GUI or hand written Ansible differs
The alternative to netlab is the workflow it was written against: draw the topology in a GUI, configure each device by hand, and keep the result in notes. That approach is faster for a single experiment with two routers, because there is nothing to install, and it produces a lab that is easy to understand because one person built it end to end.
The second alternative is to write the Ansible playbooks yourself. That approach gives full control and avoids the abstraction, and it scales fine if your lab is a stable set of devices with a stable configuration. It stops scaling when the topology changes, because the playbook, the inventory, the addressing plan and the per device configuration are four separate artifacts that have to be kept in step by hand.
netlab collapses those artifacts into one file and generates the rest, which is the trade. You give up the ability to configure a device in a way netlab does not model, and you take on a dependency on device plugins and on a transformation layer you did not write. In exchange, a topology becomes a reviewable text file and a lab becomes reproducible, which is the point of infrastructure as code applied to networking rather than to servers.
Editorial conclusion
netlab is worth adopting for network engineers who rebuild the same lab repeatedly, who need dual stack addressing and a dozen routing protocols in one place, and who would rather describe intent in YAML than click through a GUI. It is the wrong tool for a single quick topology, and for a team that cannot host Docker containers or libvirt KVM guests, since those are the two execution back ends it generates for. Before adopting it, check the device plugins your lab needs, pin release 26.10 and keep release 26.09 as the fallback the project itself recommends, and read LICENSE.md, because GitHub reports a custom licence rather than a standard one.
Frequently asked questions
What is netlab and what problem does it solve for network engineers?
netlab brings infrastructure as code concepts to networking labs. You describe the high level topology and routing design in a YAML file, and the tools generate the containerlab or Vagrant configuration, the Ansible inventory, the addressing plan and the device configurations, instead of building the topology by hand in a GUI.
How do I install netlab?
The project points to its installation guidelines at netlab.tools/install. The Python package is published as `networklab`, it requires Python 3.10 or newer, and the console entry point is `netlab`, declared in the packaging metadata as `netsim.cli:main`.
Which netlab commands start, stop and inspect a lab?
`netlab up` creates the configuration files, starts the virtual lab and deploys the device configurations, `netlab down` destroys it and `netlab restart` reconfigures it. `netlab status` shows lab and device status, and `netlab show` and `netlab defaults` display system settings and defaults.
Can netlab simulate network problems such as delay or packet loss?
Yes. The `netlab tc` command disables, enables, displays or modifies link impairment parameters, and `netlab capture` performs packet capture on virtual machine and container interfaces, so a link can be degraded and the resulting traffic inspected.
Which protocols can netlab configure on lab devices?
The documented set includes IPv4, IPv6, DHCP, DHCPv6, VLANs, VRFs, VXLAN, GRE and WireGuard tunnels, LLDP, BFD, OSPFv2, OSPFv3, EIGRP, IS-IS, RIPv2, RIPng and BGP, plus VRRP, LACP, LAG, MLAG, STP, MPLS, L3VPN, EVPN, SR-MPLS and SRv6.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/ipspace-netlab)Was this useful?