During this stage is when the magic happens since we will specify what we want to install, configure and how. Typical use cases here are hardening the image, configuring Active Directory login, adding specific configurations for management and compliance, installing software, copying plain files, etc.
This process can be done via inline shell commands, bash scripts or even using configuration tools such as Ansible, Chef, Puppet and so on.
No matter what tool you prefer, we suggest you add two important blocks that will help to make sure the Ubuntu Advantage process goes smoothly.
The first command should be added at the beginning of the process, which is
cloud-init status --wait. This will tell the script to wait until all the initialization processes are finished, including the Ubuntu Advantage activation process. If you skip this line, you may have errors during the build process, since the Ubuntu Advantage client needs to change configurations and repositories right after booting.
The second block of commands are relevant for removing information that is particular to the instance used to build the image, such as the machine ID and the Ubuntu Advantage generated token. We need generic AMIs with no duplication of unique information.
This should be added at the end of the process.
sudo ua detach --assume-yes
sudo rm -rf /var/log/ubuntu-advantage.log
sudo truncate -s 0 /etc/machine-id
sudo truncate -s 0 /var/lib/dbus/machine-id
This will ensure that every time you spin up a new instance from this AMI, you will have a “fresh start”.
In an “inline shell”, it will look like this:
"cloud-init status --wait",
"sudo apt update && sudo apt upgrade -y"
"sudo ua detach --assume-yes",
"sudo rm -rf /var/log/ubuntu-advantage.log",
"sudo truncate -s 0 /etc/machine-id",
"sudo truncate -s 0 /var/lib/dbus/machine-id"
You can also include them directly in your script or provisioning tool. In the example, all your scripts or provisioning tool goes just in the middle of those two blocks.