Overriding netplan config managed by cloud-init on an existing Digital Ocean Ubuntu droplet
(please excluse any bad formatting, still haven’t moved this away from tumblr…)
I saw a bunch of suggestions out there for doing this which have you entirely disable cloud-init’s management of the network settings. I didn’t want to do that, I just want to change the DNS servers away from DO’s default of Google’s DNS and to a local unbound service running on the droplet.
It’s easy enough to edit /etc/systemd/resolved.conf and set DNS= there, but that still leaves Google’s servers in the netplan config for the default interface which may be used as fallback.
Here’s the relevant part of the netplan config on a Ubuntu 24.04:
# /etc/netplan/50-cloud-init.yaml
network:
version: 2
ethernets:
eth0:
match:
macaddress: …
addresses:
- …
nameservers:
addresses:
- 8.8.8.8
- 8.8.4.4
search: []
It doesn’t look like simply dropping a new network configuration in /etc/cloud/cloud.cfg.d/ will do what I want. It doesn’t seem to do anything at all (local configs run too early/late?), but even if it did, I’m also concerned it might overwrite the whole netplan config I’m trying to preserve. So instead, I’m going to use the runcmd directive to call netplan directly.
I added the following to /etc/cloud/cloud.cfg.d/99-local-dns.cfg:
#cloud-config
runcmd:
- |
netplan set network.ethernets.eth0.nameservers=null \
&& netplan set network.ethernets.eth0.nameservers=“{ \
addresses: [127.0.0.1], \
search: [] \
}” \
&& netplan apply
The reason I’m setting nameservers to null instead of setting nameservers.addresses directly is because “netplan set” will simply append when applied to a list.
Rebooted, and confirmed.
# /etc/netplan/50-cloud-init.yaml
network:
version: 2
ethernets:
eth0:
match:
macaddress: …
addresses:
- …
nameservers:
addresses:
- 127.0.0.1
search: []
$ resolvectl status
…
Link 2 (eth0)
Current Scopes: DNS
Protocols: +DefaultRoute -LLMNR -mDNS -DNSOverTLS DNSSEC=yes/supported
Current DNS Server: 127.0.0.1
DNS Servers: 127.0.0.1
…