Installing Plugins
Packer plugins are separate, standalone applications that perform tasks during each build.
This page explains how to install external plugins. Refer to Integrations for a list of available plugins and their documentation.
Depending on the template type you're using (HCL2 or legacy JSON), the methods for installing plugins may differ.
If you're using HCL2, packer init
is recommended as you can install all your requirements with one
command, and those requirements are explicitly documented in the template.
packer plugins install
is also used to automate the installation from a source, and will need to
be repeated for as many plugins as you need.
We recommend this for JSON as the template cannot contain the information about the required plugins.
While packer plugins install
is able to install plugins remotely, you can use
the --path
flag to install locally-sourced plugin binaries.
This is typically useful in two general cases:
- You are in an environment with restricted access to a plugin's source.
- You are trying to install a development version of a plugin for testing.
Refer to the Installation Guides section of this page for information about each method, including usage examples.
The remainder of this document documents how Packer interacts with plugins. We encourage you to read this to get familiar with this process, as it will help you troubleshoot builds if you encounter problems with plugins.
Source Addresses
A plugin's source address is conceptually where a plugin binary can be downloaded from. Packer also uses this source as a global unique identifier. This source translates directly to the file hierarchy in which the plugin binaries will be installed.
Source addresses are a URL, without a scheme (e.g. "https://"
), query (e.g. ?arg=val
), or
fragment (e.g. #anchor
).
Example: github.com/hashicorp/happycloud
Github sources
Github sources all follow this convention: <hostname>/<namespace>/<type>
.
Hostname: The hostname of the location/service that distributes the plugin.
Namespace: An organizational namespace within the specified host. This often is the organization that maintains the plugin.
Type: A short name for the platform or system the plugin manages. The type is usually the plugin's preferred local name.
For example, the fictional happycloud
plugin could belong to the
hashicorp
namespace on github.com
, so its source
could be
github.com/hashicorp/happycloud
,
Note: the actual repository that happycloud comes from must always have
the name format github.com/hashicorp/packer-plugin-happycloud
, but the
source voluntarily omits the redundant packer-plugin-
prefix for brevity.
The source address with all the components given explicitly is called the plugin's fully-qualified address. You will see fully-qualified addresses in various outputs, like error messages.
Source and local hierarchy
As mentioned above, each source URL will directly impact how Packer will install a plugin to the local plugin directory. Each component of the path described will become a subdirectory, and finally, plugin binaries are installed at the end of that hierarchy. Multiple versions can be installed along one another.
In order for the binaries installed in this directory to be discovered and used by Packer, they must follow this set of rules:
The name of the binary must be in the
packer-plugin-<name>_<version>_x<api_version>_<os>_<arch>(.exe)?
formatThe binary must be accompanied by a SHA256SUM file, which must contain the SHA256 hash of the binary
The
describe
command of the binary must return informations that match the plugin's name, namely:a. The plugin version must match the name
b. The API version must match the name's
The version must be canonical: e.g. 1.0.1 (valid) vs. 01.000.01 (invalid)
The version must be valid semver (e.g. 1.0.0)
Pre-releases are accepted, but must be
-dev
only.Metadata shall not be in the name of the plugin binary, only metadata-free versions will be considered valid for discovery purposes.
Plugin Discovery Workflow
At initialization, Packer attempts to discover the plugins installed locally. The logic follows what's described in Configuring Packer's plugin directory section.
While Packer is not verbose during this step, you can peek into what it is discovering
with PACKER_LOG=1
enabled, where you can find log lines similar to the following:
[TRACE] discovering plugins in [...][INFO] Discovered potential plugin: [...]
Once this discovery step has finished, each discovered plugin will be ready to use by Packer, on the highest available version.
Example:
<packer_plugin_dir>└── github.com └── hashicorp └── happycloud ├── packer-plugin-happycloud_v1.1.8_x5.0_linux_amd64 ├── packer-plugin-happycloud_v1.1.8_x5.0_linux_amd64_SHA256SUM ├── packer-plugin-happycloud_v1.2.8_x5.0_linux_amd64 └── packer-plugin-happycloud_v1.2.8_x5.0_linux_amd64_SHA256SUM
In this example, the happycloud
plugin will be the one and used to serve
happycloud-related components, in version 1.2.8.
HCL2 and required_plugins
The aforementioned logic is all that can apply to legacy JSON templates.
HCL2 however introduces the concept of required_plugins
blocks.
These blocks allow you to declare what plugins your template needs in order
to be able to build an artifact, along with version constraints.
Example:
packer{ required_plugins { happycloud = { source = "github.com/hashicorp/happycloud" version = "= 1.1.8" } }}
With this constraint specified, Packer will not only be able to remotely install
the plugin you need with packer init
(provided it is hosted on a remote that the command
supports), but also restrict which versions can be used for building the template.
Using the aforementioned plugin hierarchy, a constraint like the one above will take precedence over the usual discovery process, this time yielding version 1.1.8 of the happycloud plugin for serving its components.
Installation Guides
Packer init
Using packer init
requires using HCL2 templates. If you are using JSON and
want to start using HCL2 templates in order to leverage this feature, please
refer to our JSON to HCL guide.
In order to use packer init
for managing installation of your plugins, there are
two steps required.
First, add a required_plugins
block to your packer block.
Each block will tell Packer what version(s) of a particular plugin can be installed. Make sure to set a valid version constraint string.
Here is an example required_plugins
block:
packer { required_plugins { myawesomecloud = { version = ">= 2.7.0" source = "github.com/hashicorp/myawesomecloud" } happycloud = { version = ">= 1.1.3" source = "github.com/hashicorp/happycloud" } }}
Once your template contains those required_plugins
, run
packer init
to install all missing plugin
binaries.
Given the above example, Packer will try to look for a GitHub
repository owned by user or organization hashicorp
named
packer-plugin-myawesomecloud
and packer-plugin-happycloud
.
Note: packer init
tries to install plugins matching the version constraints required by the template.
Running packer init
multiple times on the same template will result in no changes if all matching plugins
have already been installed. If you want to update a plugin or force re-installation, you may use the
--update
or --force
arguments.
Packer plugins install
Plugin installation via packer plugins install
works similar to that of the packer init
command, but
no required_plugins
block are required.
packer plugins install github.com/hashicorp/vagrant
You can only install one plugin per invocation of the command. If you need to install
a specific version of a plugin, you can specify a version to install as an optional
argument to the command line.
e.g.: packer plugins install "github.com/hashicorp/vagrant" "v1.0.1"
The command will install the plugin in the PACKER_CONFIG_DIR
set, or its
default location, which depends on the OS/environment, as documented in
Configuring Packer.
Using packer plugins install to install a local copy of a binary
If the plugin you want to install cannot be installed remotely, you can use the
--path
argument for packer plugins install
in order to use the provided
plugin binary as source.
Example:
$ ls -l packer-plugin-happycloud-rwxrwxr-x 1 root root 44745210 Jan 01 1979 packer-plugin-happycloud$ PACKER_PLUGIN_PATH=/root/plugins packer plugins install --path ./packer-plugin-happycloud "github.com/hashicorp/happycloud"Successfully installed plugin github.com/hashicorp/happycloud from /root/packer-plugin-happycloud to /root/plugins/github.com/hashicorp/happycloud/packer-plugin-happycloud_v1.2.8-dev_x5.0_linux_amd64
Note: the version does not need to be specified, Packer will automatically
determine which version to install based on the plugin's describe
output.