HashiCorp Packer

HashiCorp Packer Basics

Demo

In this walkthrough, you’ll create an AWS AMI that comes pre-installed with Nginx and configured with firewall rules, leveraging HashiCorp Packer for automation.


1. Install Packer

Download and install Packer for your platform. See the official guide for detailed instructions:
https://developer.hashicorp.com/packer/downloads

On macOS:

brew tap hashicorp/tap
brew install hashicorp/tap/packer

2. (Optional) VS Code HCL Extension

For better HCL syntax highlighting in VS Code, search for HCL in the Extensions Marketplace.

The image shows the Visual Studio Code interface with the Extensions Marketplace open, displaying search results for "HCL" extensions.

You can install similar plugins for other editors as needed.


3. Create the Packer Template

Create a file named aws-ubuntu.pkr.hcl. Packer HCL templates require the .pkr.hcl extension.

3.1 Declare Required Plugins

Every Packer template must list its plugins. For AWS, include the amazon builder plugin:

packer {
  required_plugins {
    amazon = {
      version = ">= 1.1.1"
      source  = "github.com/hashicorp/amazon"
    }
  }
}

3.2 Configure the Amazon EBS Builder

Use the amazon-ebs source to create an EBS-backed AMI. Refer to the Amazon AMI Builder plugin documentation for a full list of options.

The image shows a webpage from HashiCorp's documentation site, detailing the Amazon AMI Builder plugin for Packer, including an overview and instructions on how to use the plugin.

source "amazon-ebs" "ubuntu" {
  ami_name      = "my-first-packer-image"
  instance_type = "t2.micro"
  region        = "us-east-1"
  source_ami    = "ami-0557a15b87f6559cf"
  ssh_username  = "ubuntu"
  access_key    = "<YOUR_AWS_ACCESS_KEY>"
  secret_key    = "<YOUR_AWS_SECRET_KEY>"
}

Warning

Do not commit AWS credentials in your template. Use environment variables or an IAM role with least-privilege permissions instead.

For details on required vs. optional parameters, see the AMI configuration docs:

The image shows a webpage with documentation related to AMI configuration, including sections on required and optional parameters. There is a sidebar with a list of topics covered on the page.

Note

Find the Ubuntu source_ami ID under EC2 > AMIs in your AWS Console after selecting your region.

The image shows the AWS EC2 Management Console, displaying resources and options for managing instances in the US East (N. Virginia) region. It includes sections for launching instances, service health, and exploring AWS features.

The image shows an AWS EC2 console screen displaying a list of Ubuntu AMIs available for selection, with options for different versions and architectures.

Replace <YOUR_SOURCE_AMI_ID> in your template once you’ve copied it.


4. Build, Provision, and Post-Process

Add a build block that references your amazon-ebs source and provisions the instance:

build {
  name    = "my-first-build"
  sources = ["source.amazon-ebs.ubuntu"]

  provisioner "shell" {
    inline = [
      "sudo apt update",
      "sudo apt install nginx -y",
      "sudo systemctl enable nginx",
      "sudo systemctl start nginx",
      "sudo ufw allow proto tcp from any to any port 22,80,443",
      "echo 'y' | sudo ufw enable"
    ]
  }

  post-processor "vagrant" {}
  post-processor "compress" {}
}
ComponentPurposeExample Configuration
shellInstalls Nginx and configures UFWprovisioner "shell" { ... }
vagrantPackages the image as a Vagrant boxpost-processor "vagrant" {}
compressArchives the box output (.box file)post-processor "compress" {}

5. Initialize, Format & Validate

Execute these commands in the directory containing aws-ubuntu.pkr.hcl:

CommandDescription
packer init .Install required plugins
packer fmt .Reformat HCL for readability
packer validate .Verify template syntax and configuration

6. Build the AMI

Run the build:

packer build aws-ubuntu.pkr.hcl

A successful run will output something like:

==> my-first-build.amazon-ebs.ubuntu: Creating temporary keypair: packer_...
==> my-first-build.amazon-ebs.ubuntu: Launching a source AWS instance...
==> my-first-build.amazon-ebs.ubuntu: Provisioning with shell script...
...
==> my-first-build.amazon-ebs.ubuntu: AMI: ami-0abcd1234ef567890
...
==> Builds finished. The artifacts of successful builds are:
--> my-first-build.amazon-ebs.ubuntu: AMIs were created:
    - ami-0abcd1234ef567890
--> my-first-build.amazon-ebs.ubuntu: Vagrant box: packer-vagrant.box

7. Verify the AMI

In the AWS Console, locate the AMI named my-first-packer-image. Launch a new EC2 instance, ensure the security group allows HTTP/HTTPS, and wait for provisioning:

The image shows an AWS EC2 Management Console screen where an instance is being launched, with a progress bar indicating "Creating security groups" at 15%.

Once running, navigate to the instance’s public IP to confirm the Nginx default page displays.


Watch Video

Watch video content

Previous
Workflow in Immutable Infrastructure using Packer