---
description: |
  The `post-processor` block defines actions to perform on images after Packer builds them. Learn how to configure the `post-processor` block in JSON templates.
page_title: post-processors reference for JSON templates
---

⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️
> [!IMPORTANT]  
> **Documentation Update:** Product documentation previously located in `/website` has moved to the [`hashicorp/web-unified-docs`](https://github.com/hashicorp/web-unified-docs) repository, where all product documentation is now centralized. Please make contributions directly to `web-unified-docs`, since changes to `/website` in this repository will not appear on developer.hashicorp.com.
⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️⚠️

# `post-processors` reference for JSON templates

This documentation describes how to configure a `post-processor` block in JSON
templates. Refer to the documentation for each post-processor type for their specific configuration options.

`@include 'from-1.5/legacy-json-warning.mdx'`

## Description

The `post-processor` block defines additional actions to perform on the images built by the builders. For example, you can configure the `post-processor` to compress files and upload artifacts.

Post-processors are _optional_. If no post-processors are defined within a
template, then no post-processing will be done to the image. The resulting
artifact of a build is just the image outputted by the builder.


Within a template, a section of post-processor definitions looks like this:

```json
{
  "post-processors": [
    // ... one or more post-processor definitions here
  ]
}
```

For each post-processor definition, Packer will take the result of each of the
defined builders and send it through the post-processors. This means that if
you have one post-processor defined and two builders defined in a template, the
post-processor will run twice (once for each builder), by default. There are
ways, which will be covered later, to control what builders post-processors
apply to, if you wish. It is also possible to prevent a post-processor from
running.

## Post-Processor Definition

Within the `post-processors` array in a template, there are three ways to
define a post-processor. There are _simple_ definitions, _detailed_
definitions, and _sequence_ definitions. Another way to think about this is
that the "simple" and "detailed" definitions are shortcuts for the "sequence"
definition.

A **simple definition** is just a string; the name of the post-processor. An
example is shown below. Simple definitions are used when no additional
configuration is needed for the post-processor.

```json
{
  "post-processors": ["compress"]
}
```

A **detailed definition** is a JSON object. It is very similar to a builder or
provisioner definition. It contains a `type` field to denote the type of the
post-processor, but may also contain additional configuration for the
post-processor. A detailed definition is used when additional configuration is
needed beyond simply the type for the post-processor. An example is shown
below.

```json
{
  "post-processors": [
    {
      "type": "compress",
      "format": "tar.gz"
    }
  ]
}
```

A **sequence definition** is a JSON array comprised of other **simple** or
**detailed** definitions. The post-processors defined in the array are run in
order, with the artifact of each feeding into the next, and any intermediary
artifacts being discarded. A sequence definition may not contain another
sequence definition. Sequence definitions are used to chain together multiple
post-processors. An example is shown below, where the artifact of a build is
compressed then uploaded, but the compressed result is not kept.

It is very important that any post processors that need to be run in order, be
sequenced!

```json
{
  "post-processors": [
    ["compress", { "type": "upload", "endpoint": "http://example.com" }]
  ]
}
```

As you may be able to imagine, the **simple** and **detailed** definitions are
simply shortcuts for a **sequence** definition of only one element.

## Input Artifacts

When using post-processors, the input artifact (coming from a builder or
another post-processor) is discarded by default after the post-processor runs.
This is because generally, you don't want the intermediary artifacts on the way
to the final artifact created.

In some cases, however, you may want to keep the intermediary artifacts. You
can tell Packer to keep these artifacts by setting the `keep_input_artifact`
configuration to `true`. An example is shown below:

```json
{
  "post-processors": [
    {
      "type": "compress",
      "keep_input_artifact": true
    }
  ]
}
```

This setting will only keep the input artifact to _that specific_
post-processor. If you're specifying a sequence of post-processors, then all
intermediaries are discarded by default except for the input artifacts to
post-processors that explicitly state to keep the input artifact.

-> **Note:** The intuitive reader may be wondering what happens if multiple
post-processors are specified (not in a sequence). Does Packer require the
configuration to keep the input artifact on all the post-processors? The answer
is no, of course not. Packer is smart enough to figure out that at least one
post-processor requested that the input be kept, so it will keep it around.

## Run on Specific Builds

You can use the `only` or `except` fields to run a post-processor only with
specific builds. These two fields do what you expect: `only` will only run the
post-processor on the specified builds and `except` will run the post-processor
on anything other than the specified builds. A sequence of post-processors will
execute until a skipped post-processor.

An example of `only` being used is shown below, but the usage of `except` is
effectively the same. `only` and `except` can only be specified on "detailed"
fields. If you have a sequence of post-processors to run, `only` and `except`
will affect that post-processor and stop the sequence.

The `-except` option can specifically skip a named post processor. The `-only`
option _ignores_ post-processors.

```json
([
  {
    "name": "vbox",
    "type": "vagrant",
    "only": ["virtualbox-iso"]
  },
  {
    "type": "compress"
  }
],
[
  "compress",
  {
    "type": "upload",
    "endpoint": "http://example.com"
  }
])
```

The values within `only` or `except` are _build names_, not builder types.
Name is a required block label in HCL, but in legacy JSON, build names default
to the types of their builders (e.g. `docker` or `amazon-ebs` or
`virtualbox-iso`), unless a specific `name` attribute is specified within the
configuration.
