Search for a command to run...
Install Packer 1.16, write HCL2 templates, build machine images for AWS, Azure, GCP and QEMU, and produce signed provenance attestations for your supply chain.
Packer builds identical machine images for multiple platforms from a single configuration. One template, many clouds — with the same provisioners and the same result everywhere.
Packer 1.16.1 · HCL2 templates with source and build blocks ·
required_plugins for plugin pinning · the provenance post-processor and
packer verify-attestation for SLSA build attestations
# Add the HashiCorp signing key
wget -O - https://apt.releases.hashicorp.com/gpg \
| sudo gpg --dearmor -o /usr/share/keyrings/hashicorp-archive-keyring.gpg
# Add the repository
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(grep -oP '(?<=UBUNTU_CODENAME=).*' /etc/os-release || lsb_release -cs) main" \
| sudo tee /etc/apt/sources.list.d/hashicorp.list
# Install
sudo apt update
sudo apt install -y packer
packer version# Version
packer version
# List the available plugins
packer plugins installed
# Format a template
packer fmt .
# Validate a template
packer validate .Create template.pkr.hcl:
packer {
required_plugins {
amazon = {
source = "github.com/hashicorp/amazon"
version = ">= 1.3.0"
}
}
}
variable "aws_region" {
type = string
default = "eu-central-1"
}
variable "ami_name" {
type = string
default = "app-base-{{timestamp}}"
}
source "amazon-ebs" "ubuntu" {
region = var.aws_region
instance_type = "t3.micro"
ami_name = var.ami_name
source_ami = "ami-0abcdef1234567890" # Ubuntu 24.04 LTS
ssh_username = "ubuntu"
ami_name_filter = "app-base-*"
tags = {
Name = var.ami_name
built_by = "packer"
build_date = "{{timestamp}}"
}
}
build {
name = "ubuntu-base"
sources = ["source.amazon-ebs.ubuntu"]
provisioner "shell" {
inline = [
"sudo apt-get update",
"sudo apt-get install -y nginx",
"sudo systemctl enable nginx",
]
}
provisioner "file" {
source = "./nginx.conf"
destination = "/tmp/nginx.conf"
}
post-processor "manifest" {
output = "manifest.json"
strip_path = true
}
}# Install the plugins the template needs
packer init .
# Validate the template
packer validate .
# Build it
packer build .
# Build only one source, or exclude one
packer build -only="amazon-ebs.ubuntu" .
packer build -except="amazon-ebs" .Declare every plugin with a version constraint and commit the generated
.packer.lock.hcl file. Without it, a build can silently pick up a different plugin
version and produce a different image.
Packer uses the same template structure for every platform — only the source block
changes.
# Azure
source "azure-arm" "ubuntu" {
location = "westeurope"
vm_size = "Standard_B1s"
image_source_id = "/subscriptions/.../sourceImage"
ssh_username = "packer"
image_offer = "0001-com-ubuntu-server-jammy"
image_sku = "22_04-lts-gen2"
}
# Google Cloud
source "googlecompute" "ubuntu" {
project_id = "my-project"
source_image_family = "ubuntu-2404-lts-amd64"
image_name = "app-base-{{timestamp}}"
ssh_username = "packer"
zone = "europe-west4-a"
machine_type = "e2-medium"
}Packer 1.16 can emit and verify signed provenance for the images it builds, so consumers can prove where an image came from:
post-processor "provenance" {
only = ["docker.*"]
# Sign with a local PEM key
sign = "./cosign.key"
# ...or with a cloud KMS key
# sign = "awskms:///alias/cosign"
}# Verify an attestation
packer verify-attestation --path "pkg:docker/your-image@sha256:..." \
--certificate "chain.pem" --key "cosign.key"# Upgrade the binary
sudo apt update && sudo apt install --only-upgrade packer
# Update the plugins
packer plugins update
# Check what is installed
packer plugins installedrequired_plugins, and commit .packer.lock.hcl.{{timestamp}} or a semantic version, never latest.manifest post-processors so you know which artefact came from which build.packer validate and packer fmt -check in CI before every build.Install Vagrant 2.4.9, add boxes, manage VirtualBox, VMware, Hyper-V and libvirt providers, share folders and provision machines with Ansible or shell scripts.
Install and configure the AWS, Azure and Google Cloud command line tools with authentication, profiles, completion and multi-account workflows for every major cloud provider.