Packer

Packer builds the golden VMware templates that Terraform clones from — this keeps "what OS/patch level/base config does a fresh VM start from" version-controlled and reproducible, rather than a manually-maintained template someone clicks through once and forgets.
Official download
Packer install/downloads — always current.
What gets built
- Ubuntu templates used for general-purpose VMs and Kubernetes cluster nodes
- Windows templates (including the WDS-adjacent dev-VM path)
- HAProxy appliance template (
haproxy-tanzu), used as the control-plane load balancer in front of a cluster's kube-apiserver
Credentials
Packer authenticates the same way everything else does — Vault-sourced, via
terraform/vault/packer.tf (devhome/packer in Vault; see
Vault Overview). .pkrvars.hcl files should never contain a
literal credential.
Source material
ISOs are staged on the NAS (see TrueNAS Services) and
referenced from there rather than re-downloaded per build — the same NFS share
Terraform's vsphere_nas_datastore mounts across the ESXi cluster.
Building a template: make build-*-vm-packer (devsetup repo)
Templates aren't built by running packer build directly — the devsetup repo's
Makefile wraps it with a flavor selector, a pre-flight vCenter check, and
timestamped logging, so building any template is one command regardless of OS or use
case:
# Ubuntu — UBUNTU_PACKER_FLAVOR selects which vars file drives the build
make build-ubuntu-vm-packer UBUNTU_PACKER_FLAVOR=dke # Kubernetes node base image
make build-ubuntu-vm-packer UBUNTU_PACKER_FLAVOR=devtools # dev-tools-provisioned VM
make build-ubuntu-vm-packer UBUNTU_PACKER_FLAVOR=desktop # Ubuntu desktop/jumpbox
make build-ubuntu-vm-packer UBUNTU_PACKER_FLAVOR=rke2 # RKE2 node base image
# Windows — WIN_PACKER_FLAVOR maps to a specific PackerBuilds subdirectory
make build-win-vm-packer WIN_PACKER_FLAVOR=win11
make build-win-vm-packer WIN_PACKER_FLAVOR=WinServer2022-AD-DC
make build-win-vm-packer WIN_PACKER_FLAVOR=dke # -> WinServer2022 dir
What each target actually does:
check-vcsaruns first ($(MAKE) -C $(DEVHOME_REPO) check-vcsa) — a pre-flight guard confirming vCenter is actually reachable before sinking minutes into a build that would just fail partway through otherwise.- Ubuntu flavors resolve to a
.auto.pkrvars.hclfile underPackerBuilds/ubuntu-flavors/<flavor>/— an invalid flavor name fails immediately with the valid options listed, rather than a confusing Packer error further in. All flavors share one template directory (ubuntu-vsphere-template); only the vars file changes per flavor. - Windows flavors instead map to an entirely different
PackerBuilds/directory per flavor (win11,WinServer2022-AD-DC, orWinServer2022for thedkeflavor) and pick up whatever*.auto.pkrvars.hclfile exists there — Windows templates differ enough between flavors (AD DC promotion, different answer files) that they don't share a single template directory the way Ubuntu flavors do. - Both run
packer init .thenpacker build -var-file=..., and tee timestamped output to$(LOG_DIR)/build-*-vm-packer-<timestamp>.logso a failed overnight build has a log to check in the morning instead of a scrolled-off terminal.
Adding a new flavor is just adding a new .auto.pkrvars.hcl file in the right place —
no Makefile change needed unless it's an entirely new OS family.
Rebuilding after a base image or provisioning script changes
If a template's provisioning steps changed (an OS patch baseline, a new cloud-init
convention, an HAProxy config change like the PermitRootLogin/cert-chain setup used
for the Tanzu Supervisor's control-plane load balancer), rebuild the template with
Packer before the next Terraform apply that clones it — Terraform has no way to
detect that the template it's pointed at is stale.