HashiCorp Packer
Chapter 42: Packer - Machine Image Building
Section titled “Chapter 42: Packer - Machine Image Building”Automated Machine Image Creation with Packer
Section titled “Automated Machine Image Creation with Packer”42.1 Overview
Section titled “42.1 Overview”Packer is an open-source tool by HashiCorp for creating identical machine images for multiple platforms from a single source configuration.
Packer Overview+------------------------------------------------------------------+| || +------------------------+ || | Packer | || +------------------------+ || | || +---------------------+---------------------+ || | | | | || v v v v || +----------+ +----------+ +----------+ +----------+ || | Builders | | Provisio | | Post- | | Templates| || | | | -ners | | Processors| | | || | - AWS | | - Shell | | - Upload | | - JSON | || | - Azure | | - Ansible| | - Scan | | - HCL2 | || | - GCP | | - Puppet | | - Tag | | - Var | || | - Docker | | - Chef | | - Test | | - Packer| || +----------+ +----------+ +----------+ +----------+ || |+------------------------------------------------------------------+Key Features
Section titled “Key Features”| Feature | Description |
|---|---|
| Builders | Create images for different platforms |
| Provisioners | Configure the image |
| Post-Processors | Process images after creation |
| Templates | Define image configuration |
42.2 Packer Architecture
Section titled “42.2 Packer Architecture”Image Building Workflow
Section titled “Image Building Workflow” Packer Workflow+------------------------------------------------------------------+| || +----------+ +----------+ +----------+ +----------+ || | Template | -> | Builder | -> | Provision| -> | Post- | || | (JSON/ | | (Create | | -er | | Processor| || | HCL2) | | Instance| | (Config) | | (Export) | || +----------+ +----------+ +----------+ +----------+ || | | | | || v v v v || +----------------------------------------------------------+ || | State Management | || +----------------------------------------------------------+ || || Output: Machine Image (AMI, VHD, Docker Image, etc.) || |+------------------------------------------------------------------+AWS Builder Types
Section titled “AWS Builder Types” AWS Builders+------------------------------------------------------------------+| || +------------------+ +------------------+ +------------------+ || | AMI Builder | | EC2 Image Builder| | EBS Builder | || | | | | | | || | - Source AMI | | - Pipeline | | - Volume-based | || | - Instance Store | | - Components | | - Snapshot | || | - Launch | | - Distribution | | - Registration | || +------------------+ +------------------+ +------------------+ || || +------------------+ +------------------+ || | Instance Builder | | Chroot Builder | || | | | | || | - EC2 Instance | | - No running | || | - SSH/WinRM | | instance | || | - Full support | | - Fast build | || +------------------+ +------------------+ || |+------------------------------------------------------------------+42.3 Packer Templates
Section titled “42.3 Packer Templates”HCL2 Template Structure
Section titled “HCL2 Template Structure”# Required pluginspacker { required_plugins { amazon = { version = ">= 1.0.0" source = "github.com/hashicorp/amazon" } }}
# Variablesvariable "aws_region" { type = string default = "us-east-1"}
variable "ami_name" { type = string default = "web-server-{{timestamp}}"}
# Data sourcesdata "amazon-ami" "ubuntu" { filters = { name = "ubuntu/images/*ubuntu-jammy-22.04-amd64-server-*" root-device-type = "ebs" virtualization-type = "hvm" } most_recent = true owners = ["099720109477"]}
# Source definitionsource "amazon-ebs" "ubuntu" { region = var.aws_region source_ami = data.amazon-ami.ubuntu.id instance_type = "t3.medium" ssh_username = "ubuntu"
ami_name = var.ami_name ami_description = "Web server AMI built with Packer"
tags = { Name = "web-server" BuiltBy = "Packer" }}
# Build definitionbuild { name = "web-server" 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 = "./configs/nginx.conf" destination = "/tmp/nginx.conf" }
provisioner "shell" { inline = [ "sudo cp /tmp/nginx.conf /etc/nginx/nginx.conf", "sudo systemctl restart nginx" ] }
post-processor "manifest" { output = "manifest.json" }}JSON Template (Legacy)
Section titled “JSON Template (Legacy)”{ "variables": { "aws_region": "us-east-1", "ami_name": "web-server-{{timestamp}}" }, "builders": [ { "type": "amazon-ebs", "region": "{{user `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"] }, "instance_type": "t3.medium", "ssh_username": "ubuntu", "ami_name": "{{user `ami_name`}}", "tags": { "Name": "web-server", "BuiltBy": "Packer" } } ], "provisioners": [ { "type": "shell", "inline": [ "sudo apt-get update", "sudo apt-get install -y nginx" ] } ], "post-processors": [ { "type": "manifest", "output": "manifest.json" } ]}42.4 Provisioners
Section titled “42.4 Provisioners”Provisioner Types
Section titled “Provisioner Types” Packer Provisioners+------------------------------------------------------------------+| || +------------------+ +------------------+ +------------------+ || | Shell | | Ansible | | Chef | || | | | | | | || | - inline | | - playbook | | - cookbook | || | - script | | - galaxy | | - role | || | - execute_command| | - inventory | | - attributes | || +------------------+ +------------------+ +------------------+ || || +------------------+ +------------------+ +------------------+ || | Puppet | | File | | PowerShell | || | | | | | | || | - manifest | | - upload files | | - scripts | || | - module | | - directories | | - inline | || | - facter | | - permissions | | - elevated | || +------------------+ +------------------+ +------------------+ || |+------------------------------------------------------------------+Shell Provisioner Examples
Section titled “Shell Provisioner Examples”# Inline commandsprovisioner "shell" { inline = [ "sudo apt-get update", "sudo apt-get install -y nginx curl wget", "sudo systemctl enable nginx" ]}
# Script fileprovisioner "shell" { script = "./scripts/setup.sh"}
# Script with argumentsprovisioner "shell" { script = "./scripts/configure.sh" execute_command = "sudo -S -E bash -s '{{ .Path }}'" environment_vars = [ "APP_ENV=production", "DB_HOST=${var.db_host}" ]}
# Expect disconnect (for reboot)provisioner "shell" { inline = ["sudo reboot"] expect_disconnect = true}
# Pause before next provisionerprovisioner "shell" { inline = ["echo 'Waiting for reboot...'"] pause_before = "30s" start_retry_timeout = "10m"}Ansible Provisioner
Section titled “Ansible Provisioner”# Local Ansibleprovisioner "ansible" { playbook_file = "./ansible/site.yml" extra_arguments = [ "--extra-vars", "app_env=production" ]}
# Ansible Galaxyprovisioner "ansible" { playbook_file = "./ansible/site.yml" galaxy_file = "./ansible/requirements.yml" galaxy_command = "ansible-galaxy install -r {{.GalaxyFile}}"}
# Remote Ansible (Ansible installed on instance)provisioner "ansible-remote" { playbook_file = "./ansible/site.yml" ansible_ssh_user = "ubuntu"}File Provisioner
Section titled “File Provisioner”# Upload single fileprovisioner "file" { source = "./configs/app.conf" destination = "/tmp/app.conf"}
# Upload directoryprovisioner "file" { source = "./configs/" destination = "/tmp/configs/"}
# Upload with direction (for Windows)provisioner "file" { source = "./configs/app.conf" destination = "C:/Temp/app.conf" direction = "upload"}42.5 AWS-Specific Configuration
Section titled “42.5 AWS-Specific Configuration”AMI Builder Configuration
Section titled “AMI Builder Configuration”source "amazon-ebs" "web-server" { # Region and source AMI region = "us-east-1" source_ami = "ami-0abcdef1234567890"
# Instance configuration instance_type = "t3.medium" spot_instance_types = ["t3.medium", "t3.large"] spot_price = "0.05"
# Network configuration vpc_id = "vpc-12345678" subnet_id = "subnet-12345678" security_group_ids = ["sg-12345678"]
# SSH configuration ssh_username = "ubuntu" ssh_keypair_name = "my-keypair" ssh_private_key_file = "./keys/my-keypair.pem"
# AMI configuration ami_name = "web-server-{{timestamp}}" ami_description = "Web server AMI" ami_users = ["123456789012"] # Share with accounts ami_groups = ["all"] # Make public (or specific groups)
# AMI tags tags = { Name = "web-server" Environment = "production" BuiltBy = "Packer" Project = "web-app" }
# Snapshot tags snapshot_tags = { Name = "web-server-snapshot" }
# Launch template launch_template = { id = "lt-1234567890abcdef" version = "$Latest" }}
# Windows AMI Buildersource "amazon-ebs" "windows" { region = "us-east-1" source_ami = "ami-0abcdef1234567890" instance_type = "t3.medium"
# Windows-specific user_data_file = "./scripts/windows-userdata.ps1" communicator = "winrm" winrm_username = "Administrator" winrm_password = "PackerPassword123!" winrm_use_ssl = true winrm_insecure = true
# AMI configuration ami_name = "windows-server-{{timestamp}}"}Spot Instances for Cost Savings
Section titled “Spot Instances for Cost Savings”source "amazon-ebs" "spot-instance" { region = "us-east-1" source_ami = "ami-0abcdef1234567890"
# Use spot instances spot_price = "auto" spot_instance_types = [ "t3.medium", "t3.large", "m5.medium" ]
# Fallback to on-demand if spot unavailable spot_price_auto_product = "Linux/Unix (Amazon VPC)"
instance_type = "t3.medium" # Fallback ssh_username = "ubuntu"
ami_name = "spot-built-ami-{{timestamp}}"}42.6 Post-Processors
Section titled “42.6 Post-Processors”Post-Processor Types
Section titled “Post-Processor Types” Post-Processors+------------------------------------------------------------------+| || +------------------+ +------------------+ +------------------+ || | Manifest | | Amazon Import | | Vagrant | || | | | | | | || | - Output JSON | | - Import to EC2 | | - Vagrant box | || | - Image IDs | | - VM Import | | - VirtualBox | || | - Metadata | | - Conversion | | - AWS provider | || +------------------+ +------------------+ +------------------+ || || +------------------+ +------------------+ +------------------+ || | Docker | | Artifactory | | Checksum | || | | | | | | || | - Docker image | | - Upload | | - SHA256 | || | - Push to repo | | - Repository | | - MD5 | || | - Tag | | - Authentication | | - Verification | || +------------------+ +------------------+ +------------------+ || |+------------------------------------------------------------------+Manifest Post-Processor
Section titled “Manifest Post-Processor”build { post-processor "manifest" { output = "manifest.json" strip_path = true custom_data = { git_commit = "${var.git_commit}" build_number = "${var.build_number}" } }}Docker Post-Processor
Section titled “Docker Post-Processor”# Build Docker image from AMIbuild { sources = ["source.amazon-ebs.ubuntu"]
post-processor "docker-import" { repository = "my-app" tag = "latest" }
post-processor "docker-push" { login = true login_username = var.docker_username login_password = var.docker_password login_server = "docker.io" }}42.7 Multi-Region AMI Distribution
Section titled “42.7 Multi-Region AMI Distribution”Copy AMI to Multiple Regions
Section titled “Copy AMI to Multiple Regions”source "amazon-ebs" "base" { region = "us-east-1" source_ami = "ami-0abcdef1234567890" instance_type = "t3.medium" ssh_username = "ubuntu" ami_name = "base-ami-{{timestamp}}"
# Copy to multiple regions ami_regions = [ "us-west-1", "us-west-2", "eu-west-1", "eu-central-1", "ap-southeast-1" ]
# Region-specific AMI names ami_region_kms_key_ids = { us-west-1 = "alias/aws/ebs" us-west-2 = "alias/aws/ebs" eu-west-1 = "alias/aws/ebs" eu-central-1 = "alias/aws/ebs" }}Multi-Region Build Pipeline
Section titled “Multi-Region Build Pipeline”# Build in multiple regions simultaneouslyvariable "regions" { type = list(string) default = ["us-east-1", "eu-west-1", "ap-southeast-1"]}
build { name = "multi-region"
dynamic "sources" { for_each = var.regions iterator = region content { source = "source.amazon-ebs.base"
# Override region-specific settings region = region.value ami_name = "app-${region.value}-{{timestamp}}" } }
provisioner "shell" { inline = ["sudo apt-get update && sudo apt-get install -y nginx"] }}42.8 Golden Image Pipeline
Section titled “42.8 Golden Image Pipeline”Golden Image Architecture
Section titled “Golden Image Architecture” Golden Image Pipeline+------------------------------------------------------------------+| || Stage 1: Base Image || +----------------------------------------------------------+ || | - OS updates and patches | || | - Common packages | || | - Security hardening | || | - Base configuration | || +----------------------------------------------------------+ || | || v || Stage 2: Application Image || +----------------------------------------------------------+ || | - Application runtime | || | - Application dependencies | || | - Application configuration | || | - Application-specific hardening | || +----------------------------------------------------------+ || | || v || Stage 3: Deployment Image || +----------------------------------------------------------+ || | - Environment-specific config | || | - Secrets and credentials | || | - Monitoring agents | || | - Final validation | || +----------------------------------------------------------+ || |+------------------------------------------------------------------+Golden Image Template
Section titled “Golden Image Template”# Base image templatesource "amazon-ebs" "base" { region = "us-east-1" source_ami = data.amazon-ami.ubuntu.id instance_type = "t3.medium" ssh_username = "ubuntu"
ami_name = "base-image-{{timestamp}}" ami_users = var.account_ids}
build { name = "base-image" sources = ["source.amazon-ebs.base"]
# System updates provisioner "shell" { inline = [ "sudo apt-get update", "sudo apt-get upgrade -y", "sudo apt-get install -y curl wget jq unzip" ] }
# Security hardening provisioner "shell" { script = "./scripts/harden.sh" }
# Install common tools provisioner "shell" { script = "./scripts/install-tools.sh" }
# Output manifest post-processor "manifest" { output = "base-manifest.json" }}
# Application image (uses base image)variable "base_ami" { type = string}
source "amazon-ebs" "app" { region = "us-east-1" source_ami = var.base_ami instance_type = "t3.medium" ssh_username = "ubuntu"
ami_name = "app-image-{{timestamp}}"}
build { name = "app-image" sources = ["source.amazon-ebs.app"]
# Install application provisioner "ansible" { playbook_file = "./ansible/app.yml" }
# Configure application provisioner "file" { source = "./configs/" destination = "/opt/app/configs/" }
post-processor "manifest" { output = "app-manifest.json" }}42.9 CI/CD Integration
Section titled “42.9 CI/CD Integration”GitHub Actions Integration
Section titled “GitHub Actions Integration”name: Build AMI with Packer
on: push: branches: [main] paths: - 'packer/**' pull_request: branches: [main]
env: AWS_REGION: us-east-1
jobs: validate: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3
- name: Setup Packer uses: hashicorp/setup-packer@main with: version: "1.9.0"
- name: Validate Template run: | cd packer packer init . packer validate .
build: needs: validate runs-on: ubuntu-latest if: github.ref == 'refs/heads/main' steps: - uses: actions/checkout@v3
- name: Configure AWS credentials uses: aws-actions/configure-aws-credentials@v2 with: aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} aws-region: ${{ env.AWS_REGION }}
- name: Setup Packer uses: hashicorp/setup-packer@main with: version: "1.9.0"
- name: Build AMI run: | cd packer packer init . packer build -machine-readable . env: PKR_VAR_ami_name: "app-${{ github.sha }}"
- name: Upload manifest uses: actions/upload-artifact@v3 with: name: packer-manifest path: packer/manifest.jsonJenkins Pipeline
Section titled “Jenkins Pipeline”// Jenkinsfilepipeline { agent any
environment { AWS_REGION = 'us-east-1' PACKER_VERSION = '1.9.0' }
stages { stage('Validate') { steps { sh ''' packer init packer/ packer validate packer/ ''' } }
stage('Build AMI') { steps { withAWS(credentials: 'aws-credentials', region: "${AWS_REGION}") { sh ''' cd packer packer build \ -var "ami_name=app-${BUILD_NUMBER}" \ -var "git_commit=${GIT_COMMIT}" \ . ''' } } post { success { archiveArtifacts artifacts: 'packer/manifest.json', fingerprint: true } } }
stage('Update Terraform') { steps { script { def manifest = readJSON file: 'packer/manifest.json' def amiId = manifest.builds[0].artifact_id
sh """ cd terraform terraform apply -auto-approve \ -var "ami_id=${amiId}" """ } } } }
post { always { cleanWs() } }}42.10 Best Practices
Section titled “42.10 Best Practices”Security Best Practices
Section titled “Security Best Practices” Packer Security Best Practices+------------------------------------------------------------------+| || 1. Credential Management || +--------------------------------------------------------+ || | - Use IAM roles for EC2 instances | || | - Never hardcode credentials | || | - Use temporary credentials (STS) | || | - Rotate keys regularly | || +--------------------------------------------------------+ || || 2. Image Security || +--------------------------------------------------------+ || | - Start from trusted source AMIs | || | - Apply latest security patches | || | - Remove sensitive data before AMI creation | || | - Use encrypted AMIs | || +--------------------------------------------------------+ || || 3. Network Security || +--------------------------------------------------------+ || | | Use isolated VPC for building | || | | Restrict security group rules | || | | Use VPC endpoints for AWS services | || +--------------------------------------------------------+ || |+------------------------------------------------------------------+Performance Optimization
Section titled “Performance Optimization”# Use spot instances for cost savingssource "amazon-ebs" "optimized" { # ... other config ...
# Spot instances spot_price = "auto" spot_instance_types = ["t3.medium", "t3.large", "m5.medium"]
# Faster EBS volumes volume_type = "gp3" volume_size = 20 encrypted = true
# Parallel provisioning skip_create_ami = false}
# Parallel buildsbuild { sources = [ "source.amazon-ebs.region1", "source.amazon-ebs.region2", "source.amazon-ebs.region3" ]
# Run provisioners in parallel provisioner "shell" { inline = ["echo 'Parallel provisioning'"] }}Template Organization
Section titled “Template Organization”packer/+------------------------------------------------------------------+| || packer.pkr.hcl # Main template || variables.pkr.hcl # Variable definitions || sources.pkr.hcl # Source definitions || builds.pkr.hcl # Build definitions || || scripts/ # Shell scripts || +-- setup.sh || +-- harden.sh || +-- install-tools.sh || || configs/ # Configuration files || +-- nginx.conf || +-- app.conf || || ansible/ # Ansible playbooks || +-- site.yml || +-- roles/ || +-- web-server/ || || manifests/ # Output manifests || +-- base-manifest.json || +-- app-manifest.json || |+------------------------------------------------------------------+42.12 Why This Matters in DevOps/SRE
Section titled “42.12 Why This Matters in DevOps/SRE”Packer is essential for creating consistent, immutable infrastructure. SREs use it to bake configuration into AMIs, reducing configuration drift and deployment time.
Packer in DevOps/SRE+------------------------------------------------------------------+| || SRE Image Management: || || 1. Immutable Infrastructure || +----------------------------------------------------------+ || | - Bake configuration into AMIs | || | - Same image across dev/staging/production | || | - Faster deployments, consistent environments | || +----------------------------------------------------------+ || || 2. Security & Compliance || +----------------------------------------------------------+ || | - Security hardening in the image | || | - Automated patching during image build | || | - Audit trail of image versions | || +----------------------------------------------------------+ || || 3. Golden Image Pipeline || +----------------------------------------------------------+ || | - Automated daily/weekly image builds | || | - Integration with CI/CD pipelines | || | - Automated testing before image promotion | || +----------------------------------------------------------+ || |+------------------------------------------------------------------+42.13 Linux Systems Perspective
Section titled “42.13 Linux Systems Perspective”Packer Automation from Arch Linux
Section titled “Packer Automation from Arch Linux”# Install Packer on Arch Linuxsudo pacman -S packer
# Verify installationpacker --version
# Build imagepacker build template.pkr.hcl
# Validate templatepacker validate template.pkr.hcl
# Debug buildPACKER_LOG=1 packer build template.pkr.hcl42.14 Common Mistakes & Anti-Patterns
Section titled “42.14 Common Mistakes & Anti-Patterns” Packer Anti-Patterns+------------------------------------------------------------------+| || ❌ Mistake 1: Building Images Manually || +----------------------------------------------------------+ || | Problem: Inconsistent images, configuration drift | || | Impact: Snowflake servers, deployment failures | || | Fix: Automate image building in CI/CD pipeline | || +----------------------------------------------------------+ || || ❌ Mistake 2: Not Using Version Control for Templates || +----------------------------------------------------------+ || | Problem: No audit trail, hard to reproduce images | || | Impact: Can't rollback, compliance gaps | || | Fix: Store templates in Git, use tags for versions | || +----------------------------------------------------------+ || || ❌ Mistake 3: Not Testing Built Images || +----------------------------------------------------------+ || | Problem: Bugs discovered after deployment | || | Impact: Failed deployments, rollbacks | || | Fix: Use test frameworks (Terratest, Inspec) | || +----------------------------------------------------------+ || || ❌ Mistake 4: Not Using Parallel Builds || +----------------------------------------------------------+ || | Problem: Slow image building for multiple regions | || | Impact: Long CI/CD pipeline times | || | Fix: Use parallel builds for multi-region AMIs | || +----------------------------------------------------------+ || |+------------------------------------------------------------------+42.15 Interview Questions
Section titled “42.15 Interview Questions”Conceptual Questions
Section titled “Conceptual Questions”-
Q: Explain the difference between Packer and configuration management tools like Ansible.
- A: Packer creates machine images (AMIs) at build time - it’s for provisioning. Ansible configures running systems at deployment time. Use both: Packer bakes base configuration into AMI, Ansible handles deployment-time configuration.
-
Q: Why use Golden Images?
- A: Golden images reduce deployment time, ensure consistency, enable faster scaling, reduce configuration drift, and improve security by baking in hardening. They also simplify troubleshooting by having known good states.
Scenario-Based Questions
Section titled “Scenario-Based Questions”- Q: Design an automated AMI pipeline.
- A: Use Packer with: (1) GitLab CI or CodePipeline trigger on schedule or code change, (2) Packer builds AMI with latest patches and configuration, (3) Terratest validates image functionality, (4) Resulting AMI tagged and stored, (5) Auto Scaling Groups updated to use new AMI.
42.16 Exam Tips
Section titled “42.16 Exam Tips”Common Issues
Section titled “Common Issues” Packer Troubleshooting+------------------------------------------------------------------+| || Issue: SSH Connection Timeout || +--------------------------------------------------------+ || | Solutions: | || | - Check security group allows SSH (port 22) | || | - Verify ssh_username matches AMI | || | - Increase ssh_timeout value | || | - Check subnet route table | || +--------------------------------------------------------+ || || Issue: AMI Creation Failed || +--------------------------------------------------------+ || | Solutions: | || | - Check IAM permissions | || | - Verify AMI name is unique | || | - Check EBS volume limits | || | - Review instance logs | || +--------------------------------------------------------+ || || Issue: Provisioner Failures || +--------------------------------------------------------+ || | Solutions: | || | - Enable debug logging: PACKER_LOG=1 | || | - Check script exit codes | || | - Verify file paths exist | || | - Test provisioners manually | || +--------------------------------------------------------+ || |+------------------------------------------------------------------+Debug Mode
Section titled “Debug Mode”# Enable debug loggingPACKER_LOG=1 packer build template.pkr.hcl
# Save log to filePACKER_LOG=1 PACKER_LOG_PATH=packer.log packer build template.pkr.hcl
# Debug mode (keeps instance running on failure)packer build -debug template.pkr.hcl
# On-error behaviorpacker build -on-error=ask template.pkr.hcl# Options: cleanup, abort, ask, run-cleanup-provisioner42.17 Key Takeaways
Section titled “42.17 Key Takeaways”| Topic | Key Points |
|---|---|
| Builders | Use appropriate builder for use case (EBS, instance, chroot) |
| Provisioners | Shell for simple, Ansible for complex configurations |
| Security | Use IAM roles, encrypt AMIs, isolate build environment |
| CI/CD | Integrate with pipelines for automated image building |
| Multi-Region | Use ami_regions for distribution, parallel builds for speed |
| Golden Images | Build layered images for maintainability |
42.18 References
Section titled “42.18 References”42.19 Summary
Section titled “42.19 Summary” Chapter 42 Summary+------------------------------------------------------------------+| || Packer - Machine Image Building || +------------------------------------------------------------+ || | - Immutable infrastructure through AMI baking | || | - Automated image creation with builders | || | - Configuration provisioning with provisioners | || | - Security best practices (IAM, encryption, isolation) | || +------------------------------------------------------------+ || || Key Components || +------------------------------------------------------------+ || | - Builders: EBS, Instance Store, Chroot | || | - Provisioners: Shell, Ansible, PowerShell | || | - Post-processors: AMIManage, Vagrant | || | - Variables: User, local, environment | || +------------------------------------------------------------+ || || Best Practices || +------------------------------------------------------------+ || | - Use IAM roles, not access keys | || | - Encrypt AMIs with KMS | || | - Build in isolated VPCs | || | - Integrate with CI/CD pipelines | || +------------------------------------------------------------+ || |+------------------------------------------------------------------+Next Chapter: Chapter 43 - Ansible on AWS