Netplan network configuration tutorial for beginners

Netplan is a utility developed by Canonical, the company behind Ubuntu. It provides a network configuration abstraction over the currently supported two “backend” system (“renderer” in Netplan terminology): networkd and NetworkManager. Using Netplan, both physical and virtual network interfaces are configured via yaml files which are translated to configurations compatible with the selected backend.

In this article we learn about Netplan and we see how can we use it to setup network interfaces on recent versions of Ubuntu.

In this tutorial you will learn:

  • The basic structure of yaml configuration files used by Netplan
  • How to create a simple rule to assign a static IP to a network interface
  • How to test and apply a netplan configuration

Netplan network configuration tutorial for beginners

Netplan network configuration tutorial for beginners

Software requirements and conventions used

Software Requirements and Linux Command Line Conventions
Category Requirements, Conventions or Software Version Used
System Ubuntu >= 20.04 (Focal Fossa)
Software Netplan (installed by default)
Other Root permissions to modify configuration files
Conventions # – requires given linux-commands to be executed with root privileges either directly as a root user or by use of sudo command
$ – requires given linux-commands to be executed as a regular non-privileged user

Netplan configuration files

Since Ubuntu 20.04 Netplan replaced the traditional method of configuring network interfaces using the /etc/network/interfaces file; it aims to make things easier and more centralized (the old way of configuring interfaces can still be used: check our article about How to switch back networking to /etc/network/interfaces on Ubuntu 20.04 Focal Fossa Linux).

There are three locations in which Netplan configuration files can be placed. In order of priority they are:

  1. /run/netplan
  2. /etc/netplan
  3. /lib/netplan

Netplan design overview

Netplan design overview


Inside each of those directories, configurations are created using files with the .yaml extension which are processed in lexicographical order, regardless of the directory they are in. Directory priority has a role only when files with the same name exist: in those cases, only the file contained in the directory with the higher priority is parsed. If a boolean or scalar parameter is defined in more than one configuration file, it assumes the value it has in the last file that is parsed; if the values are sequences, instead, they are concatenated.

Users are supposed to place their configurations inside the /etc/netplan directory. By default, the only files present on a fresh installed Ubuntu 24.04 system are /etc/netplan/01-network-manager-all.yaml and /etc/netplan/50-cloud-init.yaml. Let’s take a look at the instructions they contain.

The /etc/netplan/01-network-manage-all.yaml file

The first configuration file we can find in the /etc/netplan/ directory is 01-network-manager-all.yaml. It contains the following instructions:

# Let NetworkManager manage all devices on this system
network:
  version: 2
  renderer: NetworkManager

As suggested by the comment in the file, the configuration is used to let the NetworkManager renderer manage all the network interfaces on the system. We can observe that directives are indented inside the main key, network. Since we are dealing with yaml files, the indentation is crucial.

The other two keywords we can find in the file are version and renderer: the former indicates the syntax version in use, the latter is used to specify the renderer we want to use.

The /etc/netplan/50-cloud-init.yaml file

The second file in the /etc/netplan directory is 50-cloud-init.yaml. This file is generated by cloud-init, a tool created by Canonical to perform early initializations and customizations of Linux systems. Here is the content of the file on my virtualized instance of Ubuntu:

# This file is generated from information provided by the datasource. Changes
# to it will not persist across an instance reboot. To disable cloud-init's
# network configuration capabilities, write a file
# /etc/cloud/cloud.cfg.d/99-disable-network-config.cfg with the following:
# network: {config: disabled}
network:
    ethernets:
        enp1s0:
            dhcp4: true
    version: 2

What this configuration accomplishes? It enables dhcp for IPv4 addresses on the enp1s0 network interface, which is the only one on my machine. As stated in the comments at the beginning of the file, changes to this configuration will not survive an “instance reboot”. This doesn’t mean the file will be reset at each reboot, but that changes will not persist if cloud-init has yet to run (it runs at first boot – this message has sense in the context of base system-images for containers and similar environments), or if we force a re-run, which is a potentially destructive operation.

In all cases, to prevent cloud-init from performing network configurations, all we have to do is to create the /etc/cloud/cloud.cfg.d/99-disable-network-config.cfg file with the following content:

network: {config: disabled}

We can do it by running:

$ echo "network: {config: disabled}" | sudo tee /etc/cloud/cloud.cfg.d/99-disable-network-config.cfg

In the next section of this tutorial we will create a slightly more complex configuration example, and we will use it to assign a static IPv4 address to a network interface.

A Configuration example – setting a static IPv4 address

The configuration files we saw until now are quite basic; let’s try something a little bit more complex and see how can we configure a static IPv4 address using Netplan. The first thing we must to do is to create a new configuration file to be parsed after the default ones. For the moment, we store it as /tmp/60-static-ip.yml. Inside the file, we create a rule to match the network interface(s) we want to setup by using the match mapping, in which we specify network interfaces properties and their values as key-value pairs. All of them must match for the rule to be applied:

# Set static ip address for enp1s0 interface
network:
    version: 2
    renderer: NetworkManager
    ethernets:
        id0:
            match:
                name: enp1s0
            dhcp4: false
            addresses:
                - 192.168.122.250/24
            nameservers:
                addresses:
                    - 192.168.122.1
            routes:
                - to: default
                  via: 192.168.122.1

Let’s take a closer look to the new instructions we used in the configuration. Inside the main network node, devices can be grouped by their type:

  • ethernets
  • wifis
  • bridges


Since in our example we our dealing with an ethernet interface, we used ethernets. Inside the match mapping, we referenced the interface by its name: enp1s0. Match rules can also be based on macaddress and, only when using networkd as the renderer, on driver which is the Linux kernel driver name used for the device(s).

Since our goal was to assign a static address, we disabled dhcp4 setting it to “false”, and used the addresses key to associate an IPv4 address to the interface. Multiple addresses can be specified; they must be provided together with their subnet mask.

We also set the addresses of the nameservers in the corresponding mapping. Finally, we set the IPv4 address of the gateway to be used by the interface via the routes key, which accepts a sequence of mappings as value. In each of those mappings, we can use the to, keyword to specify the destination address for the route (here “default” is an alias for 0.0.0.0), and via to specify the gateway address. In previous versions of Netplan the static gateway IP was configured via the gateway4 key, but it is now deprecated.

Simplifying the configuration

The configuration we used in the example above can be simplified. To reference the interface we want to assign the static address to, we used match, but we could have omitted it. Since we want our settings to be applied to a single specific interface, we can reference it directly using its predictable name as id:

network:
    version: 2
    renderer: NetworkManager
    ethernets:
        enp1s0:
            dhcp4: false
            addresses:
                - 192.168.122.250/24
            nameservers:
                addresses:
                    - 192.168.122.1
            routes:
                - to: default
                  via: 192.168.122.1

When match is used, the id (id0 in the previous example) is arbitrary and its used to reference the configured device(s) from other sections of the configuration file; when match is omitted, instead, the id must correspond to the device predictable name. At this point our configuration is ready; all we should do is test it and apply it.

Testing and applying a Netplan configuration

It’s time to test our configuration, and see if it works correctly. To achieve our goal we can use the netplan utility and the try subcommand, which, as its name suggests, is used to try a configuration and optionally discard it after a certain amount of time (the default timeout is of 120 seconds, but it can be changed using the --timeout option).

As you can see from the output of the ip address command, the current IPv4 address of the enp1s0 interface is 192.168.122.200:

$ ip address|grep enp1s0
2: enp1s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    inet 192.168.122.200/24 brd 192.168.122.255 scope global dynamic noprefixroute enp1s0

Let’s try the configuration we created in the previous step. We pass the path of the configuration file as argument to the --config-file option:

$ sudo netplan try --config-file /tmp/60-static-ip.yaml

Once we run the command, the following prompt appears on screen:

Do you want to keep these settings?


Press ENTER before the timeout to accept the new configuration


Changes will revert in 120 seconds

We have enough time to very if the IP address of the interface changed. From another shell instance, we run:

$ ip address | grep enp1s0
2: enp1s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    inet 192.168.122.250/24 brd 192.168.122.255 scope global dynamic noprefixroute enp1s0


As we can see, the IPv4 address changed as expected. At this point if we are satisfied with the result of our configuration, we can press “Enter” at the prompt, and the configuration file will be copied under the /etc/netplan directory, with a random suffix. If we don’t want to accept the changes, we just wait for the command to timeout, or, if possibile, interrupt it by pressing CTRL+c.

To apply the configuration without trying it first, we can copy the file directly under the /etc/netplan directory, and issue the netplan apply command.

Conclusions

In this tutorial we approached Netplan, a utility developed by Canonical to abstract network interfaces configuration using yaml files. Netplan is active by default since Ubuntu 20.04 Focal Fossa. In this tutorial we saw how to write a simple rule to set a static IP address for a network interface, and we saw how to test and apply changes via the try and apply subcommands of the netplan utility. We barely scratched the surface of what can be accomplished using Netplan; if you want to know more about it, please take a look at the Netplan website, and at the manpage of the utility.