Netplan on Ubuntu: Declarative Networking Without the Lockout Panic
Netplan turns Ubuntu network config into declarative YAML rendered by systemd-networkd or NetworkManager. Here's how to set a static IP safely with netplan try, and where the abstraction ends.
09 May 2026, 08:17 UTC

If you have ever edited a network config on a remote Ubuntu server, hit apply, and watched your SSH session freeze mid-keystroke, you already understand the problem Netplan is trying to solve — and the one it can still create. Netplan gives you a single, declarative YAML file to describe your network, but a typo in that file can cut you off from the machine just as efficiently as the old /etc/network/interfaces ever did.
The useful takeaway: Netplan is an abstraction layer, not a network stack. It translates your YAML into configuration for a real backend — either systemd-networkd (the default on servers) or NetworkManager (the default on desktops). Once you treat it as a compiler for network config rather than the network itself, the tooling and the failure modes both make more sense.
How the pieces fit together
Netplan reads every .yaml file in /etc/netplan/, merges them (files are processed in lexical order, so 99-custom.yaml overrides earlier files), and renders backend-specific configuration. With the networkd renderer, that means files under /run/systemd/network/ that systemd-networkd consumes. With NetworkManager, it writes connection profiles NetworkManager picks up.
This matters for debugging: if the network misbehaves after a successful netplan apply, Netplan itself is done — you need to look at the renderer. On a server, that means journalctl -u systemd-networkd and networkctl status, not more YAML edits.
A worked example: static IP on a server
Say you have a fresh Ubuntu Server 22.04 or 24.04 install and want a static address on interface enp1s0. First, confirm the interface name with ip link — never guess it. Then create or edit a file as root, e.g. /etc/netplan/01-static.yaml:
network:
version: 2
renderer: networkd
ethernets:
enp1s0:
dhcp4: false
addresses:
- 192.168.1.50/24
routes:
- to: default
via: 192.168.1.1
nameservers:
addresses: [192.168.1.1, 1.1.1.1]Two things to note. First, YAML is strictly indentation-sensitive — use spaces, not tabs, and keep nesting consistent. A misindented file fails parsing, which is annoying but safe. Second, the routes block shown here is the modern syntax; older guides use gateway4, which is deprecated in current releases but still widely copied around.
Before committing anything on a machine you can only reach over SSH, run:
sudo netplan tryThis applies the configuration temporarily. If it works, press Enter to confirm within the timeout. If it breaks connectivity — wrong gateway, wrong interface name — Netplan reverts automatically when the timeout expires, and your session (or a fresh one) comes back. This is the single most valuable command in the toolset for remote work. Only after a successful netplan try should you treat the config as permanent; a plain sudo netplan apply makes changes immediately with no safety net.
Then verify from the machine itself:
ip addr show enp1s0
ip route
networkctl status enp1s0
resolvectl statusCheck that the address, the default route via 192.168.1.1, and DNS resolution all match what you declared. A quick ping -c 3 192.168.1.1 and a DNS lookup confirm both layers.
Choosing a renderer
The default split is sensible: servers use networkd, desktops use NetworkManager. The practical reason to override it is tooling. If you manage a laptop or a machine where users expect to join Wi-Fi networks from a GUI or nmcli, set renderer: NetworkManager and let Netplan hand off the device. If you want a headless server with bridging, VLANs, or bonding described entirely in YAML, networkd keeps everything in systemd-land with predictable logging.
Mixing is possible — you can declare some interfaces under one renderer and others under the second — but it complicates debugging, since you now have two daemons to interrogate. Keep it simple unless you have a concrete reason.
The trade-offs
Netplan's abstraction is also its limit. It deliberately exposes a common subset of features; renderer-specific knobs (advanced NetworkManager settings, exotic systemd-networkd options) may not be expressible in YAML and require dropping down to the backend's own config files — at which point you are maintaining two layers. And because Netplan only manages the renderers, netplan apply succeeding tells you nothing about whether the network actually works; verification with ip and networkctl is not optional.
Syntax and available keys also vary by Netplan version, so check netplan --version and the documentation matching your Ubuntu release before copying examples from older blog posts.
Closing advice
Treat Netplan edits like firewall rule changes: make them small, test with netplan try whenever the machine is remote, and verify with ip addr, ip route, and networkctl status afterward. The YAML layer genuinely does make static IPs, bridges, and DNS configuration more uniform across Ubuntu systems — as long as you remember the real network lives one layer below.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.