# Netplan keeps one YAML file in charge of several network backends

> Netplan is Canonical's declarative network configuration tool, and its distinguishing job is translating a single YAML document into whatever renderer the running system actually uses, from NetworkManager to systemd-networkd to Open vSwitch.

**canonical/netplan** — Declarative network configuration for various backends

- Repository: https://github.com/canonical/netplan
- Website: https://netplan.io
- Stars: 853 · Forks: 254
- Language: Python
- License: GPL-3.0
- Published: 2026-10-20 · Updated: 2026-10-20 · Language: en
- Canonical page: https://hysenlabs.com/projects/canonical-netplan

## The abstraction is a YAML file that renders to a backend

Netplan is described as declarative network configuration for various backends, and that phrase carries the whole design. You write YAML, you do not write ifupdown or NetworkManager keyfiles or systemd-networkd .network files, and Netplan translates your document into the format the running system expects. The top level of the repository shows the scope of that translation: there is a src/ directory for the generators, a dbus/ directory, an abi-compat/ directory, a netplan_cli/ directory holding the Python command line, a python-cffi/ directory for the bindings, and separate snap/ and rpm/ packaging trees. The features are generated rather than hand maintained, with features_h_generator.sh and features_py_generator.sh producing the C header and the Python side of the feature list, which is how a single source of truth ends up in both languages.

## One configuration, several renderers

The examples directory is the best evidence of how wide the surface is, because it is a list of YAML files rather than prose. It includes bonding.yaml, bonding_router.yaml, bridge.yaml, bridge_vlan.yaml, dhcp.yaml, dhcp_wired8021x.yaml, dummy-devices.yaml, infiniband.yaml, ipv6_tunnel.yaml, loopback_interface.yaml, modem.yaml, offload.yaml, openvswitch.yaml, sriov.yaml, sriov_vlan.yaml, static-routes.yaml, static.yaml, static_multiaddress.yaml, route_metric.yaml, source_routing.yaml, network_manager.yaml, direct_connect_gateway.yaml and direct_connect_gateway_ipv6.yaml. The presence of network_manager.yaml and openvswitch.yaml next to the plain interface examples is the point: the same YAML vocabulary describes a link that NetworkManager will drive, a bridge that Open vSwitch will build, or a plain interface that systemd-networkd will take. The topic tags on the repository say the same thing, abstraction and configuration, and the whole abstraction is that the operator does not have to know which of those will end up running.

## The Python CLI resolves paths at runtime, which shapes the build

The README explains an implementation detail that explains a lot of the build machinery. The Python command line resolves binary and library paths at runtime, and the required environment variables, such as NETPLAN_GENERATE_PATH, are needed because of that. In practice the CLI is a front end that calls out to compiled generators, and the local development wrapper has to point at the freshly built binaries rather than whatever is installed on the system.

```sh
$ make run ARGS="info"
# output:
netplan.io:
  website: "https://netplan.io/"
  features:
  - dhcp-use-domains
  - auth-phase2
```

That is the whole test loop for a change to the tool itself: build it, then run the built binary against a controlled environment without installing it system wide. The Makefile run target sets NETPLAN_GENERATE_PATH and NETPLAN_CONFIGURE_PATH, LD_LIBRARY_PATH and PYTHONPATH, and invokes the staged sbin binary, which is a small amount of plumbing that saves a system install per iteration.

## Meson is the real build system and make is a wrapper

The build is Meson, with a Makefile provided for convenience. The direct Meson steps are a setup, a compile, a test and an install, and the setup step takes a coverage flag.

```sh
* meson setup build --prefix=/usr [-Db_coverage=true]
* meson compile -C build
* meson test -C build --verbose [TEST_NAME]
* meson install -C build --destdir ../tmproot
```

The Makefile targets wrap the same thing. make or make default sets up the _build directory and compiles, make check builds and runs all tests in _build, make linting runs the Meson linting and codestyle test targets, make install accepts a DESTDIR and defaults to ../tmproot, make clean removes generated artifacts, and make run executes the locally built CLI. The separation is worth noting: linting and codestyle are Meson test targets, so style violations fail the same test run as functional failures, and the Makefile targets are thin wrappers rather than a second build definition.

## The dependency list is the real cost of building it

The README gives the build and test dependencies for Ubuntu and Debian in one apt invocation.

```sh
sudo apt install \
    build-essential \
    pkg-config \
    meson \
    libglib2.0-dev \
    libyaml-dev \
    libsystemd-dev \
    uuid-dev \
    bash-completion \
    python3-dev \
    python3-cffi \
    python3-coverage \
    python3-pytest \
    python3-pytest-cov \
    pyflakes3 \
    pycodestyle \
    libcmocka-dev \
    gcovr \
    pandoc
```

Three of those entries tell you what the tool is made of. libyaml-dev is the configuration parser, libsystemd-dev is the systemd integration including the networkd renderer and the netplan-configure.service unit, and libglib2.0-dev is the C library the generators use. python3-cffi and python3-pytest are for the CLI, cmocka is the C unit test framework, and pandoc is there for the documentation. The mix of C, Python and YAML is not incidental. Netplan is a compiler from a declarative document to backend configuration files, so it needs a real parser, a real generator and a real test story on both sides of the language boundary.

## Where a declarative network file stops working

The limitation is inherent in the model rather than in the implementation. A declarative file describes the state you want, and Netplan's job is to make it true. Some network requirements are not state but sequence: an interface that must come up only after a tunnel is established, a route that must be re-added when a link flaps, a fallback that depends on a runtime check. Expressing those in YAML means encoding the workaround, and the moment you encode it you are back to imperative scripts with a declarative wrapper. There is a second practical limit. Netplan renders your file into the backend's own configuration, and that generated file is what the system reads. If someone or some tool edits the generated file directly, the change is lost at the next apply, and if the backend itself is reconfigured by other tooling, the two sources of truth diverge. The README does not document a locking mechanism to prevent that, so a team that mixes netplan with manual edits to /etc/network will have a support problem that is not the tool's fault but is the tool's consequence.

## Distribution, bug reports and the licence

The README points to Launchpad for bug reports rather than GitHub issues, which reflects that the packaging and the upstream development live in different places. The IRC channel is #netplan on Libera.Chat, and the developer mailing list is netplan-developers on the Launchpad lists. The licence is GPL-3.0, with the COPYING file at the repository root, and that matters more here than it would for a typical library: a tool that writes system configuration files and ships inside an operating system image is a component of the distribution, and the copyleft terms are the reason downstream distributions can package it. The project also ships a SECURITY.md, a CONTRIBUTING.md and a separate documentation tree under doc/ with its own make run workflow for previewing changes in a browser. The last push was on 2026-10-15, and the release tags are Netplan v1.2.2 from 2026-07-20, v1.2.1 from 2026-01-27 and v1.2 from 2025-12-16, so the code moves more often than the tags.

## Conclusion

Netplan suits an Ubuntu or Debian operator who wants network configuration to be a version controlled YAML file rather than a set of distribution specific files, and it suits a team that runs several images with different network managers because the backend is a per file decision. It is the wrong tool for a network with dynamic requirements that a declarative file cannot express, and for anyone who needs the generated backend files to be the source of truth, since a hand edit to them will be overwritten on the next apply. Before adopting it, read the architecture overview at netplan.io/design, and note that the same YAML can be rendered to several backends, so the configuration you write is not the configuration that runs until a backend has been chosen. The last push was on 2026-10-15 and the current release is Netplan v1.2.2 from 2026-07-20.

## FAQ

### What is Netplan and which backends does it support?

Netplan is a declarative network configuration tool built around a single YAML file that it renders to whichever backend the system uses. The repository examples include configurations for NetworkManager and Open vSwitch alongside systemd-networkd style interfaces, along with bonding, bridges, VLANs, SR-IOV, Infiniband and tunnel setups.

### How do I build Netplan from source?

The build uses Meson, with meson setup build --prefix=/usr, meson compile -C build, meson test -C build --verbose and meson install -C build --destdir ../tmproot. A Makefile wrapper is provided, with make, make check, make linting, make install and make clean targets.

### How can I test a locally built Netplan without installing it?

Run make and make install, then use make run ARGS="<command>". The wrapper sets environment variables such as NETPLAN_GENERATE_PATH, NETPLAN_CONFIGURE_PATH, LD_LIBRARY_PATH and PYTHONPATH automatically, because the Python CLI resolves binary and library paths at runtime.

### Where do I report bugs for Netplan?

The README asks for bug reports to be filed in Launchpad rather than in GitHub issues. Support questions go to the netplan IRC channel on Libera.Chat or the netplan-developers mailing list.

### What licence is Netplan released under?

Netplan is released under the GPL-3.0 licence, with the terms in the COPYING file at the repository root.

## Sources

- [canonical/netplan on GitHub](https://github.com/canonical/netplan)
- [License: GPL-3.0](https://github.com/canonical/netplan/blob/main/LICENSE)
- [Project website](https://netplan.io)
- [README](https://github.com/canonical/netplan/blob/main/README.md)
- [Releases](https://github.com/canonical/netplan/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/canonical-netplan
