Linux unattended installation using preseed For a while now, I have been looking for a way to automate UEFI Linux installations. I use Hyper-V on a daily basis and have tried various methods from PXE, System Center Virtual Machine Manager, as well as other FAI systems like Foreman. PXE and System Center Virtual Machine Manager both work perfectly with Legacy or Generation 1 virtual machines with Hyper-V, but not for Generation 2 (UEFI). System Center Virtual Machine Manager is supposed to be compatable with Generation 2 virtual machines, but since 2012 R2, when Linux support was announced, there has been a bug where by a virtual machine template will not boot once created. I’ve scoured the internet to try and find a fix for this, but it doesn’t look like I’m the only one.
So, I couldn’t get Generation 2 virtual machines to boot without user interaction, so I decided to try and automate things post install. This is where I wanted to use Ansible. I wrote a post about provisioning multiple Linux servers with Ansible, explaining how to automate the installation of packages and other items. I figured, I could create the new virtual machine, then SSH in afterwards with Ansible. However, I then came across the issue of SSH keys, as well as needing Python to properly use Ansible. Yes, there are ways to enter a password in order to dial in and install the SSH keys and Python, but these methods were dirty and required extra flags.
I called out to Reddit. Another user suggested using a preseed to install the SSH keys and packages needed for Ansible in a post install script. I had heard of using preseeds in the past but this never actually crossed my mind as a viable solution. Not one that I thought would work with UEFI installations anyway. I got reading. This is when I discovered the power of using a preseed. My hands raised to the air with joy. I had spent many, many hours gritting my teeth at solutions that didn’t work (at least for me).
I started trying to make my own ISO with by editing the default built in preseed with my own. I got a basic preseed working, although a bit rusty. However, I figured, I may want to edit the preseed on the fly on a per VM basis but I didn’t want to have to make new install media each time. Then I came across how I could load the preseed file over the network. This meant, I could edit various parameters of the preseed, easily and without creating new install media.
Here’s how I did it. You can also see a scaled down guide on how to complete this by visiting the Github repository here: https://github.com/dsgnr/Ubuntu-16.04-Unattended-Install.
Follow the steps below to create your own Ubuntu 16.04 preseed ISO.
First, we need to start by grabbing the original install media.
Extract the ISO
We then need to extract our newly downloaded Ubuntu image.
The above command will extract the ISO you have just downloaded and place the files into a new directory called
This is for UEFI booting. This specifies the timeout on the grub menu to 1 second, tells grub what network adapter to use and grabs the preseed file.
Replace the contents with grub.cfg with the following. Make sure you alter the HTTP location of your preseed file! My preseed file is currently stored in http://preseed.handsoff.local/ubuntu-16-04/preseed.cfg
This will allow you to install a legacy or generation 1 virtual machine. If you do not want to enable preseeding on a legacy device, this step isn’t necessary.
Replace the contents with the following. Make sure you alter the HTTP location of your preseed file!
This file will allow you to install a legacy or generation 1 virtual machine. If you do not wish to have this functionality then skip this step.
Create new ISO
We need to create the new ISO. This command will specify the different parameters of the ISO.
You will now have a custom built Ubuntu 16.04 install ISO in
As we have created a hybrid ISO, meaning it can be used in both UEFI and Legacy modes, it’s good to make sure EFI is specified in the partition table. You can check this by using the following command:
If the partitions have been created correctly, you should see something similar to the following:
The Preseed file
You will need to upload your preseed .cfg file to location specified in grub.cfg and txt.cfg. As we have specified networking within the Grub menu, we are now able to pull the preseed file over network using DHCP.
You can either encrypt your password, or pass it over plain text. If you want to use plain text, then comment the line
d-i passwd/user-password-crypted and uncomment the two lines above containing
passwd/user-password-again. Don’t forget to update your password. If you would like to hash the password, enter the following line. This will prompt for a password and return a hash for you to use. You must then add your hash to the preseed.cfg file.
The post install script
The preseed uses wget to download your post-install.sh file to the /tmp folder just before the machine reboots after installation. My script does the following:
- apt-get update && upgrade -y
- apt-get dist-upgrade -y
- Installs basic packages defined at the head of the script.
- Installs SSH keys for both the default user, and root. You must edit the post-install.sh file to add your keys.
- Edits /etc/sshd_config to allow root ssh access, as well as password authentication.
- Configures networking specified at the top of the script.
- Changes the hostname which is defined at the top of the script.
Unfortunately, there seems to be a bug in Xenial which ignores the hostname set in the preseed file. Therefore, a default hostname is set within grub to remove the prompt during installation. If you know a better way around this, please commit a PR on the Github repository.