Installing Plugins
Packer plugins are separate, standalone applications that perform tasks during each build.
You do not need to install the builder, provisioner, or post-processor components that ship with the Packer binary. Packer automatically knows how to find and launch these built-in plugins.
This page explains how to install custom external plugins. Refer to External Plugins for a list of available plugins and their documentation.
Depending on the template type you're using (HCL2 or legascy 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 usef 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.
Finally, you can manually install any plugin. This is mostly useful if you're in an environment with restricted internet access, or if you're installing non-final versions of plugins.
Refer to the Installation Guides section of this page for information about each, including usage examples.
The remainder of this document will serve as documentation on how Packer interacts with plugins. We encourage you to read this to get familiar with this process, as it will help you troubleshoot your builds if you encounter problems with that.
Source Addresses
A plugin's source address is its global identifier. It also tells Packer where to download it.
Source addresses consist of three parts delimited by slashes (/
), as
follows:
<HOSTNAME>/<NAMESPACE>/<TYPE>
Hostname: The hostname of the location/service that distributes the plugin. Currently, the only valid "hostname" is github.com, but we plan to eventually support plugins downloaded from other domains.
Namespace: An organizational namespace within the specified host. This often is the organization that publishes 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 myawesomecloud
plugin could belong to the
hashicorp
namespace on github.com
, so its source
could be
github.com/hashicorp/myawesomecloud
,
Note: the actual repository that myawesomecloud comes from must always have
the name format github.com/hashicorp/packer-plugin-myawesomecloud
, but the
required_plugins
block omits the redundant packer-plugin-
repository prefix
for brevity.
The source address with all three components given explicitly is called the plugin's fully-qualified address. You will see fully-qualified address in various outputs, like error messages.
Plugin Loading 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:
This logic however is ignored when plugins are defined in required_plugins
blocks;
instead, for every plugin required in this way, Packer will only consider them if they're
installed in Packer's plugin directory, under a directory hierarchy that matches the
source, with the plugin name respecting a convention.
For example, if we install the github.com/hashicorp/amazon
plugin in version 1.2.8 through
either packer init
or packer plugins install
, this will yield the following (in a
Linux x86_64 environment):
Both the plugin's binary, and the related SHA256SUM file must be placed alongside
each other for Packer to consider them for a required_plugins
constraint.
Installation Guides
Note: Only multi-component plugin binaries -- plugins named
packer-plugin-*, like the packer-plugin-amazon
-- are expected to work with
Packer init. The legacy builder
, post-processor
and provisioner
plugin
types will continue to be detected but Packer cannot install them automatically.
If a plugin you use has not been upgraded to use the multi-component plugin
architecture, contact your maintainer to request an upgrade.
Create a required_plugins block
- 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:
- Run
packer init
from your project directory (the directory containing your Packer templates) to install all missing plugin binaries. Given the above example, Packer will try to look for a GitHub repository owned by user or organizationazr
namedpacker-plugin-myawesomecloud
andpacker-plugin-happycloud
.
Names and Addresses
Each plugin has two identifiers:
- A
source
address, which is necessary when requiring a plugin not bundled with the Packer binary. - A unique local name, which is used everywhere else in a Packer configuration.
Local Names
Local names allow you to access the components of a plugin and must be unique per configuration.
This is best explained using an example. In the above required_plugins
block,
we declared the local name "myawesomecloud" for the plugin azr/myawesomecloud
.
If the "myawesomecloud" plugin contains both an "ebs" builder and an "import"
post-processor, then the builder will be accessed in a source block by using:
similarly, the import post-processor would be accessed by declaring the post-processor block:
If we change the required_plugins block to use a different local name "foo":
Then we'd instead access that builder using the source: