packer Documentation

Packer is a tool for creating identical machine images for multiple platforms from a single source configuration.

15,812 stars Go Go 13 files Β· ~5,909 tokens
RAW Doc

Docker & Self-Hosted Deployment Verified OCI

Deploy packer on any server, homelab, or cloud container platform.

1-Click Terminal Command
bash (docker run)
docker run -d --name packer --restart always hashicorp/packer:latest

Technical Documentation: hashicorp/packer

ℹ️ Provenance: Multi-Tier Ingestion Β· CodeWiki Reference

Overview (`README.md`)

Packer

[](LICENSE) [](https://github.com/hashicorp/packer/actions/workflows/build.yml) [](https://discuss.hashicorp.com/c/packer)

Packer is a tool for building identical machine images for multiple platforms
from a single source configuration.

Packer is lightweight, runs on every major operating system, and is highly
performant, creating machine images for multiple platforms in parallel. Packer
supports various platforms through external plugin integrations, the full list of which can
be found at https://developer.hashicorp.com/packer/integrations.

The images that Packer creates can easily be turned into Vagrant boxes.

Quick Start

Packer

There is a great introduction and getting started guide
for building a Docker image on your local machine without using any paid cloud resources.

Alternatively, you can refer to getting started with AWS to
learn how to build a machine image for an external cloud provider.

HCP Packer

HCP Packer registry stores Packer image metadata, enabling you to track your image lifecycle.

To get started with building an AWS machine image to HCP Packer for referencing in Terraform refer
to the collection of HCP Packer Tutorials.

Documentation

Comprehensive documentation is viewable on the Packer website at https://developer.hashicorp.com/packer/docs.

Contributing to Packer

See
CONTRIBUTING.md
for best practices and instructions on setting up your development environment
to work on Packer.

Contributing to Documentation

Important: Packer documentation has moved to the hashicorp/web-unified-docs repository.

To contribute documentation changes:

Unmaintained Plugins

As contributors' circumstances change, development on a community maintained
plugin can slow. When this happens, HashiCorp may use GitHub's option to archive the
plugin’s repository, to clearly signal the plugin's status to users.

What does unmaintained mean?

  1. The code repository and all commit history will still be available.
  2. Documentation will remain on the Packer website.
  3. Issues and pull requests are monitored as a best effort.
  4. No active development will be performed by HashiCorp.

If you are interested in maintaining an unmaintained or archived plugin, please reach out to us at [email protected].


Overview (`.github/workflows/nightly-release-readme.md`)

Nightly releases are snapshots of the development activity on the Packer project that may include new features and bug fixes scheduled for upcoming releases. These releases are made available to make it easier for users to test their existing build configurations against the latest Packer code base for potential issues or to experiment with new features, with a chance to provide feedback on ways to improve the changes before being released.

As these releases are snapshots of the latest code, you may encounter an issue compared to the latest stable release. Users are encouraged to run nightly releases in a non production environment. If you encounter an issue, please check our issue tracker to see if the issue has already been reported; if a report hasn't been made, please report it so we can review the issue and make any needed fixes.

Note: Nightly releases are only available via GitHub Releases, and artifacts are not codesigned or notarized. Distribution via other Release Channels such as the Releases Site or Homebrew is not yet supported.


Overview (`.release/docker/README.md`)

Packer Docker Container

The root of this repository contains the officially supported HashiCorp Dockerfile to build the hashicorp/packer docker image. The dev docker image should be built for local dev and testing, while the production docker image, release, is built in CI and makes use of CI-built binaries. The light and full docker images are built using the official binaries from releases.hashicorp.com.

License

This image is licensed under (BUSL-1.1)[https://github.com/hashicorp/packer/blob/main/LICENSE].

Build

Refer to the Makefile of this repository, especially the docker and docker-dev targets to build a local version of the dev image based on the sources available.

Usage

This repository automatically builds containers for using the
packer command line program. It contains three distinct
varieties of build: a light version, which just contains the binary,
a full build, which contains the Packer binary with pre-installed plugins,
and a dev version, which compiles the binary from source
inside the container before exposing it for use.

`light`

The light version of this container will copy the current stable version of
the binary, taken from releases.hashicorp.com, into the container. It will also
set it for use as the default entrypoint. This will be the best option for most uses,
especially if you are just looking to run the binary from a container.
The latest tag on DockerHub also points to this version.

You can use this version with the following:

shell
docker run <args> hashicorp/packer:light <command>

`full`

The full version of the container builds upon light and pre-installs
the plugins officially maintained by HashiCorp.

You can use this version with the following:

shell
docker run <args> hashicorp/packer:full <command>

You can view the list of pre-installed plugins with the following:

shell
docker run <args> hashicorp/packer:full plugins installed

`dev`

The dev version of this container contains all of the source code found in
the current ref of this repository. Using Google's
official golang image
as a base, this
container will copy the source from the current branch, build the binary, and
expose it for running. Because all build artifacts are included, it should be quite a bit larger than
the light image. This version of the container is most useful for development or
debugging.

You can use this version with the following:

shell
docker run <args> hashicorp/packer:dev <command>

Running a build:

The easiest way to run a command that references a configuration with one or more template files, is to mount a volume for the local workspace.

Running packer init

shell
docker run \
    -v `pwd`:/workspace -w /workspace \
    -e PACKER_PLUGIN_PATH=/workspace/.packer.d/plugins \
    hashicorp/packer:latest \
    init .

~> Note: packer init is available from Packer v1.7.0 and later

The command will mount the working directory (pwd) to workspace, which is the working directory (-w) inside the container.
Any plugin installed with packer init will be installed under the directory specified under the PACKER_PLUGIN_PATH environment variable. PACKER_PLUGIN_PATH must be set to a path inside the volume mount so that plugins can become available at packer build.

Running packer build

shell
docker run \
    -v `pwd`:/workspace -w /workspace \
    -e PACKER_PLUGIN_PATH=/workspace/.packer.d/plugins \
    hashicorp/packer:latest \
    build .

Building old-legacy JSON templates

For old-legacy JSON, the build command must specify the template file(s).

shell
docker run \
    -v `pwd`:/workspace -w /workspace \
    hashicorp/packer:latest \
    build template.json

For the manual installation of third-party plugins, we recommended that plugin binaries are placed under a sub-directory under the working directory. Add -e PACKER_PLUGIN_PATH=/workspace/<subdirectory_plugin_path> to the command above to tell Packer where the plugins are.

To pass a var file (var.json) to the build command:

shell
docker run \
    -v `pwd`:/workspace -w /workspace \
    hashicorp/packer:latest \
    build --var-file var.json template.json

var.json is expected to be inside the local working directory (pwd) and in the container's workspace mount.


Overview (`examples/ci/README.md`)

Provenance CI reference workflows

These are copy-paste reference workflows for producing SLSA provenance with the
Packer provenance post-processor. They are not wired into this
repository's own CI β€” copy them into your project's .github/workflows/
directory and adapt the template and artifact paths.

SLSA levels and Packer

SLSA Build levels are mostly properties of the build platform, not the
build tool. Packer is a tool, so its reach is:

SLSA Build level Requirement Packer's role What Packer provides
L1 Provenance exists and is distributed Fully in Packer Provenance generation
L2 Provenance signed by a hosted platform Packer signs via CI OIDC identity Keyless signing in CI
L3 Hardened platform; build steps cannot reach the signing key Platform property; Packer is compatible Delegated-signing pattern
L4 β€” Not defined in SLSA v1.0 β€”

Packer generates SLSA Provenance v1 and reaches Build L1, and L2 when run on a
hosted CI with keyless signing. L3 is a property of the build platform: it
requires the signing key to be unreachable by the build steps. Packer does not
confer L3 on its own, but the delegated-signing pattern below is compatible with
an L3 platform.

Workflows

  • github-actions-l2-keyless.yml β€” L2: Packer
    signs provenance keyless using the workflow's OIDC identity, uploads to Rekor,
    and verifies the signed attestation with packer verify-attestation.
  • github-actions-l3-delegated.yml β€”
    L3-compatible: the build job only builds and publishes a digest; provenance
    generation and signing are delegated to an isolated reusable workflow so the
    build steps cannot reach the signing material.

Overview (`post-processor/provenance/README.md`)

Provenance Post-Processor

The provenance post-processor writes in-toto attestations for the incoming
artifact.

It supports:

  • SLSA provenance statements enriched with source-control and CI metadata.
  • SBOM sidecars plus SBOM attestations.
  • Optional DSSE signing with a configurable signer and verifier.

Signing defaults to none, which writes the unsigned JSON statement.

Source detection

The provenance statement records the build's source repository as a resolved
dependency. Packer detects this from the Git repository containing the current
working directory (the directory Packer runs in). Set source_uri to override
the detected value, for example when the build runs outside the source checkout
or the remote URL should be normalized.

Signing modes:

  • key signs with a PEM private key and verifies with either the signer's
    derived public key or an explicit verifier PEM.
  • kms signs with a KMS or Vault URI such as awskms://..., gcpkms://...,
    azurekms://..., or hashivault://.... Verification uses the fetched KMS
    public key or an explicit verifier PEM.
  • keyless signs with an ephemeral keypair and a Fulcio-issued certificate.
    It requires an ambient OIDC token, such as SIGSTORE_ID_TOKEN, or a CI
    provider token that can be exchanged for a Sigstore identity. When using the
    built-in verifier path, also configure the expected signing identity and OIDC
    issuer. Set an optional trusted-root JSON path to pin verification to a
    specific Sigstore root; otherwise the public Sigstore trusted root is fetched.
    Keyless signing can also emit a Sigstore bundle sidecar and upload to Rekor.

Example:

hcl
post-processor "provenance" {
  build_type = "https://packer.io/buildtypes/hcl2/v1"
  template   = "ubuntu.pkr.hcl"
  only_builds = ["qemu.ubuntu"]
  user_variables = {
    region = "us-east-1"
  }
  sbom = true
}

Signed example:

hcl
post-processor "provenance" {
  signing_mode = "key"
  signer       = "keys/provenance-signing.pem"
  verifier     = "keys/provenance-signing.pub.pem"
  sbom         = true
}

KMS example:

hcl
post-processor "provenance" {
  signing_mode = "kms"
  signer       = "awskms://alias/packer-provenance"
  sbom         = true
}

Keyless example:

hcl
post-processor "provenance" {
  signing_mode        = "keyless"
  fulcio_url          = "https://fulcio.sigstore.dev"
  rekor_url           = "https://rekor.sigstore.dev"
  upload_tlog         = true
  keyless_identity    = "https://github.com/hashicorp/packer/.github/workflows/build.yml@refs/heads/main"
  keyless_oidc_issuer = "https://token.actions.githubusercontent.com"
  trusted_root_path   = "sigstore-trusted-root.json"
}

With keyless signing, Packer writes an additional *.sigstore.json sidecar next
to each signed attestation. When upload_tlog = true, that bundle includes
Rekor-backed transparency evidence for packer verify-attestation -bundle ....

During a build, keyless verification enforces the Fulcio certificate chain and
the configured identity policy. For Rekor-backed verification, run
packer verify-attestation with the generated Sigstore bundle and the
-require-rekor and/or -require-timestamp flags.

SLSA levels and CI

SLSA Build levels are mostly properties of the build platform, not the build
tool. Packer is a tool, so its reach is:

SLSA Build level Requirement Packer's role What Packer provides
L1 Provenance exists and is distributed Fully in Packer Provenance generation
L2 Provenance signed by a hosted platform Packer signs via CI OIDC identity Keyless signing in CI
L3 Hardened platform; build steps cannot reach the signing key Platform property; Packer is compatible Delegated-signing pattern
L4 β€” Not defined in SLSA v1.0 β€”

Packer generates SLSA Provenance v1 and reaches Build L1, and L2 when run on a
hosted CI with keyless signing. L3 is a property of the build platform: it
requires the signing key to be unreachable by the build steps. Packer does not
confer L3 on its own, but the delegated-signing pattern is compatible with an L3
platform.

Reference GitHub Actions workflows for both the L2 keyless pattern and the
L3-compatible delegated-signing pattern live under
examples/ci/.


Overview (`examples/hcl/linux/README.md`)

Basic HCL2 Ubuntu builders

Taking the chef/bento repo as an example.

I recommend you start by reading the build.pkr.hcl file and the
comments/description there.


Overview (`packer_test/common/plugin_tester/README.md`)

Packer Test Plugin

This directory is meant to be a minimal plugin that we can use for testing Packer.
Any components defined in this plugin are not for use, as they virtually do nothing, and are only here to test Packer's core capabilities


Overview (`packer_test/common/plugin_tester/docs/README.md`)

Scaffolding Plugins

Installation

Using pre-built releases

Using the `packer init` command

Starting from version 1.7, Packer supports a new packer init command allowing
automatic installation of Packer plugins. Read the
Packer documentation for more information.

To install this plugin, copy and paste this code into your Packer configuration .
Then, run packer init.

hcl
packer {
  required_plugins {
    name = {
      version = ">= 0.0.1"
      source  = "github.com/hashicorp/name"
    }
  }
}

Note: With the new Packer release starting from version 1.14.0, the packer init command will automatically install official (Amazon, Ansible, Azure, Docker, GoogleCloudPlatform, Qemu, Vagrant, VirtualBox) plugins from the HashiCorp release site.
These official plugins will now be released through the official release site only.

Going forward, to use newer versions of official Packer plugins, you'll need to upgrade to Packer version 1.14.0 or later. If you're using an older version, you can still install plugins, but as a workaround, you'll need to manually install them using the CLI.
There is no change to the syntax or commands for installing plugins.

Manual installation

You can find pre-built binary releases of the plugin here.
Once you have downloaded the latest archive corresponding to your target OS,
uncompress it to retrieve the plugin binary file corresponding to your platform.
To install the plugin, please follow the Packer documentation on
installing a plugin.

From Source

If you prefer to build the plugin from its source code, clone the GitHub
repository locally and run the command go build from the root
directory. Upon successful compilation, a packer-plugin-name plugin
binary file can be found in the root directory.
To install the compiled plugin, please follow the official Packer documentation
on installing a plugin.

Plugin Contents

The Scaffolding plugin is intended as a starting point for creating Packer plugins, containing:

Builders

  • builder - The scaffolding builder is used to create endless Packer
    plugins using a consistent plugin structure.

Provisioners

  • provisioner - The scaffolding provisioner is used to provision
    Packer builds.

Post-processors

  • post-processor - The scaffolding post-processor is used to
    export scaffolding builds.

Data Sources

  • data source - The scaffolding data source is used to
    export scaffolding data.

Overview (`packer_test/common/plugin_tester/example/README.md`)

The Example Folder

This folder must contain a fully working example of the plugin usage. The example must define the required_plugins
block. A pre-defined GitHub Action will run packer init, packer validate, and packer build to test your plugin
with the latest version available of Packer.

The folder can contain multiple HCL2 compatible files. The action will execute Packer at this folder level
running packer init -upgrade . and packer build ..

If the plugin requires authentication, the configuration should be provided via GitHub Secrets and set as environment
variables in the test-plugin-example.yml file. Example:

yml
- name: Build
    working-directory: ${{ github.event.inputs.folder }}
    run: PACKER_LOG=${{ github.event.inputs.logs }} packer build .
    env:
      AUTH_KEY: ${{ secrets.AUTH_KEY }}
      AUTH_PASSWORD: ${{ secrets.AUTH_PASSWORD }}

Packer Test Common Plugin Tester Docs Builders Builder Name (`packer_test/common/plugin_tester/docs/builders/builder-name.mdx`)


The scaffolding builder is used to create endless Packer plugins using a consistent plugin structure. page_title: Scaffolding - Builders nav_title: Scaffolding

Scaffolding

Type: scaffolding

The scaffolding builder is used to create endless Packer plugins using
a consistent plugin structure.

Required

  • mock (string) - The name of the mock to use for the Scaffolding API.

Optional

  • mock_api_url (string) - The Scaffolding API endpoint to connect to.
    Defaults to https://example.com

Example Usage

hcl
source "scaffolding" "example" {
   mock = "bird"
 }

 build {
   sources = ["source.scaffolding.example"]
 }

Packer Test Common Plugin Tester Docs Datasources Datasource Name (`packer_test/common/plugin_tester/docs/datasources/datasource-name.mdx`)


The scaffolding data source is used to create endless Packer plugins using a consistent plugin structure. page_title: Scaffolding - Data Sources nav_title: Scaffolding

Scaffolding

Type: scaffolding

The scaffolding data source is used to create endless Packer plugins using
a consistent plugin structure.

Required

  • mock (string) - The name of the mock to use for the Scaffolding API.

Optional

  • mock_api_url (string) - The Scaffolding API endpoint to connect to.
    Defaults to https://example.com

OutPut

  • foo (string) - The Scaffolding output foo value.
  • bar (string) - The Scaffolding output bar value.

Example Usage

hcl
data "scaffolding" "example" {
   mock = "bird"
 }
 source "scaffolding" "example" {
   mock = data.scaffolding.example.foo
 }

 build {
   sources = ["source.scaffolding.example"]
 }

Packer Test Common Plugin Tester Docs Post Processors Postprocessor Name (`packer_test/common/plugin_tester/docs/post-processors/postprocessor-name.mdx`)


The scaffolding post-processor is used to export Packer Scaffolding builds. page_title: Scaffolding - Post-Processors nav_title: Scaffolding

Scaffolding

Type: scaffolding

The scaffolding post-processor is used to export Packer Scaffolding builds.

Required

  • mock (string) - The output path where to save exported build to.

Optional

Example Usage

hcl
source "scaffolding" "example" {
   mock = "jay"
 }

 build {
   sources = ["source.scaffolding.example"]

   post-processor "scaffolding" {
     mock = "builds/scaffolding.box"
   }
 }

Packer Test Common Plugin Tester Docs Provisioners Provisioner Name (`packer_test/common/plugin_tester/docs/provisioners/provisioner-name.mdx`)


The scaffolding provisioner is used to provisioner Packer builds. page_title: Scaffolding - Provisioners nav_title: Scaffolding

Scaffolding

Type: scaffolding

The scaffolding provisioner is used to provisioner Packer builds.

Required

  • mock (string) - The name of the mock string to display.

Optional

Example Usage

hcl
source "null" "example" {
   communicator = "none"
 }

 build {
   source "null.example" {
     name = "jay"
   }

   provisioner "scaffolding" {
     mock = "mocking ${source.name}"
   }
 }

--- METRICS ---