Packer — Machine Image Builder Guide
Build identical, immutable machine images for AWS, GCP, Azure, VMware, and Docker from a single HCL2 template. HashiCorp Packer codifies your golden image pipeline.
What is Packer?
HashiCorp Packer is an open-source tool that automates the creation of machine images across multiple platforms. Given a single template, Packer can build an AWS AMI, a GCP Image, an Azure Managed Image, and a VMware OVA simultaneously — all from the same provisioning code. Released in 2013 by Mitchell Hashimoto (co-founder of HashiCorp), Packer is a cornerstone of immutable infrastructure pipelines used by engineering teams worldwide.
The workflow is simple: Packer launches a temporary VM (or container) using a base image, runs provisioners (shell scripts, Ansible playbooks, Chef recipes) to install software and configure the OS, then captures a snapshot as an immutable image. The temporary VM is destroyed. The resulting image becomes your golden artifact — versioned, tested, and ready to deploy to auto-scaling groups or Kubernetes nodes without any post-boot configuration.
Key Features
- Multi-builder — build for AWS, GCP, Azure, VMware, VirtualBox, QEMU, Docker in parallel
- HCL2 templates — typed variables, for_each build matrices, better error messages
- Provisioners — shell, Ansible, Chef, Puppet, Salt, PowerShell, Windows shell
- Post-processors — manifest, compress, shell-local, amazon-import, Vagrant box
- packer validate — catch template errors before starting expensive cloud builds
- packer fmt — format HCL2 templates consistently (like terraform fmt)
- Variable files — .pkrvars.hcl files for per-environment configuration
- Plugin system — first-class and community-maintained builder/provisioner plugins
HCL2 Template: AWS AMI with Ansible
# ubuntu-web.pkr.hcl
packer {
required_version = ">= 1.9.0"
required_plugins {
amazon = {
version = ">= 1.3.0"
source = "github.com/hashicorp/amazon"
}
ansible = {
version = ">= 1.1.0"
source = "github.com/hashicorp/ansible"
}
}
}
variable "aws_region" {
type = string
default = "us-east-1"
}
variable "ami_name_prefix" {
type = string
default = "my-app"
}
variable "app_version" {
type = string
description = "Application version tag to embed in the image"
}
locals {
timestamp = regex_replace(timestamp(), "[: TZ]", "")
ami_name = "${var.ami_name_prefix}-${var.app_version}-${local.timestamp}"
}
source "amazon-ebs" "ubuntu" {
region = var.aws_region
instance_type = "t3.medium"
ami_name = local.ami_name
source_ami_filter {
filters = {
name = "ubuntu/images/hvm-ssd/ubuntu-jammy-22.04-amd64-server-*"
root-device-type = "ebs"
virtualization-type = "hvm"
}
most_recent = true
owners = ["099720109477"] # Canonical
}
ssh_username = "ubuntu"
tags = {
Name = local.ami_name
AppVersion = var.app_version
BuildTime = local.timestamp
ManagedBy = "Packer"
}
launch_block_device_mappings {
device_name = "/dev/sda1"
volume_size = 20
volume_type = "gp3"
delete_on_termination = true
}
}
build {
name = "ubuntu-web-server"
sources = ["source.amazon-ebs.ubuntu"]
# Shell provisioner for initial setup
provisioner "shell" {
inline = [
"sudo apt-get update -y",
"sudo apt-get install -y python3 python3-pip",
"sudo apt-get clean",
]
}
# Ansible provisioner for full configuration
provisioner "ansible" {
playbook_file = "./ansible/site.yml"
roles_path = "./ansible/roles"
extra_arguments = [
"--extra-vars", "app_version=${var.app_version}",
"--become",
]
}
# Write AMI ID to manifest file for downstream use
post-processor "manifest" {
output = "manifest.json"
strip_path = true
}
# Run local script after build (e.g., update Terraform variable)
post-processor "shell-local" {
inline = ["echo 'Build complete. AMI ID written to manifest.json'"]
}
} Validate, format, and build:
packer init . # download plugins packer fmt . # format templates packer validate -var 'app_version=1.2.3' . # validate before build packer build -var 'app_version=1.2.3' ubuntu-web.pkr.hcl # run the build cat manifest.json | jq '.builds[-1].artifact_id' # extract AMI ID
Packer vs Alternatives
| Feature | Packer | Docker | EC2 Image Builder | Manual AMI |
|---|---|---|---|---|
| Output formats | AMI, GCP, Azure, VMware, Docker, QEMU | OCI container images | AWS AMI only | AWS AMI only |
| Reproducibility | Excellent (code-defined) | Excellent (Dockerfile) | Good | Poor (manual steps) |
| Multi-cloud | Yes | Yes (registries) | No (AWS only) | No |
| Boot time | Fast (pre-baked) | Very fast (container) | Fast | Slow (userdata bootstrap) |
| Use case | VM images, EC2 auto-scaling | Containerized apps | AWS-native pipelines | One-off images |
Use Cases
- Building golden AMIs for EC2 Auto Scaling Groups — pre-baked images start in seconds instead of minutes
- Immutable infrastructure pipelines where every deploy creates new instances from a fresh image
- Multi-cloud image distribution — build once for AWS and GCP from the same Packer template
- Security baseline images with hardened OS configurations, compliance agents, and monitoring pre-installed
- Kubernetes node images with custom container runtimes, kernel parameters, and tooling
- CI/CD integration — Packer builds triggered by git tags, new AMI IDs fed to Terraform for deployment
Pros and Cons
Pros
- ✓ Codified, reproducible image builds — no more snowflake AMIs
- ✓ Multi-platform: one template builds for multiple clouds
- ✓ Integrates with Ansible, Chef, shell — use existing provisioning code
- ✓ Enables immutable infrastructure and fast auto-scaling
- ✓ packer validate catches errors before costly cloud builds
- ✓ HCL2 format is consistent with Terraform knowledge
Cons
- ✗ Build times can be long (10-30 min for cloud AMIs)
- ✗ Each image update requires a full rebuild and new deploy
- ✗ Costs money — cloud builder instances run during build
- ✗ AMI cleanup requires separate tooling (old images accumulate)
- ✗ Debugging failed builds requires checking cloud console logs
- ✗ Not suitable for containerized apps (Docker is better there)
Frequently Asked Questions
What is Packer and what problem does it solve?▼
Packer is an open-source tool by HashiCorp that automates the creation of identical machine images for multiple platforms from a single configuration. Without Packer, teams create AMIs or VM images manually — clicking through console UIs, running ad-hoc scripts, and struggling to reproduce images consistently. Packer codifies the image build process: start a base VM, run provisioners (shell scripts, Ansible, Chef), capture the result as an immutable image. The same Packer template can build an AWS AMI, a VMware OVA, a Google Cloud image, and a Docker image simultaneously.
What is the difference between Packer JSON and HCL2 templates?▼
Packer originally used JSON templates (.json). Starting with Packer 1.7+, HashiCorp introduced HCL2 (.pkr.hcl) as the preferred format, aligning with Terraform's configuration language. HCL2 offers significant advantages: variables can be defined with types and validation, multiple builds are cleaner, the for_each meta-argument enables build matrices, and error messages are much more readable. New projects should use HCL2. The packer hcl2_upgrade command can automatically convert JSON templates to HCL2.
How does Packer integrate with Ansible?▼
Packer's ansible provisioner runs an Ansible playbook against the machine being built. Unlike using the shell provisioner to run ansible-playbook, Packer's ansible provisioner starts a local SSH proxy and connects to the build machine automatically — you don't need Ansible installed on the build VM. Specify the playbook_file and optional roles_path, extra_arguments, and ansible_env_vars. This is the most common pattern for teams that already use Ansible for configuration management and want the same playbooks for both ongoing config and image builds.
What is immutable infrastructure and why does Packer enable it?▼
Immutable infrastructure is the practice of never modifying running servers in place. Instead, you build a new machine image with the required changes, deploy new instances from that image, and decommission the old instances. Packer is central to this pattern because it produces versioned, tested, golden images that contain the OS, runtime, and application pre-installed. Benefits include: faster auto-scaling (no bootstrap time), consistent environments, easy rollbacks (deploy previous AMI version), and elimination of configuration drift over time.
How do I pass variables to a Packer build?▼
Packer supports several variable input methods. In HCL2, declare variables with the variable block and set defaults, types, and descriptions. Pass values via: -var 'key=value' CLI flag, -var-file=prod.pkrvars.hcl (an HCL file of key=value pairs), or PKR_VAR_key environment variables. For sensitive values like AWS credentials, use environment variables (AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY) which Packer inherits from the shell — never hardcode credentials in templates.
What are Packer post-processors and when should I use them?▼
Post-processors run after builders and provisioners complete to transform or upload the artifact. Common post-processors: manifest (write build artifacts to a JSON file for use in CI/CD), compress (zip the artifact), shell-local (run a local script after build), and amazon-import (import a VMware OVA to AWS as an AMI). For multi-step pipelines, you can chain post-processors: build an image, compress it, then upload it — all in one Packer run. The manifest post-processor is especially useful for passing AMI IDs to Terraform or Ansible for deployment.
Related Products
on GumroadPremium Workflow Pack
Production-grade workflows, architecture guides, and deployment scripts for teams that ship. 10 advanced CI/CD workflows (blue-green, canary, E2E, security), 5 architecture deep-dives, code review checklist, PR process guide, and 5 battle-tested Bash deployment scripts.
Buy on Gumroad →GitHub Actions CI/CD Templates Pack
12 production-ready GitHub Actions workflow templates covering Node.js, Python, Docker, multi-environment deployments, security scanning, and auto-changelog. Copy, paste, ship.
Buy on Gumroad →Developer Productivity Bundle
Stop rebuilding the same setup every project. 51 VSCode snippets, 40 Git aliases, 5 Docker Compose stacks, 5 GitHub Actions workflows, 5 README templates, and a dotfiles kit. Set up a professional dev environment in under an hour.
Buy on Gumroad →You Might Also Need
Nomad Job Spec Builder
Generate HashiCorp Nomad job specification HCL from form inputs. Build service, batch, and system jobs with Docker/exec drivers, resources, and Consul service registration.
Open free tool →
Vault Policy Generator
Generate HashiCorp Vault HCL policies from path and capabilities form. Build least-privilege Vault policies for secrets access control.
Open free tool →
Infrastructure Cost Calculator
Compare and estimate monthly infrastructure costs for AWS EC2, Azure VMs, and Google Compute Engine. Add storage and data transfer for total monthly cloud cost.
Open free tool →
More Free Tools
Related Articles
AWS CDK vs Terraform vs Pulumi: Infrastructure as Code Comparison 2026
Complete comparison of AWS CDK, Terraform, and Pulumi for infrastructure as code in 2026 — language support, state management, multi-cloud, community, and when to use each.
Backstage Internal Developer Portal: Complete Setup Guide 2026
Learn how to set up Backstage IDP from scratch. Covers software catalog, TechDocs, plugins, CI/CD integration, and building a self-service developer platform your team will actually use.
Ansible vs Chef vs Puppet: Configuration Management Tools Compared 2026
Ansible vs Chef vs Puppet — compare agentless vs agent-based architecture, YAML vs Ruby DSL, scalability, Windows support, and cloud integration. Find the right config management tool for 2026.
Docker Compose vs Kubernetes for Small Teams 2026
Should small teams use Docker Compose or Kubernetes in 2026? Compare production viability, K3s as a middle ground, Kompose migration, and the real costs of managed Kubernetes for teams under 20.
Docker Compose vs Kubernetes: When to Use Each (2026)
A practical guide to choosing between Docker Compose and Kubernetes in 2026. Compare complexity, use cases, cost, and learn when to migrate from one to the other.
Enjoying this tool? Get more like it.
Weekly developer tool guides, productivity playbooks & AI tricks. Free. No spam.
Unlock AI-Powered Dev Tools
- ⚡ AI Code Review, Doc Generator & SQL Builder
- ⚡ All premium templates & early access
- ⚡ Member discounts on Gumroad products
$9/mo after trial · Cancel anytime
Want the full toolkit?
Get DevPlaybook Pro
Every template, guide, boilerplate, and automation script in one bundle. 13 premium products — grab them all at once and save big.
MIT licensed · Instant download · No subscription
See what's included → Browse all deals →