How I Use Packer in My Homelab

Info

I thought I’d share a quick overview of how I got started with Packer and what I’ve been using it for. I’ll be posting more detailed instructions on how to use Packer to create Proxmox templates for Ubuntu and Debian, as well as virtual machines for VMWare Workstation. It took me a while to create my templates because I also got deeper into cloud-init, autoinstall and preseed files.

Packer lets us create the same images for different platforms from one source. I use Packer to create virtual machines for VMWare Workstation for testing purposes and virtual machine templates as a golden base image on Proxmox. All you need to do is define the installer ISO, set up the variables, create the Packer build and source blocks, and add automatic OS install files like Ubuntu autoinstall or a Debian preseed file.

Packer Installation

The installation is pretty straightforward. Just follow the instructions in the documentation.

Packer Workflow

You’ll find all the Packer templates on my GitLab repository.

This is what my current Packer working directory for the Proxmox template files looks like:

.
├── files
│   ├── 99-pve.cfg
├── http
│   ├── meta-data
│   ├── user-data
│   ├── preseed.cfg
├── proxmox-linux.pkr.hcl
├── def-vars.pkr.hcl
└── variables.auto.pkrvars.hcl

proxmox-linux-pkr.hcl
This is the Packer HCL template file, which includes the source and build configuration blocks.

def-vars.pkr.hcl
The Packer HCL file includes all the variable definitions.

variables.auto.pkrvars.hcl
The Packer HCL variables file is easy to read and includes all the assignments.

files - 99-pve-cfg
This is where you tell cloud-init what data sources it should look for when it’s booting up the virtual machine template.

http - user-data and preseed.cfg
The file user-data is for Ubuntu cloud-config autoinstall. There’s also a required meta-data file in this directory. It’s used for cloud deployment, but as I’m not deploying to the cloud, I can leave it empty. The preseed.cfg file is used for the automatic Debian installation.

Packer will set up an HTTP server to serve those files during the automated OS installation.

For the first initialisation I run packer init .. This will install the required plugins, which are listed at the top of my proxmox-linux-pkr.hcl file. It is also possible to install them manually:
packer plugins install github.com/hashicorp/proxmox.

Note: Default Linux Plugin Directory on Linux

  • $HOME/.packer.d/plugins: this is the old-style installation directory for plugins. ~/.packer.d will have precedence over the following if it exists.
  • $HOME/.config/packer/plugins: this replaces ~/.packer.d, if no existing configuration directory exists, Packer will create this automatically at first use.

After creating or modifying the templates, I validate them with packer validate .. And it is also possible to format them to a canonical format and style automatically with packer fmt .. If you run packer on a specific file packer validate proxmox-linux.pkr.hcl, only that file will be processed, not even auto.pkrvars.hcl files are included.

And to build the images, I simply run packer with this command, e.g. packer build . Here is a simple overview of what Packer does when I run this command:

  1. Downloads and provides the OS Installer ISO file.
  2. Connects to Proxmox via API and creates a VM with the defined resources and boots the VM with the defined ISO image.
  3. Launches local HTTP server to serve files, such as autoinstall, preseed.
  4. Waits 10s for VM to boot.
  5. Types the defined boot command so that the operating system is installed with the defined and served autoinstall or preseed configuration file.
  6. Waits for SSH to become available. This can take several minutes while the automated OS installation is running.
  7. Connects via SSH with the defined SSH user and the defined private Auth Key. This works because we created a user with our SSH public key during the automatic OS installation.
  8. Executes the provisioning blocks.
    • System and cloud-init clean-up.
    • Uploads cloud-init Proxmox configuration file.
    • Ansible user setup.
  9. Stops the virtual machine.
  10. Converts VM to template.
  11. Adds a cloud-init cdrom to the storage pool.
  12. Build finished message - took about 7-9 minutes in my environment.

I’ve got one HCL template file for my source and build blocks, which I use for both Linux distributions. I only use two external files for the variables. You could also create all of this in one template file, or you could create extra files for every source and build block or for each OS. With packer build . Packer will always include all pkr.hcl files in the directory, only *.pkrvars.hcl files have to be specified with the parameter --var-file=example.pkrvars.hcl if the filename is not example.auto.pkrvars.hcl. Just do whatever works best for your workflow.

The key is to keep the templates DRY (don’t repeat yourself), use descriptive file names as well as consistent naming and conventions, document your configuration, use version control and for sensitive information like credentials or API keys use environment variables. Following this, the Packer project will be organised, maintainable and scalable as the infrastructure automation needs grow.

To make things more automated and to stick to IaC’s methods, I’ll use the templates that Packer created to then deploy the virtual machines with Terraform.


Resources