Automating Ubuntu VM Installations


One of the biggest annoyances in my homelab is having to take the time to setup new VMs. 90% of my VMs use Ubuntu 16.04 Server so I was determined to find a way to automate the process of installing VMs.

The method that I found worked best for me was altering the ISO file to include a preseed file. There are other methods such as Puppet and Chef, however I found this to be the easiest method for me.

This guide will walk you through how to use the method I use, as well as how to make the changes that apply to your lab.

In order to get this to work correctly, you’ll already need an Ubuntu VM setup as this scripted for use on Ubuntu. You’ll likely want to fork my repo as well since you’ll likely make edits to the files that apply to your lab.


Understanding & Updating the Files

My Repo is located here : https://git.cyanlab.io/tylerhammer/ubuntu-automated-install

Once you’ve downloaded the files, lets take a look at what we have.

We have the following:

  • create-iso.sh – This is our main script that does all the heavily lifting for us.
  • ubuntu.seed – This is our pre-seed file
  • start.sh – This is a file thats included and intended to be run after the installation is complete. More on this later.

First, we’ll take a look at the create-iso.sh file. In this file, we’re only looking to change a couple of things. Ultimately we are just going to point these to the new location of our files. So whether this be on your own Git Repo, or on a local web server.

First line to change is line 187. Simply replace my URL with your URL for your ubuntu.seed file.

download "https://git.cyanlab.io/tylerhammer/ubuntu-automated-install/raw/master/ubuntu.seed"

The new two lines will be replaced with the same URL, so I’ll put them together here. In line 240 & line 243, replace my URL with your URL for the start.sh file.

late_command="apt-install wget; in-target wget --no-check-certificate -O /home/${USERNAME}/start.sh https://git.cyanlab.io/tylerhammer/ubuntu-automated-install/raw/master/start.sh ;\
     in-target chmod +x /home/${USERNAME}/start.sh ;"
else 
   late_command="chroot /target wget -O /home/${USERNAME}/start.sh https://git.cyanlab.io/tylerhammer/ubuntu-automated-install/raw/master/start.sh ;\
     chroot /target chmod +x /home/${USERNAME}/start.sh ;"

Thats all we need to change so go ahead and save your edits.

Next we need to look at the ubuntu.seed file. The biggest things we’ll change here are the Language and Keyboard settings to match your region, and the packages we wish to install. For regional and keyboard settings head on over to https://help.ubuntu.com/lts/installation-guide/armhf/apbs04.html for a better idea of what needs to be changed. Mine is setup for English and US based keyboard.

# Regional Settings
d-i debian-installer/language                               string      en_US:en
d-i debian-installer/country                                string      US
d-i debian-installer/locale                                 string      en_US
d-i debian-installer/splash                                 boolean     false
d-i localechooser/supported-locales                         multiselect en_US.UTF-8
d-i pkgsel/install-language-support                         boolean     true

# Keyboard Settings
d-i console-setup/ask_detect                                boolean     false
d-i keyboard-configuration/xkb-keymap                       select      us
d-i keyboard-configuration/layoutcode                       string      us
d-i debconf/language                                        string      en_US:en

The next section in the ubuntu.seed file we need to change is what software we install. Line 70 & line 72 determine what we install.

Line 70 shows what packages we install.

tasksel tasksel/first    multiselect openssh-server, standard

My default installs Open SSH Server & Standard. Think of this section as if you were to see this screen when manually installing:

Line 72 determines any additional packages you would install.

d-i pkgsel/include  string   openssh-server build-essential curl git open-vm-tools software-properties-common

In my example, I install Curl, Git, Open-VM-Tools, & Software-Properties-Common. These are just packages I use on almost all of my VMs so it makes sense to install them by default for me. Simply add any packages that are in the default Ubuntu Repository. If you’d like to add something thats not in the default repository, you can add it to the start.sh script.

Finally we have the start.sh file. This file is basically our post installation script that we use to install anything that isn’t included in the default repository, as well as make changes. This script can be anything so I’m not going to recommend any changes to my script, as you can easily create your own. However, I will explain what my script does.

My version of start.sh asks me to set a static IP, change the hostname and domain of the server, as well as update the password to something more secure (You’ll understand why soon). It also adds an SSH key from a local URL on my network, and then finally it updates and upgrades the server.


Running the Script

Actually running the script is really simple. You’ll download it, chmod it, and run it. Note: Running the script requires sudo.

wget https://git.cyanlab.io/tylerhammer/ubuntu-automated-install/raw/master/create-iso.sh && chmod +x create-iso.sh && sudo ./create-iso.sh

Script starts off asking you what version of Ubuntu you want to use. Simply enter 1, 2 or 3 to select which version.

+-----------------------------------------------------------+
|            CYANLAB UNATTENDED UBUNTU ISO MAKER            |
+-----------------------------------------------------------+

Which version of Ubuntu would you like to remaster?

[1] Ubuntu 12.04.5 LTS Server amd64 - Precise Pangolin
[2] Ubuntu 14.04.5 LTS Server amd64 - Trusty Tahr
[3] Ubuntu 16.04.3 LTS Server amd64 - Xenial Xerus

Please enter your preference: [1|2|3]: 3

For me, I’ll be using 16.04.3, so I’ll select option 3.

Next, it will ask you which timezone you want to use. This uses the TZ Database format. A full list of Timezones can be found HERE. For me, since I’m on the Eastern side of the US, I use America/New_York.

Next it will ask you for a default username to create. For me, I use the username thammer.

Then, it will ask you for a default password for that user. For ease, I use a simple password like Apple123!. That way each installation is easy to log in to. The password is then updated to something more secure when I run my `start.sh` file.

Finally, it will ask you whether or not you want to make it bootable. I typically choose y here so that I can put this on a USB or CD for a non-VM installation.

At this point, you should have something that looks like this:

Once you hit enter on the bootable selection, the script will begin to do its job. Its going to download the ISO for the version of Ubuntu you selected, then download the ubuntu.seed file, and it will inject everything into the ISO for you. Once its finished, it will display all the settings you selected to ensure they are what you intended them to be. This is added just in case so that you can simply delete the new ISO and re-run the script if something was incorrect.

Your final output should look like this:

Now, that you’ve created your new ISO, you simple need to upload it to your host and use it to install. Once you’ve powered on the VM, it will automatically begin the setup so long as the changes you made to the seed file are valid.

And thats it! I use the same ISO for all the installations, and then finish with my start.sh file to customize as it.

Feel free to reach out to me if you have any questions, concerns or recommendations on how to improve this. I can be reached via email at contact@cyanlab.io