The Infrastructure
Considerations
Last time I had played around with NGINX I found the user system very confusing, as well as the multiple ways to enable sites through confs and/or symlinks. I found it very easy to get the VM into such a state that it wasn’t worth trying to fix it again.
I needed a way to easily create a VM on UnRaid and get it to a known state automatically. Essentially creating a cloud-like infrastructure where I could boot VM’s into a known state just like provisioning a droplet or instance in the cloud.
And yes this could be an argument for containerisation to do this, one day I’ll write a post with my thoughts around docker. While useful and definitely having a place it also introduces another layer of complexity that I didn’t want to deal with for now.
Automating an Ubunut server install on Unraid.
Ubuntu uses autoinstallation which can be thought of as an extension to could-init. All the docs available here : Ubunto Auto Install. But these docs are just insane, and probably only make sense if you are generating a truly cloud infrastructure. Way beyond what we need. The quickstart is impenetrable to someone of my skillset!
Firstly, I created a new VM interactively then took the sample-user data file at:
/var/log/installer/autoinstall-user-data
This was overly complex and way to specific for our needs and if used again on another VM it would error out due to subtle changes in storage devices. I ran it through ChatGPT to make it more general and it came up with something like this:
apt:
geoip: true
preserve_sources_list: false
identity:
hostname: genericvm
password: XXXXXX
realname: XXXXXX
username: XXXXXX
keyboard:
layout: us
locale: en_US.UTF-8
network:
ethernets:
enp1s0:
dhcp4: true
version: 2
ssh:
allow-pw: false
install-server: true
storage:
layout:
name: direct
updates: security
version: 1
Change the user and password and hostname to your needs. Remember the password field is encrypted, see: Passwords
Note that this install has no SSH password and no keys. Be careful you can easily lock yourself out.
The full userdata file is available in the infra repo at:
https://github.com/abl030/infra/blob/main/UnRaid_AutoInstall_VM/user-data
User-Data
Next we need to run some commands on the first boot. This is annoying and took the longest for me to figure out, because runcmd is within user-data which is within autoinstall. I had my formatting wrong because I was reading the cloud-init docs.
In any case here’s what I came up with:
user-data:
runcmd:
#this line just tests the runcmd, delete it or least change the user folder to the appropriate username
- touch /home/abl030/test
- apt update
- apt upgrade -y
- apt autoremove -y
- curl -fsSL https://tailscale.com/install.sh | sh
#replace authkey with your tailscale authkey
- tailscale up --authkey=tskey-auth-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
- tailscale set --ssh
- tailscale set --auto-update
#edit our unattended-upgrades file to automatically update everything, remove unused packages and also reboot when required.
- sed -i '/"${distro_id}:${distro_codename}-updates"/s/^\/\/\s*//; /"${distro_id}:${distro_codename}-proposed"/s/^\/\/\s*//; /"${distro_id}:${distro_codename}-backports"/s/^\/\/\s*//' /etc/apt/apt.conf.d/50unattended-upgrades
- sed -i 's#//Unattended-Upgrade::Remove-Unused-Dependencies "false";#Unattended-Upgrade::Remove-Unused-Dependencies "true";#' /etc/apt/apt.conf.d/50unattended-upgrades
- sed -i 's#//Unattended-Upgrade::Automatic-Reboot "false";#Unattended-Upgrade::Automatic-Reboot "true";#' /etc/apt/apt.conf.d/50unattended-upgrades
- systemctl restart unattended-upgrades.service
#update timezone so logs make sense
- timedatectl set-timezone Australia/Perth
In this we update the VM, install tailscale, auto log in and let tailscale manage our SSH. Set unattended upgrades to do its thing and also set the timezone. This just ensures a nice base for our VM that updates itself, security is emphasised over downtime in this instance.
Tailscale SSH is also nice, means no port forwarding, no port 22 out on the open internet and tailscale can handle all authentication in a central place.
In the next post I’ll talk about getting this user data file into the ubuntu ISO.