Packer can build a VMware template that’s so minimal, it’ll make you question why you ever bothered with bloated base images.
Let’s see it in action. Imagine you’re deploying a new web server. Instead of starting with a generic Ubuntu image, downloading a dozen security patches, and then installing your web server software, Packer automates this entire process. It takes a raw .iso file, boots a VM in vSphere, runs a set of pre-defined commands (like apt-get update && apt-get install -y nginx), and then captures that VM as a ready-to-deploy template.
Here’s a snippet of a Packer configuration for vSphere:
source "vmware-iso" "ubuntu" {
communicator = "ssh"
ssh_username = "ubuntu"
ssh_password = "password" # In production, use SSH keys!
iso_url = "http://your-iso-mirror/ubuntu-22.04.3-live-server-amd64.iso"
iso_checksum = "sha256:YOUR_SHA256_CHECKSUM"
vmx_template = "vmx/ubuntu.vmx" # Custom VMX settings
output_directory = "output-ubuntu-template"
# vSphere connection details
vsphere_server = "your-vcenter.yourdomain.com"
vsphere_username = "your-vcsa-user"
vsphere_password = "your-vcsa-password" # Use secrets management!
vsphere_datacenter = "Datacenter"
vsphere_folder = "PackerTemplates"
vsphere_resource_pool = "Cluster/Resources/PoolName"
vsphere_datastore = "vsanDatastore"
vsphere_network = "VM Network"
# VM settings
guest_os_type = "ubuntu-64"
cpus = 2
memory = 2048 # MB
disk_size = 40960 # MB
disk_thin = true
# Post-installation steps
http_directory = "http" # For preseed/kickstart files
boot_wait = "5s"
ssh_timeout = "10m"
shutdown_command = "sudo /sbin/halt -p"
}
build {
sources = ["source.vmware-iso.ubuntu"]
provisioner "shell" {
inline = [
"echo 'Waiting for cloud-init to finish...'",
"cloud-init status --wait",
"echo 'Updating packages and installing Nginx...'",
"sudo apt-get update",
"sudo DEBIAN_FRONTEND=noninteractive apt-get install -y nginx",
"echo 'Nginx installed. Cleaning up...'",
"sudo apt-get clean",
"sudo rm -rf /var/lib/apt/lists/*"
]
}
# Example of using a preseed file for unattended installation
# provisioner "file" {
# source = "http/preseed.cfg"
# destination = "/tmp/preseed.cfg"
# }
# provisioner "shell" {
# inline = ["sudo debconf-set-selections /tmp/preseed.cfg"]
# }
}
The problem Packer solves is the tedious, error-prone manual process of creating standardized virtual machine images. Every time you need a new VM for a specific purpose (web server, database, Jenkins agent), you’d typically spin up a VM, install the OS, configure it, install your software, and then clone it or use it as a base. This leads to "configuration drift" where each VM slowly becomes unique, making management a nightmare. Packer, by automating this, ensures every VM built from a template is identical.
Internally, Packer’s vmware-iso builder acts like a hypervisor automation tool. It connects to your vSphere API, creates a new VM based on your specifications, attaches the specified ISO, boots the VM, and then uses a "communicator" (like SSH or WinRM) to run commands on the guest OS. Once your provisioners (shell scripts, Ansible playbooks, etc.) are done, Packer tells the VM to shut down, and then it uses vSphere’s API to convert that running VM into a template. The vmx_template allows you to pre-configure hardware settings beyond what the builder directly supports, like specific SCSI controller types or advanced CPU features. The http_directory is crucial for unattended installations; it serves files (like preseed.cfg for Debian/Ubuntu or ks.cfg for CentOS/RHEL) to the booting VM via a temporary web server, allowing the OS installer to run without manual input.
One thing people often overlook is the shutdown_command. This command is vital for a clean capture. If the VM isn’t cleanly shut down, vSphere might not be able to convert it into a template, or the resulting template might have issues. Packer waits for this command to execute and for the guest OS to signal it’s powered off before proceeding with the template creation. This ensures the disk state is consistent.
The next concept you’ll likely want to explore is how to integrate Packer with your CI/CD pipeline for fully automated image builds on every code commit.