# Technical Documentation: hashicorp/packer

> ℹ️ **Provenance:** Multi-Tier Ingestion · [CodeWiki Reference](https://codewiki.google/github.com/hashicorp/packer)

### Overview (`README.md`)

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

<p align="center" style="text-align:center;">
  <a href="https://www.packer.io">
    <img alt="HashiCorp Packer logo" src="assets/public/img/logo-packer-padded.svg" width="500" />
  </a>
</p>

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](http://www.vagrantup.com) boxes.

## Quick Start

### Packer 

There is a great [introduction and getting started guide](https://learn.hashicorp.com/tutorials/packer/get-started-install-cli)
for building a Docker image on your local machine without using any paid cloud resources. 

Alternatively, you can refer to [getting started with AWS](https://developer.hashicorp.com/packer/tutorials/aws-get-started) 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](https://developer.hashicorp.com/packer/tutorials/hcp-get-started).

## Documentation

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

## Contributing to Packer

See
[CONTRIBUTING.md](https://github.com/hashicorp/packer/blob/main/.github/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`](https://github.com/hashicorp/web-unified-docs) repository.

To contribute documentation changes:
- Make contributions directly to the `web-unified-docs` repository
- See the [Updating Documentation section](https://github.com/hashicorp/packer/blob/main/.github/CONTRIBUTING.md#updating-documentation) in CONTRIBUTING.md for detailed instructions

## 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.
1. Documentation will remain on the Packer website.
1. Issues and pull requests are monitored as a best effort.
1. 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 packer@hashicorp.com.

---

### 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](https://github.com/hashicorp/packer/milestones). 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](https://github.com/hashicorp/packer/issues) 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](https://www.hashicorp.com/official-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`](https://developer.hashicorp.com/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](https://github.com/hashicorp/packer). Using [Google's
official `golang` image](https://hub.docker.com/_/golang/) 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](https://www.packer.io/docs/plugins#installing-plugins) 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`](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`](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/`](../../examples/ci/).

---

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

# Basic HCL2 Ubuntu builders

Taking the [chef/bento](https://github.com/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](https://www.packer.io/docs/commands/init) for more information.

To install this plugin, copy and paste this code into your Packer configuration .
Then, run [`packer init`](https://www.packer.io/docs/commands/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](https://releases.hashicorp.com/). 
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](https://developer.hashicorp.com/packer/docs/plugins/install#manually-install-plugins-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](https://github.com/hashicorp/packer-plugin-name/releases).
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](https://www.packer.io/docs/extending/plugins/#installing-plugins).


#### 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](https://www.packer.io/docs/extending/plugins/#installing-plugins).


## Plugin Contents

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

### Builders

- [builder](/docs/builders/builder-name.mdx) - The scaffolding builder is used to create endless Packer
  plugins using a consistent plugin structure.

### Provisioners

- [provisioner](/docs/provisioners/provisioner-name.mdx) - The scaffolding provisioner is used to provision
  Packer builds.

### Post-processors

- [post-processor](/docs/post-processors/postprocessor-name.mdx) - The scaffolding post-processor is used to
  export scaffolding builds.

### Data Sources

- [data source](/docs/datasources/datasource-name.mdx) - 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](/.github/workflows/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`)

---
description: >
  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`)

---
description: >
  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`)

---
description: >
  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`)

---
description: >
  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 ---
- Files Extracted: 13
- Estimated Token Budget: ~5830 tokens
- Canonical Reference: https://codewiki.google/github.com/hashicorp/packer
