Remove cloud-init with User Data
I have a personal project where I’m working with a lot of IaC (Infrastructure-as-Code). One of my guiding principles is immutability: anything I create should be automatically configured. Manual intervention is forbidden. In addition, if something needs to be changed, the object should be replaced rather than having its state updated (with a few logical exceptions).
I created an image with Packer to serve as the
base for a DigitalOcean Droplet. Custom Images must have cloud-init
installed. Since my
Droplet will never be rebooted or modified after creation I don’t want to keep cloud-init around
once the initialization is complete. Now, the only means of controlling the Droplet is providing
user data, and adding
apt-get remove -y cloud-init
there makes initialization fail because cloud-init has more to do
after the script runs. Instead, I use systemd:
Bashsudo systemd-run -p After=cloud-final.service -p Type=oneshot --no-block bash -c 'apt-get purge -y cloud-init && rm -rf /var/lib/cloud'
This defines a one-off service that runs after cloud-init’s last stage, removes cloud-init and its
paraphernalia, and then exits. There’s no need to wait: the user data script continues immediately
and the service is effectively suspended until everything is ready. Since I put this at the end of
the script—which has set -euxo pipefail
at the beginning—any errors immediately halt execution, so
this line is never reached and I don’t have to worry about it removing logs I need for the purpose
of debugging.