Debian 10, Cloud-init and static IP addresses

In the last two days, I was preparing a virtual environment for some tests about MariaDB replication. I was determined to use the same identical settings of the production machine I was simulating: Debian 10, Docker, MariaDB 10.4. I use terraform for these tests, which works pretty well with the libvirt provider.

Usually, I do some testing using the Ubuntu LTS cloud image (even if I’m using Debian everywhere) due to the easiness of setup. However, in this test, I want to use Debian because I want to be sure about the accuracy of this test.

Yesterday morning I discovered that even Debian has some official cloud-ready images. A quick look on internet and I discovered that genericcloud is what I need.

Long story short, I was using Cloud-init to setup static IP addresses on Debian Buster images. However, the image was still trying the DHCP, and no DNS.

Stable is… too stable?

Digging inside the image, I discovered that Cloud-init was too old (version 18.something), while in the backport repo there was an updated 20. By looking at the behavior of the old and new version, I discovered that the 18 version is creating a file inside the /run/cloud/interfaces.d/ens3 with the correct configuration, which is however ignored, and a similar file is created inside /etc/network/interfaces.d/ens3 with the wrong configuration (eg. DHCP). The updated version instead is writing the latter file correctly (eg. same content of the former), still ignoring the one in /run.

Because there is no cloud-ready version for buster-backports, I decided to compile one on my own, updating cloud-init in order to fix the issue with the network configuration.

I cloned the Debian Cloud images repository and I downloaded the cloud-init deb package inside localdebs/, so the fai-based installer can use that version (as it’s new). Then:

user@debian: ~/debian-cloud-images/localdebs$ apt-ftparchive packages . > Packages

This command is used to generate a valid Packages file for the “local repo”.

What about the DNS?

The fix above is not sufficient to resolve for the DNS. In fact, no /etc/resolv.conf is ever created, neither by cloud-init (with any possible configuration…) or the system itself (which is normal as, by default, it’s missing resolvconf package or any other package which generates that file).

Using runcmd in cloud-init was not an option for me as I was trying to install packages and do other things using cloud-init, so before the runcmd part.

I tried different things:

I ended up editing config_spaces/scripts/LAST/10-cleanup, which is the script that has the duty of cleaning up the image. At the end of the rm command set I wrote something like echo "nameserver 192.0.2.1" > $target/etc/resolv.conf where 192.0.2.1 is your preferred DNS server.

Unfortunately this is not a definitive solution, as DNS servers specified in the cloud-init still gets ignored (at least up until the cloud-init preparation ends). However is a workaround which might be usable. I really hope that these things will be fixed in the next Debian major release.

Build the image

Ah, of course the command for building the image is:

$ make image_buster-backports_genericcloud_amd64

Note: by default these images have no root password in console, and no remote root login capability except for public key auth.

Addendum: download pre-built image

This pre-built image uses 1.1.1.1 DNS and an updated version of cloud-init:

https://drive.google.com/file/d/1GeeFgJwny478c1VCEnKf1Tsba3WUhyr2/view?usp=sharing