Packer Components
Packer components build machine images (AMIs, VM images, container images) using HashiCorp Packer. They allow you to manage image builds with the same stack-based configuration approach used for Terraform and Helmfile.
Available Configuration Sections
Packer components support the common configuration sections:
vars- Variables passed to packer.
env- Environment variables during execution.
settings- Integrations and metadata.
metadata- Component behavior and inheritance.
command- Override packer binary.
hooks- Lifecycle event handlers.
Component Structure
A typical Packer component configuration:
components:
packer:
ami-ubuntu:
metadata:
component: ami-ubuntu
vars:
region: us-east-1
instance_type: t3.medium
source_ami_filter:
name: "ubuntu/images/hvm-ssd/ubuntu-jammy-22.04-amd64-server-*"
owner: "099720109477" # Canonical
ami_name_prefix: "acme-ubuntu"
env:
AWS_PROFILE: acme-prod
Packer Directory Structure
Packer components are located in the path configured in atmos.yaml:
# atmos.yaml
components:
packer:
base_path: components/packer
Example structure:
components/packer/
├── ami-ubuntu/
│ ├── template.pkr.hcl
│ ├── variables.pkr.hcl
│ └── scripts/
│ ├── setup.sh
│ └── cleanup.sh
├── ami-eks-node/
│ ├── template.pkr.hcl
│ └── variables.pkr.hcl
└── docker-base/
└── template.pkr.hcl
Packer Template
Each Packer component contains HCL templates that use variables passed from Atmos:
components/packer/ami-ubuntu/variables.pkr.hcl
components/packer/ami-ubuntu/template.pkr.hcl
Component-Type Defaults
Define defaults for all Packer components:
# Apply to all Packer components
packer:
vars:
region: us-east-1
tags:
ManagedBy: Atmos
Builder: Packer
env:
PACKER_LOG: "1"
AWS_PROFILE: acme-build
# Individual components
components:
packer:
ami-ubuntu:
vars:
instance_type: t3.medium
Complete Example
stacks/orgs/acme/plat/prod/us-east-1.yaml
Running Packer Commands
Atmos provides commands that wrap Packer operations:
# Initialize Packer plugins
atmos packer init ami-ubuntu -s plat-ue1-prod
# Validate templates
atmos packer validate ami-ubuntu -s plat-ue1-prod
# Build images
atmos packer build ami-ubuntu -s plat-ue1-prod
# Run any packer subcommand
atmos packer <subcommand> <component> -s <stack>
Environment Variables
Common environment variables for Packer components:
PACKER_LOG- Enable logging (set to
1). PACKER_LOG_PATH- Path to log file.
AWS_PROFILE- AWS profile for authentication.
AWS_REGION- Default AWS region.
PACKER_CACHE_DIR- Directory for Packer cache.
Variables File Generation
Atmos generates a variables file that Packer uses during builds:
// atmos-packer.pkrvars.json (auto-generated)
{
"region": "us-east-1",
"instance_type": "t3.medium",
"ami_name_prefix": "acme-prod",
"source_ami_filter": {
"name": "ubuntu/images/hvm-ssd/ubuntu-jammy-22.04-amd64-server-*",
"owner": "099720109477"
},
"tags": {
"Environment": "prod",
"ManagedBy": "Atmos"
}
}
Multi-Cloud Support
Packer components can build images for multiple cloud providers:
AWS AMI
components:
packer:
ami-builder:
vars:
region: us-east-1
source_ami_filter:
name: "ubuntu/images/*"
owner: "099720109477"
Azure VM Image
components:
packer:
azure-image:
vars:
azure_subscription_id: "{{ env \"ARM_SUBSCRIPTION_ID\" }}"
azure_resource_group: "packer-images-rg"
azure_location: "eastus"
env:
ARM_CLIENT_ID: "{{ env \"ARM_CLIENT_ID\" }}"
ARM_CLIENT_SECRET: "{{ env \"ARM_CLIENT_SECRET\" }}"
GCP Machine Image
components:
packer:
gcp-image:
vars:
project_id: "my-gcp-project"
zone: "us-central1-a"
source_image_family: "ubuntu-2204-lts"
env:
GOOGLE_APPLICATION_CREDENTIALS: "/path/to/credentials.json"
Docker Image
components:
packer:
docker-image:
vars:
repository: "myregistry/myimage"
tag: "latest"
base_image: "ubuntu:22.04"
env:
DOCKER_HOST: "unix:///var/run/docker.sock"
Best Practices
-
Version Pin Plugins: Always specify explicit plugin versions in your Packer templates.
-
Use Source AMI Filters: Use filters with
most_recent = trueto automatically get the latest base images. -
Tag Everything: Apply consistent tags to all built images for tracking and cost allocation.
-
Use Provisioner Scripts: Keep provisioning logic in external scripts for easier testing and maintenance.
-
Clean Up: Include cleanup scripts to reduce image size and remove sensitive data.
-
Use Dependencies: Define
depends_onwhen images need to be built in a specific order. -
Centralize Defaults: Define common settings in catalog defaults and override only when necessary.