I am a HUGE fan of HashiCorp Packer and I have been using it for a number of years across many different projects including the VMware Event Broker Appliance (VEBA) solution. While it can certainly feel daunting at first, the same can be said for just about anything new, I typically point folks over to Ryan Johnson's fantastic Packer Examples for VMware vSphere project as a starting point, where you can find working Packer examples across a number of popular OS distributions for both Windows and Linux.
Most recently, I was helping out a few colleagues who was interested in automating the build of an Ubuntu Desktop image that could then be exported to an OVF/OVA. Of course, my recommendation was for them take a look at Ryan's project and they should be able to augment the existing Ubuntu Server 22.04 example. Interestingly enough, while I always recommend Ryan's Packer example repo, I have not personally used it myself and this is primarily due to the existing customization I have in my Packer builds which includes the use of custom OVF properties, which you can read more about HERE, HERE AND HERE.
Since I was recommending the project, I figure I should probably give it a try at least once and the Ubuntu Desktop addition should be a trivial thing to add ... right?
Ryan's project is extremely comprehensive and while things should just work if you use the default builds, but if you wish to make tweaks, I can certainly understand that you could feel overwhelmed, which is exactly how I felt when trying to figure out how to augment the existing Ubuntu Server 22.04 build.
While I do have experience in using Packer, it did take me a few attempts as I ran into some setup issues on my macOS system and just ended up deploying an Ubuntu 22.04 VM to then use as my build host. The required change to go from an Ubuntu Server to Ubuntu Desktop was minimal, you do need to understand the project layout and ultimately how the repo has been setup, which includes the use of Ansible Packer Provisioner, which was not something I had used before.
I wanted to put together this blog post, not only as a reference for myself but also for anyone who wants to start using Packer and Ryan's awesome repo but need a bit more guidance if you intend to perform further customization.
Step 1 - Download and install the latest Ubuntu Server 22.04 (https://releases.ubuntu.com/jammy/ubuntu-22.04.2-live-server-amd64.iso) as a VM. While you can certainly run the Packer build from your desktop system, depending on how it has been setup, you might still run into issues and having a dedicated build host is not necessary a bad thing.
Step 2 - SSH to your Ubuntu build VM and run the following commands to add the required HashiCorp package repo:
sudo bash -c 'wget -O- https://apt.releases.hashicorp.com/gpg | gpg --dearmor > /usr/share/keyrings/hashicorp-archive-keyring.gpg' gpg --no-default-keyring --keyring /usr/share/keyrings/hashicorp-archive-keyring.gpg --fingerprint sudo bash -c 'echo "deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] \ https://apt.releases.hashicorp.com $(lsb_release -cs) main" > /etc/apt/sources.list.d/hashicorp.list'
Step 3 - Install all the required packages by running the following command:
sudo apt-get update && sudo apt-get install -y python3-pip packer git jq xorriso whois net-tools ansible packer pip3 install --user ansible-core==2.13
Step 4 - Clone Ryan's repo and change into the directory:
git clone https://github.com/vmware-samples/packer-examples-for-vsphere.git cd packer-examples-for-vsphere
Step 5 - Create a new build configuration, which allows you to isolate each build separately including credentials and build environments. In the example, I have named this jammy_desktop, but you can use any name as it simply creates a directory with the Packer configuration files that you will need to edit.
./config.sh jammy_desktop
Step 6 - Depending on when you clone Ryan's repo, you may want to use newer versions of the OS ISO images and that requires you to update the Packer configuration file to include the directory where the ISO image will be stored on your vSphere Datastore but also the filename and SHA256 hash. In my example, I am using the latest Ubuntu Server 22.04.2 image and I have tweaked the filename to match the default value but the directory and the SHA26 hash is a different value. You can use sha256sum utility to generate the required has.
To make this change, edit builds/linux/ubuntu/22-04-lts/linux-ubuntu.auto.pkrvars.hcl and you will want to update the following fields as noted below:
iso_path = "1.ISO"
iso_file = "ubuntu-22.04-live-server-amd64.iso"
iso_checksum_type = "sha256"
iso_checksum_value = "5e38b55d57d94ff029719342357325ed3bda38fa80054f9330dc789cd2d43931"
Step 7 - Since we want an Ubuntu Desktop image rather than the default Ubuntu Server, which does not include a graphical desktop, we will need to adjust the cloud-init user-data configuration to include the additional ubuntu-desktop package which will give us the desktop experience.
To make this change, edit builds/linux/ubuntu/22-04-lts/data/user-data.pkrtpl.hcl and append ubuntu-desktop entry under the packages section:
packages:
- openssh-server
- open-vm-tools
- cloud-init
- ubuntu-desktop
Note: If you need to make other OS customization, you can certainly apply the changes here or look at using the Ansible Packer Provisioner which is also used within the project. Additional research should be done if you intend to use Ansible rather than native cloud-init interface which Ubuntu supports.
Step 8 - Next, we will change into the build configuration directory called jammy_desktop in our example and edit a few of the configuration files for our build.
cd jammy-desktop/
Step 9 - Since default Ubuntu Server Packer example uses the Ansible Provisioner, we will need to provide an SSH key that it will use to communicate with the VM. First, run the following command (hit enter with no password) to generate a new SSH private (${HOME}/.ssh/ansible_id_ecdsa) and public (${HOME}/.ssh/ansible_id_ecdsa.pub) key.
ssh-keygen -t ecdsa -b 521 -C "ansible[at]rainpole.io" -f ${HOME}/.ssh/ansible_id_ecdsa
Now take the contents of ${HOME}/.ssh/ansible_id_ecdsa.pub and replace the ansible_key variable in ansible.pkrvars.hcl file.
Step 10 - There is also a build account that is used by Packer wand we will also need to provide an SSH key that it will use to communicate with the VM. Run the following command (hit enter with no password) to generate a new SSH private (${HOME}/.ssh/build_id_ecdsa) and public (${HOME}/.ssh/build_id_ecdsa.pub) key.
ssh-keygen -t ecdsa -b 521 -C "build[at]rainpole.io" -f ${HOME}/.ssh/build_id_ecdsa
Now take the contents of ${HOME}/.ssh/build_id_ecdsa.pub and replace the build_key variable in build.pkrvars.hcl file.
Additionally, we also need to provide a password for the build account including the SHA512 hash of the password. To generate the hash, you can run the following command and then specify the password of your choice and it will output the SHA512 hash
mkpasswd -m sha-512
Using the hash and the raw password, you can then update both build_password and build_password_encrypted variable in build.pkrvars.hcl file.
Step 11 - Now we need to edit common.pkrvars.hcl file and specify the vSphere Datastore in which your ISO images will be stored by editing the common_iso_datastore variable. Ryan's repo uses both the Content Library and OVF Providers to allow multiple output of the final image. If you do not have or intend to output the Ubuntu image into an existing vSphere Content Library, then make sure you configure the common_content_library_skip_export variable to true or else you will hit an error at the very end of the build.
Step 12 - The last configuration file you will need to edit is the vsphere.pkrvars.hcl file which contains information about your vSphere environment including vCenter Server, credentials and resources Packer will use. This should be pretty straight forward and if you are using the default self-signed TLS certificate for vCenter Server, make sure you set the vsphere_insecure_connection variable to true.
Step 13 - If you recall from Step 6, we had specified the name of the ISO and the directory it would be found in. You now need to ensure this matches up in your vSphere environment by uploading the Ubuntu ISO image that Packer will use to build your image.
Step 14 - Finally, we are now ready to build our Ubuntu Desktop 22.04 image by changing back to root directory of repo and run the following command:
./build.sh jammy_desktop
If everything was configured correctly, you should see a new VM that is created by Packer and it will begin the OS installation and then customize the VM and finally export the image as an OVF/VMDK which will be located under the artifacts directory. The build time will vary based on your environment and resources but the screenshot above is what you should see with a successful build. Hopefully this was useful for anyone looking to get started with Packer but might feel a bit overwhelm with making changes to the default Ubuntu build.
Dayne Segal says
how about doing something similar for RHEL?
William Lam says
The same concept applies 🙂
dayne segal says
I have googled and googled, i am stuck at the point where it is waiting for an IP, this points to vmware tools being an issue but for the life of me i cannot get vmware tools installed
William Lam says
I'd recommend posting on the Github repo if you're still stuck. There's also packer debugging that you can enable to see what is going on, but more than likely you've got connectivity issues between where you're running Packer and your ESXi host, make sure they can talk to each other (bi-directionally)
Pascal says
The awesome Repo is not really for Windows Client User or i am mistaken?