Ubuntu Netplan Tutorial

Khimananda Oli 8 min read Virtualization
Ubuntu Netplan Tutorial

By Khimananda Oli | Last reviewed: August 2026

Managing network interfaces on modern Ubuntu servers requires mastering Netplan, the declarative YAML-based configuration utility that replaced legacy /etc/network/interfaces. This Ubuntu Netplan tutorial provides the exact syntax and validation workflows needed to configure static IPs, bonds, and VLANs without locking yourself out of production systems. Whether you are performing an initial Ubuntu server setup or migrating legacy configurations, understanding this abstraction layer is mandatory for reliable infrastructure.

How does Ubuntu Netplan architecture differ from legacy networking?

Before writing any configuration, you must understand that Netplan is not a network daemon itself; it is a translation layer. In previous Ubuntu releases, administrators edited ifupdown scripts directly. Since Ubuntu 17.10, Netplan reads YAML descriptions from /etc/netplan/*.yaml and generates backend-specific configurations for either systemd-networkd or NetworkManager. This separation means your YAML must be syntactically perfect, as indentation errors will cause the parser to fail silently or reject the entire configuration block.

Netplan YAML/etc/netplan/*.yamlNetplan CLIGenerator & Parsersystemd-networkdServer / HeadlessNetworkManagerDesktop / WiFi
Figure 1: Netplan acts as an abstraction layer, translating YAML definitions into backend-specific configs for systemd-networkd or NetworkManager.

The choice of renderer matters significantly. For headless servers, cloud instances, and containers, networkd is the standard due to its low overhead and tight integration with systemd. For desktops or machines requiring WiFi roaming and GUI management, NetworkManager is appropriate. Mixing renderers across different interface stanzas in the same file is technically possible but operationally dangerous; pick one per system unless you have a documented reason to split them. When automating server provisioning via tools like Ansible or cloud-init, always target networkd to ensure predictable behavior across reboots.

How do you configure a static IP address with Netplan?

Setting a static IP is the most common task in this Ubuntu Netplan tutorial. Unlike legacy tools where you might specify a netmask like 255.255.255.0, Netplan strictly uses CIDR notation. You must also explicitly define default routes and DNS servers, as these are no longer inherited automatically when switching from DHCP to static addressing.

Identifying your interface name

Never guess interface names. Use ip link show or ls /sys/class/net/ to confirm the exact kernel-assigned name. On modern Ubuntu, expect predictable naming like enp3s0 or ens18 rather than eth0. Using the wrong name will result in a valid YAML file that applies to nothing, leaving your server unreachable.

Writing the static configuration

Create or edit your configuration file. The filename order matters; Netplan processes files alphanumerically. Standard practice is 01-netcfg.yaml or 00-installer-config.yaml.

# /etc/netplan/01-static-ip.yaml
network:
  version: 2
  renderer: networkd
  ethernets:
    enp3s0:
      dhcp4: false
      addresses:
        - 192.168.10.50/24
      routes:
        - to: default
          via: 192.168.10.1
          metric: 100
      nameservers:
        addresses:
          - 1.1.1.1
          - 8.8.8.8
        search:
          - internal.example.com

Several details here trip up experienced engineers. The addresses key takes a list, even for a single IP. The routes section replaces the old gateway4 directive, which is now deprecated in newer Netplan versions. Always use the explicit to: default route syntax for forward compatibility. The metric value becomes critical when multiple interfaces exist; lower metrics win for default routing. If you are configuring UFW alongside this, remember that Netplan applies before firewall rules, so ensure your new subnet is allowed.

Validating and applying safely

Never run netplan apply blindly on a remote server. Use the safety mechanism first:

sudo netplan try

This command validates the YAML syntax, applies the configuration temporarily, and waits for user confirmation. If you lose connectivity or fail to press ENTER within 120 seconds, it automatically reverts to the previous working configuration. This is your primary defense against lockouts. Only after confirming connectivity should you run sudo netplan apply to make changes persistent.

How do you configure bonding and VLANs for high availability?

Production environments rarely rely on single links. Bonding (link aggregation) and VLAN tagging provide redundancy and segmentation. Netplan handles these natively, but the hierarchy requires careful indentation. A common mistake is defining physical interfaces and bonds at the same level without proper referencing.

enp3s0Physical NIC 1enp4s0Physical NIC 2bond0802.3ad LACPbond0.100VLAN Tag 100Key Parametersmode: 802.3adlacp-rate: fasttransmit-hash-policy: layer3+4id: 100 (VLAN)
Figure 2: High-availability topology combining LACP bonding with VLAN tagging for segmented production traffic.

Below is a complete configuration for an active-active LACP bond with a tagged VLAN. Note that physical interfaces listed under bond0 must not have their own IP addresses or DHCP settings; they become raw slaves.

network:
  version: 2
  renderer: networkd
  ethernets:
    enp3s0:
      dhcp4: false
    enp4s0:
      dhcp4: false
  bonds:
    bond0:
      interfaces: [enp3s0, enp4s0]
      parameters:
        mode: 802.3ad
        lacp-rate: fast
        transmit-hash-policy: layer3+4
      dhcp4: false
      addresses:
        - 10.0.0.10/24
      routes:
        - to: default
          via: 10.0.0.1
  vlans:
    bond0.100:
      id: 100
      link: bond0
      addresses:
        - 172.16.100.10/24
      nameservers:
        addresses: [10.0.0.2]

The transmit-hash-policy: layer3+4 setting ensures traffic distribution based on IP and port pairs, preventing out-of-order packets that plague simpler MAC-based hashing. For switches that don't support LACP, use mode: balance-alb or active-backup. Always verify switch-side configuration matches your Netplan bond mode; mismatched LACP settings are the number one cause of intermittent packet loss in bonded setups.

What are the critical differences between Netplan and legacy ifupdown?

Engineers migrating from Debian or older Ubuntu releases often attempt to translate concepts directly, leading to subtle failures. Understanding these architectural shifts prevents hours of debugging.

FeatureLegacy ifupdownNetplan (2026 Standard)
Configuration FormatFlat text /etc/network/interfacesHierarchical YAML in /etc/netplan/
ValidationRuntime only (ifup/ifdown)Pre-apply syntax check + rollback
Backend AbstractionDirect kernel/ioctl callsGenerates networkd or NM configs
Hot ReloadingManual ifdown/ifup cycleAtomic apply with transaction safety
Cloud IntegrationRequires custom scriptsNative cloud-init datasource support
Bond/VLAN SyntaxSeparate iface stanzasNested under bonds/vlans keys

The most significant operational difference is atomicity. Legacy ifup could leave a system in a half-configured state if a command failed mid-execution. Netplan generates all backend configs in a temporary location and swaps them atomically. This aligns with modern idempotent infrastructure principles where partial states are treated as failures. Additionally, Netplan's integration with cloud-init means that on AWS, Azure, or GCP, the platform's metadata service can inject network config that merges cleanly with your base YAML, something impossible with static ifupdown files.

How do you troubleshoot Netplan configuration failures?

Even with validation, issues arise. Debugging requires moving beyond "it didn't work" to systematic diagnosis. Start by checking the generated backend files. If using networkd, inspect /run/systemd/network/ to see what Netplan actually produced. Discrepancies between your YAML and generated files indicate parser misunderstandings or version-specific feature gaps.

  1. Verify YAML structure: Use python3 -c "import yaml; yaml.safe_load(open('/etc/netplan/01-netcfg.yaml'))" to catch pure syntax errors independent of Netplan's parser. Indentation mistakes are the most frequent culprit.
  2. Check backend status: Run systemctl status systemd-networkd and journalctl -u systemd-networkd -xe. Netplan may succeed while networkd fails to bring up an interface due to missing firmware or driver issues.
  3. Validate interface naming: If your config applies but doesn't take effect, run udevadm info /sys/class/net/enp3s0 to confirm the kernel sees the device. Predictable names can change after hardware swaps or BIOS updates.
  4. Test rollback manually: Intentionally break a config and time how long netplan try takes to revert. Know this window before relying on it during maintenance windows.
  5. Audit permissions: Netplan refuses to read world-readable YAML files containing sensitive data. Ensure permissions are 600 or 644 owned by root. This is especially relevant when managing secrets in automation pipelines that deploy network configs.
Config Not Applying?Run: sudo netplan generateFAILSSUCCESSYAML Syntax ErrorFix indentation/typesCheck Backend Logsjournalctl -u systemd-networkdVerify Interface Namesip link / udevadm infoCheck Switch/Firmware
Figure 3: Systematic troubleshooting flow isolating YAML parsing errors from runtime backend failures.

A frequent hidden failure occurs when multiple Netplan files conflict. If 01-netcfg.yaml defines enp3s0 with DHCP and 02-custom.yaml defines the same interface statically, the last file processed wins for overlapping keys, but merging behavior for lists like addresses can be unpredictable. Consolidate interface definitions into single files whenever possible. When managing fleets with configuration management tools, use distinct filenames per concern (e.g., 01-base.yaml, 02-bonds.yaml) and ensure no interface appears in more than one file.

Next steps for production-ready networking

This Ubuntu Netplan tutorial covers the core patterns you will encounter in 90% of server deployments. Mastery comes from treating network configuration as code: version control your YAML files, validate them in CI before deployment, and always test changes with netplan try before permanent application. Remember that Netplan is merely the declaration layer; true reliability depends on understanding the underlying systemd-networkd or NetworkManager behavior it orchestrates. For teams building automated infrastructure, integrate Netplan validation into your pipeline alongside Terraform and Ansible checks to catch misconfigurations before they reach production. If you need help auditing your network automation strategy or designing compliant infrastructure, reach out to discuss your environment.

Frequently Asked Questions

Netplan is the default network configuration utility for Ubuntu since 17.10, replacing ifupdown. It uses YAML files to define interfaces and generates backend configs for systemd-networkd or NetworkManager, providing a unified declarative approach across server and desktop environments in 2026.

Configs live in /etc/netplan/ with .yaml extensions. The system reads them alphabetically, so 01-netcfg.yaml applies before 99-custom.yaml. Always edit these files directly rather than modifying generated backend configurations to prevent overwrites during updates or reboots.

Run sudo netplan try first to validate syntax and test connectivity with an automatic rollback timer. If the connection survives the timeout, confirm with sudo netplan apply. This prevents lockouts when configuring remote servers over SSH without console access.

Yes, but not simultaneously on the same interface. Set renderer: networkd for headless servers or renderer: NetworkManager for desktops in your YAML. Mixing renderers across different interfaces works but complicates troubleshooting and is generally discouraged in production deployments.

Define addresses under dhcp4: false with a CIDR notation like 192.168.1.10/24. Add routes with to: default and via: gateway_ip. Specify nameservers as a list under nameservers: addresses:. Always validate indentation since YAML parsing errors silently fail without clear feedback.

Common causes include incorrect YAML indentation, missing required keys like renderer, or duplicate interface definitions. Check journalctl -u systemd-networkd for backend errors. Use netplan generate --debug to see parsed output and identify which file contains the syntax problem before applying.

If locked out, access the server via console and restore from backup or edit the YAML manually. For active sessions, netplan try auto-reverts after 120 seconds by default. You can also run netplan apply --rollback immediately if you catch the issue within the grace period.

Yes. Define vlans: under the parent physical interface with id: and optional link:. Each VLAN gets its own DHCP or static config block. Ensure the parent interface has no direct IP assignment when using tagged VLANs to avoid routing conflicts and unexpected behavior.

Use wifis: section with access-points containing ssid and password fields. Set renderer: NetworkManager since systemd-networkd lacks wireless support. Install wpasupplicant package first. Note that WiFi via Netplan is uncommon on servers and typically reserved for edge or IoT deployments.

Yes. Define bonds: with interfaces listing member NICs and parameters like mode: 802.3ad for LACP. Configure lacp-rate and transmit-hash-policy as needed. Member interfaces must not have their own IP settings. Test failover scenarios thoroughly before deploying bonded links in production.

Create /etc/cloud/cloud.cfg.d/99-disable-network-config.cfg containing network: {config: disabled}. Cloud-init regenerates Netplan files on every boot otherwise, overwriting manual edits. This step is critical for persistent custom networking on AWS EC2, Azure VMs, or other cloud instances running Ubuntu 24.04 LTS.

Files must be owned by root with mode 0600. Netplan refuses to read world-readable configs as a security measure since they may contain WiFi passwords or sensitive network topology data. Fix permissions with chmod 600 /etc/netplan/*.yaml if you encounter permission denied errors during apply.

Check resolved status with resolvectl status and verify nameservers appear correctly. Inspect /run/systemd/resolve/resolv.conf for actual resolver config. Ensure systemd-resolved service is active. Misconfigured DNS often stems from missing nameservers key or conflicting DHCP options overriding static entries in your YAML definition.

No. Netplan was introduced in Ubuntu 17.10 and became mandatory in 18.04 LTS. Systems running 16.04 or earlier still use ifupdown with /etc/network/interfaces. Upgrading requires migrating configs manually; there is no automated conversion tool, so plan downtime and test thoroughly before upgrading legacy systems.

Use netplan generate to parse all configs without activating them. This catches syntax errors, undefined references, and invalid parameter combinations. Combine with yamllint for stricter formatting checks. Always validate in CI pipelines or pre-commit hooks to prevent broken network configs from reaching production servers.