Automate machine image creation for multiple platforms from a single source configuration. Build consistent, reproducible images for AWS, Azure, Docker, and more.
Packer is an open-source tool developed by HashiCorp that automates the creation of machine images for multiple platforms from a single source configuration. It enables infrastructure teams to build identical machine images for various environments, ensuring consistency across development, staging, and production systems.
Packer creates machine images by:
Build for AWS, Azure, GCP, Docker, VMware, VirtualBox, and more
Pre-configured images eliminate runtime provisioning overhead
Store image configurations as code in version control
Validate images before deployment to production
Ensure identical configurations across all environments
# Add HashiCorp GPG key
wget -O- https://apt.releases.hashicorp.com/gpg | \
sudo gpg --dearmor -o /usr/share/keyrings/hashicorp-archive-keyring.gpg
# Add repository
echo "deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] \
https://apt.releases.hashicorp.com $(lsb_release -cs) main" | \
sudo tee /etc/apt/sources.list.d/hashicorp.list
# Install Packer
sudo apt update && sudo apt install packerpacker versionPacker v1.12.0Define image builds using HCL2 format for better readability
packer {
required_plugins {
amazon = {
version = ">= 1.0.0"
source = "github.com/hashicorp/amazon"
}
}
}
source "amazon-ebs" "example" {
# Builder configuration
}
build {
sources = ["source.amazon-ebs.example"]
provisioner "shell" {
# Provisioner configuration
}
}Create machine images for specific platforms
| Builder | Description | Use Case |
|---|---|---|
| amazon-ebs | Creates Amazon Machine Images | AWS EC2 instances |
| azure-arm | Creates Azure managed images | Azure VMs |
| googlecompute | Creates GCE images | GCP instances |
| docker | Creates Docker container images | Containers |
| virtualbox-iso | Creates VirtualBox images | Local testing |
Install and configure software on the machine image
packer {
required_plugins {
amazon = {
version = ">= 1.0.0"
source = "github.com/hashicorp/amazon"
}
}
}
variable "aws_region" {
type = string
default = "us-east-1"
}
source "amazon-ebs" "ubuntu" {
ami_name = "packer-ubuntu-{{timestamp}}"
instance_type = "t2.micro"
region = var.aws_region
source_ami_filter {
filters = {
name = "ubuntu/images/*ubuntu-jammy-22.04-amd64-server-*"
root-device-type = "ebs"
virtualization-type = "hvm"
}
most_recent = true
owners = ["099720109477"]
}
ssh_username = "ubuntu"
}
build {
sources = ["source.amazon-ebs.ubuntu"]
provisioner "shell" {
inline = [
"sudo apt-get update",
"sudo apt-get upgrade -y",
"sudo apt-get install -y nginx",
]
}
}Build the image:
# Initialize plugins
packer init aws-ubuntu.pkr.hcl
# Validate configuration
packer validate aws-ubuntu.pkr.hcl
# Build the image
packer build aws-ubuntu.pkr.hclpacker {
required_plugins {
docker = {
version = ">= 1.0.0"
source = "github.com/hashicorp/docker"
}
}
}
source "docker" "nginx" {
image = "nginx:latest"
commit = true
}
build {
sources = ["source.docker.nginx"]
provisioner "shell" {
inline = [
"apt-get update",
"apt-get install -y curl",
]
}
post-processor "docker-tag" {
repository = "my-nginx"
tags = ["latest", "v1.0"]
}
}packer init docker-nginx.pkr.hcl
packer build docker-nginx.pkr.hclvariable "app_version" {
type = string
default = "1.0.0"
}
variable "environment" {
type = string
}Pass variables at build time:
packer build -var="environment=production" -var="app_version=2.0.0" template.pkr.hclOr use a variables file:
environment = "production"
app_version = "2.0.0"packer build -var-file="production.pkrvars.hcl" template.pkr.hclprovisioner "shell" {
scripts = [
"scripts/update-system.sh",
"scripts/install-docker.sh",
"scripts/configure-firewall.sh"
]
}provisioner "file" {
source = "configs/nginx.conf"
destination = "/tmp/nginx.conf"
}
provisioner "shell" {
inline = ["sudo mv /tmp/nginx.conf /etc/nginx/nginx.conf"]
}ssh_username matches the AMI's default userssh_timeout value# Run packer init to install required plugins
packer init template.pkr.hcl
# Clear plugin cache if needed
rm -rf ~/.packer.d/plugins/export PACKER_LOG=1
export PACKER_LOG_PATH="packer.log"
packer build template.pkr.hcl| Command | Description |
|---|---|
| packer init | Download and install required plugins |
| packer validate | Check template syntax and configuration |
| packer fmt | Format template files to canonical style |
| packer build | Build image from template |
| packer inspect | Show template components without building |
| packer console | Interactive console for testing expressions |