---
description: |
  The `provisioners` block contains provisioners that Packer uses to install and configure software on machines. Learn how to configure provisioners in JSON templates.
page_title: provisioners reference for JSON templates
---

# `provisioners` reference for JSON templates

This topic provides reference information about the `provisioners` block in JSON templates for Packer. Refer to the documentation for specific provisioner types to learn about their configuration options.

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

## Description

The `provisioners` block contains provisioners that Packer uses to install and configure software within running machines prior to turning them into machine images.

Provisioners are optional. When you omit the `provisioners` block, Packer installs only the default software within the resulting machine images. 

Use the following syntax to add the `provisioners` block to your JSON template:

```json
{
  "provisioners": [
    // ... one or more provisioner definitions here
  ]
}
```

For each of the definitions, Packer will run the provisioner for each of the
configured builds. The provisioners will be run in the order they are defined
within the template.

## Provisioner Definition

A provisioner definition is a JSON object that must contain at least the `type`
key. This key specifies the name of the provisioner to use. Additional keys
within the object are used to configure the provisioner, with the exception of
a handful of special keys, covered later.

As an example, the "shell" provisioner requires a key such as `script` which
specifies a path to a shell script to execute within the machines being
created.

An example provisioner definition is shown below, configuring the shell
provisioner to run a local script within the machines:

```json
{
  "type": "shell",
  "script": "script.sh"
}
```

## Run on Specific Builds

You can use the `only` or `except` configurations to run a provisioner only
with specific builds. These two configurations do what you expect: `only` will
only run the provisioner on the specified builds and `except` will run the
provisioner on anything other than the specified builds.

An example of `only` being used is shown below, but the usage of `except` is
effectively the same:

```json
{
  "type": "shell",
  "script": "script.sh",
  "only": ["virtualbox-iso"]
}
```

The values within `only` or `except` are _build names_, not builder types. If
you recall, build names by default are just their builder type, but if you
specify a custom `name` parameter, then you should use that as the value
instead of the type.
Values within `except` could also be a _post-processor_ name.

## On Error Provisioner

You can optionally create a single specialized provisioner field called an
`error-cleanup-provisioner`. This provisioner will not run unless the normal
provisioning run fails. If the normal provisioning run does fail, this special
error provisioner will run _before the instance is shut down_. This allows you
to make last minute changes and clean up behaviors that Packer may not be able
to clean up on its own.

For examples, users may use this provisioner to make sure that the instance is
properly unsubscribed from any services that it connected to during the build
run.

Toy usage example for the error cleanup script:

```json
{
  "builders": [
    {
      "type": "null",
      "communicator": "none"
    }
  ],
  "provisioners": [
    {
      "type": "shell-local",
      "inline": ["exit 2"]
    }
  ],
  "error-cleanup-provisioner": {
    "type": "shell-local",
    "inline": ["echo 'rubber ducky'> ducky.txt"]
  }
}
```

## Build-Specific Overrides

While the goal of Packer is to produce identical machine images, it sometimes
requires periods of time where the machines are different before they
eventually converge to be identical. In these cases, different configurations
for provisioners may be necessary depending on the build. This can be done
using build-specific overrides.

An example of where this might be necessary is when building both an EC2 AMI
and a VMware machine. The source EC2 AMI may setup a user with administrative
privileges by default, whereas the VMware machine doesn't have these
privileges. In this case, the shell script may need to be executed differently.
Of course, the goal is that hopefully the shell script converges these two
images to be identical. However, they may initially need to be run differently.

This example is shown below:

```json
{
  "type": "shell",
  "script": "script.sh",
  "override": {
    "vmware-iso": {
      "execute_command": "echo 'password' | sudo -S bash {{.Path}}"
    }
  }
}
```

As you can see, the `override` key is used. The value of this key is another
JSON object where the key is the name of a [builder
definition](/packer/docs/templates/legacy_json_templates/builders). The value of this is in turn
another JSON object. This JSON object simply contains the provisioner
configuration as normal. This configuration is merged into the default
provisioner configuration.

## Pausing Before Running

With certain provisioners it is sometimes desirable to pause for some period of
time before running it. Specifically, in cases where a provisioner reboots the
machine, you may want to wait for some period of time before starting the next
provisioner.

Every provisioner definition in a Packer template can take a special
configuration `pause_before` that is the amount of time to pause before running
that provisioner. By default, there is no pause. An example is shown below:

```json
{
  "type": "shell",
  "script": "script.sh",
  "pause_before": "10s"
}
```

For the above provisioner, Packer will wait 10 seconds before uploading and
executing the shell script.

## Retry on error

With certain provisioners it is sometimes desirable to retry when it fails.
Specifically, in cases where the provisioner depends on external processes that are not done yet.

Every provisioner definition in a Packer template can take a special
configuration `max_retries` that is the maximum number of times a provisioner will retry on error.
By default, there `max_retries` is zero and there is no retry on error. An example is shown below:

```json
{
  "type": "shell",
  "script": "script.sh",
  "max_retries": 5
}
```

For the above provisioner, Packer will retry maximum five times until stops failing.
If after five retries the provisioner still fails, then the complete build will fail.

## Timeout

Sometimes a command can take much more time than expected

Every provisioner definition in a Packer template can take a special
configuration `timeout` that is the amount of time to wait before
considering that the provisioner failed. By default, there is no timeout. An
example is shown below:

```json
{
  "type": "shell",
  "script": "script.sh",
  "timeout": "5m"
}
```

For the above provisioner, Packer will cancel the script if it takes more than
5 minutes.

Timeout has no effect in debug mode.
