Updated on 16 Jan, 2022. I worte a post for Ubuntu 20.04 Server.

It will be convenient if the installation is fully automated when configuring multiple nodes at the same time. However, I believe Ubuntu doesn't care about unattended installation via the CD image. Its developers seem to be unwilling to write a detailed tutorial about that, even some changes they made make trouble unintentionally. Note that installing via PXE Network Boot is a good alternative.

## Before getting hands dirty

An unnoticeable fact is that Ubuntu Server replaced its installer silently, which means some tutorials are actually not applicable for specific versions of Ubuntu. According to my observation, we have two installers so far,

• Before Ubuntu 18.04.3: Debian-Installer, a non-live installer
• Ubuntu 18.04.4~18.04.5: Old version of subiquity, a live installer, without unattended installation support
• There are two varients, (thanks for jack's comment)
• one is called non-live version with Debian-Installer
• another is called live version with old version of subiquity, which doesn't have unattended installation support
• Ubuntu 20.04: subiquity, a live installer, with unattended installation support

Consider that Ubuntu 18.04 has excellent compatibility, this tutorial aims at making Ubuntu 18.04.5 Installation ISO. As for Ubuntu 20.04 users, please refer to this tutorial https://gist.github.com/s3rj1k/55b10cd20f31542046018fcce32f103e or my newer blog post for your information, and you can still read this tutorial because some approaches mentioned in this article also work.

Since Ubuntu 18.04.4~18.04.5 doesn't support unattended installation, we have to use Ubuntu 18.04.3 as the original version. Note that this version is deprecated. Thus it can only be downloaded from old-releases site. Make sure what you download is a non-live version, such as,

There is an excellent tool called cubic, which helps us decompress and repack the ISO file and rootfs image. Also, it will automatically set up the virtual environment (chroot), where modifying the root filesystem is quite easy, just like operating a regular Ubuntu.

Run cubic command in the terminal to launch this program.

## Modify Root Filesystem

Generally speaking, all the files existing in the virtual environment will be directly copied to the machine where this system is installed, except several files generated during installation. Thus, you can preinstall some software in this step.

Consider that Ubuntu 18.04.3 is a bit outdated, so some build-in software should be upgraded.

Note:

• The Linux Kernel has been installed in this stage, and it will be installed by Debian-installer during installation. Therefore, you still need to perform apt upgrade after installation.
• You can change an APT repository in the virtual environment, but the file /etc/apt/source.list will be replaced by Debian-installer or cloud-init eventually.
• SSH server could be installed in advance to save some time in installing OS, and cloud-init will regenerate SSH-key during the first boot.

### Write Post-Installation Script

cloud-init is widely used in the cloud industry to initialize the system during the first boot. In fact, we could utilize it to do post-installation configuration. It is recommended to refer to these examples to customize your script: https://cloudinit.readthedocs.io/en/latest/topics/examples.html.

I attach my script located at /etc/cloud/cloud.cfg.d/20-asc-init.cfg here for your reference.

### Optional: Configure DHCP for all network interfaces after installation

Debian-installer has a known bug: netcfg/choose_interface=auto fails to pick the functional network interface from many ones. Meanwhile, cloud-init also only configure one interface since most of the cloud instances only have one. If your machine happens to have one interface, you can skip this part. Otherwise, you need a workaround.

I wrote a script /usr/bin/asc_init_net to automatically generate configuration file for Netplan during post-installation. All interfaces will contact the DHCP server to get available IP addresses simultaneously. Of course, this script should be executed by cloud-init as bootcmd.

Don't forget to set the correct permission.

### Clean up

/etc/machine-id might be generated when you install some software or do something else. However, this ID should vary from machine to machine. If two machines share the same ID, they may get the same IP address from the DHCP server. Therefore, this file should keep empty.

Note: This file could be regenerated by running systemd-machine-id-setup or rebooting the computer.

Moreover, cloud-init will be executed on the next boot only if it is clean, then it will write something to disk to prevent itself from running again. To make sure it will work as expected, we can clean it manually.

## Write Preseed File

Preseed files store all the answers to the questions that the installer asks. Move to the directory custom-disk, which is created by cubic and contains the supporting files of the CD, including bootloaders and some configuration. Create a file custom-disk/preseed/auto-inst.seed, and write the following content to that file.

Note: The network is disabled during the installation due the problem we talked about earlier. As a result, debian-install will

• Fail to use self-defined APT repository
• Skip setting the host name
• Skip configuring netplan

But, all the problems above can be fixed by cloud-init.

Automatic installation requires us to pass extra arguments to the kernel. Luckily, cubic will help us to edit the configuration of bootloaders.

Note: There are two bootloaders in the CD image. grub is used to support the EFI firmware, and isolinux is used to support the traditional BIOS.

Write the content below to the corresponding file.

### isolinux/txt.cfg

Note: isolinux has a build-in option Rescue a broken system.

By now, everything is ready to go. Let us enjoy the automatic installation.