Recently I created a small home lab with some Odroid H3+ boards and a NAS. My plan was to run Ubuntu 20.04 on the Odroids and then use ansible to further configure them. The Ubuntu server install ISO was the easiest way to get Ubuntu installed, but I ran into an issue: The default drivers didn’t work with the Odroid’s network hardware.

Installing the drivers manaully was pretty straight forward (there are packages), but I wanted the whole install process automated to allow me to re-image them quickly when necessary. That lead me down the track of automated Ubuntu installation using cloud-init and autoinstall.

Unfortunately the entire process involved a lot of trial and error, but now that I have it working, I wanted to document it for future reference.

First, some reference material:

After some searching, I ran across this: https://github.com/covertsh/ubuntu-autoinstall-generator

The ubuntu-autoinstall-generator repository contains a bash script that takes an existing installation ISO and creates a copy of it with a user-data configuration file baked into it. Previously, the process involved creating an entirely new “live CD”, but this script incorporates cloud-init and autoinstall which is the new way to do things.

To get started, I created the cloud-init-homelab directory and a file called user-data with the following contents:

#cloud-config
autoinstall:
  version: 1
  interactive-sections:
    - identity
    - storage
  locale: en_US.UTF-8
  keyboard:
    layout: us
  ssh:
    allow-pw: true
    install-server: true
  late-commands:
    - mkdir -p /target/opt/
    - cp -rfv /cdrom/h3-extras /target/opt/
    - curtin in-target --target=/target -- bash -c 'cd /opt/h3-extras; ls; dpkg -i *.deb'
    - curtin in-target --target=/target -- cp /opt/h3-extras/netplan-99-network-manager.yaml /etc/netplan/99-network-manager.yaml
    - curtin in-target --target=/target -- cp /opt/h3-extras/cloud-init-99-custom-networking.cfg /etc/cloud/cloud.cfg.d/99-custom-networking.cfg

The real important thing to note is the cp -rfv /cdrom/h3-extras /target/opt/ command. In the cloud-init-homelab directory is the h3-extras subdirectory. That folder contains all of the additional packages that are installed during the late-commands section.

The h3-extras directory is populated with a few commands:

cat > cloud-init-99-custom-networking.cfg <<EOF
network:
  config: disabled
EOF
cat > netplan-99-network-manager.yaml <<EOF
network:
  version: 2
  renderer: NetworkManager
EOF
apt-get download $(apt-cache depends --recurse --no-recommends --no-suggests --no-conflicts --no-breaks --no-replaces --no-enhances --no-pre-depends network-manager | grep "^\w")
apt-get download $(apt-cache depends --recurse --no-recommends --no-suggests --no-conflicts --no-breaks --no-replaces --no-enhances --no-pre-depends realtek-r8125-dkms | grep "^\w")

One small note with regard to installing network-manager. That command downloads some conflicting ntp packages. The simple solution was to delete those specific deb files from the h3-extras directory.

I also made one small change to the ubuntu-autoinstall-generator.sh at line 215:

cp -rf h3-extras "$tmpdir/"

This copies the h3-extras directory into the $tmpdir/ directory that is used to create the new ISO. When the command is run to create the ISO with ./ubuntu-autoinstall-generator.sh -a -u ./user-data -s ./ubuntu-20.04.6-live-server-amd64.iso -k, mount the ISO with sudo mount -o loop ./ubuntu-autoinstall-2023-08-04.iso /mnt/ubuntu-autoinstall, and inspect the contents via ls /mnt/ubuntu-autoinstall/h3-extras/, we can see all of the included files.

The cloud-init-99-custom-networking.cfg file disables the default cloud-init networking configuration. The netplan-99-network-manager.yaml file configures the netplan to use network-manager.

And that’s it! Write the ISO to a DVD or a USB drive and boot it up. You’ll be prompted to configure storage and identity information (hostname and a username and password). I could probably automate the storage information because all of the Odroid devices are the same, but it’s a pretty quick <enter> through that screen.

Once installation completes, I can log in with the user that I specified during installation. Then configure your devices with nmcli and you’re good to go.