I have an DigitalOcean server that's being configured via cloud-init. With Ubuntu Bionic Beaver, this creates a netplan file in /etc/netplan/50-cloud-init.yaml that contains nameserver addresses. However, overriding these addresses is not straightforward.

On Bionic Beaver, /etc/resolv.conf is managed by the systemd-resolved service. I can edit the global nameservers like so:

echo 'DNS=' >> /etc/systemd/resolved.conf
service systemd-resolved restart

However, this doesn't affect the interface-specific nameservers set up by cloud-init. For that, I have to edit the netplan file directly or override it somehow. I can edit the file directly, but this isn't very automation-friendly. The netplan documentation says there's a hierarchy for netplan YAML files:

Configuration files can exist in three different locations with the precedence from most important to least as follows:

  • /run/netplan/*.yaml
  • /etc/netplan/*.yaml
  • /lib/netplan/*.yaml

Alphabetically later files, no matter what directory in, will amend keys if the key does not already exist and override previous keys if they do.

Given this, I wrote an "alphabetically later file" as follows:

# /etc/netplan/51-cloudflare-dns.yaml

Given the guidance above, I expected this to replace the nameservers for eth0 with the new ones applied. However, running netplan apply appended to the list of nameservers for the interface rather than replacing them, as seen with systemd-resolve --status:

Link 2 (eth0)
      Current Scopes: DNS
       LLMNR setting: yes
MulticastDNS setting: no
      DNSSEC setting: no
    DNSSEC supported: no
         DNS Servers:

How can I override netplan's per-interface nameservers, rather than appending to them? Both file-based and command-line solutions that persist across reboots are welcome.

  • Question, you've said that editing the yaml file isn't very automation friendly; in what sense? Do you mean it's easier to enabling/disabling a single conf file to change the dns servers field? On my servers, I automate the DNS fields using a python script which reads and writes yaml files, so I'm automating this step in fact. It may be simplest to give you a python script that does just that. – Mercury00 Feb 5 '19 at 17:21

This is the only way I have found:

Rename /etc/netplan/50-cloud-init.yaml to /etc/netplan/51-network-settings.yaml and edit it with the changes you want. Make sure to remove the old version of the file to prevent your nameservers from getting appended to the old ones. Then create a file named something like /etc/cloud/cloud.cfg.d/99-disable-network-config.cfg with the contents network: {config: disabled}, which will prevent cloud-init from recreating its output file.

The downside of this is if the network configuration changes otherwise, as cloud-init will not be managing the settings any more. I suppose it would be better to configure cloud-init to change just the nameservers, but I didn't find a way to do that.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.