Packer is an open-source tool for creating identical machine images for multiple platforms from a single source configuration. Build AMIs, Docker images, Vagrant boxes, and more — all from one template.
What Is Packer?
Packer automates the creation of machine images. Instead of manually configuring servers, you define your image as code and Packer builds it identically across AWS, Azure, GCP, Docker, VMware, and more.
Key Features:
- Multi-platform (AWS, Azure, GCP, Docker, VMware)
- HCL2 configuration language
- Parallel builds for multiple platforms
- Provisioners (shell, Ansible, Chef, Puppet)
- Post-processors (compress, upload, tag)
- Plugin ecosystem
- CI/CD integration
- Idempotent builds
Quick Start
# Install
brew install packer
# Initialize plugins
packer init .
# Build
packer build template.pkr.hcl
Packer Template (HCL2)
# docker-image.pkr.hcl
packer {
required_plugins {
docker = {
version = ">= 1.0.0"
source = "github.com/hashicorp/docker"
}
}
}
source "docker" "ubuntu" {
image = "ubuntu:22.04"
commit = true
}
build {
name = "my-app"
sources = ["source.docker.ubuntu"]
provisioner "shell" {
inline = [
"apt-get update",
"apt-get install -y python3 python3-pip nginx",
"pip3 install flask gunicorn"
]
}
provisioner "file" {
source = "app/"
destination = "/opt/app/"
}
provisioner "shell" {
inline = [
"cd /opt/app && pip3 install -r requirements.txt"
]
}
post-processor "docker-tag" {
repository = "myapp"
tags = ["latest", "1.0.0"]
}
}
AWS AMI Build
source "amazon-ebs" "web-server" {
ami_name = "web-server-{{timestamp}}"
instance_type = "t3.micro"
region = "us-east-1"
source_ami_filter {
filters = {
name = "ubuntu/images/hvm-ssd/ubuntu-jammy-22.04-amd64-server-*"
root-device-type = "ebs"
virtualization-type = "hvm"
}
owners = ["099720109477"]
most_recent = true
}
ssh_username = "ubuntu"
}
build {
sources = ["source.amazon-ebs.web-server"]
provisioner "ansible" {
playbook_file = "./playbook.yml"
}
post-processor "manifest" {
output = "manifest.json"
}
}
Multi-Platform Build
# Build for AWS AND Azure simultaneously
build {
sources = [
"source.amazon-ebs.web-server",
"source.azure-arm.web-server"
]
provisioner "shell" {
inline = ["echo Building for platform: ${source.type}"]
}
}
Packer with Variables
variable "app_version" {
type = string
default = "1.0.0"
}
variable "environment" {
type = string
}
source "docker" "app" {
image = "node:20-alpine"
commit = true
}
build {
sources = ["source.docker.app"]
provisioner "shell" {
environment_vars = [
"APP_VERSION=${var.app_version}",
"NODE_ENV=${var.environment}"
]
inline = [
"echo Building version $APP_VERSION for $NODE_ENV"
]
}
}
packer build -var 'environment=production' template.pkr.hcl
Resources
- Packer Docs
- Packer GitHub — 15K+ stars
- Plugin Registry
Need to scrape web data for your infrastructure? Check out my web scraping tools on Apify — production-ready actors for Reddit, Google Maps, and more. Questions? Email me at spinov001@gmail.com
Top comments (0)