2013-06-11 00:47:16 -04:00
|
|
|
---
|
2017-06-14 21:04:16 -04:00
|
|
|
description: |
|
2020-03-18 18:46:47 -04:00
|
|
|
Packer Plugins allow new functionality to be added to Packer without modifying
|
|
|
|
the core source code. Packer plugins are able to add new builders,
|
|
|
|
provisioners, hooks, and more.
|
2015-07-22 22:31:00 -04:00
|
|
|
layout: docs
|
2020-03-18 18:46:47 -04:00
|
|
|
page_title: Plugins - Extending
|
2020-04-02 19:39:47 -04:00
|
|
|
sidebar_title: Plugins
|
2017-03-25 18:13:52 -04:00
|
|
|
---
|
|
|
|
|
|
|
|
# Plugins
|
|
|
|
|
|
|
|
Packer Plugins allow new functionality to be added to Packer without modifying
|
2017-07-04 10:39:41 -04:00
|
|
|
the core source code. Packer plugins are able to add new builders,
|
2017-03-25 18:13:52 -04:00
|
|
|
provisioners, hooks, and more. In fact, much of Packer itself is implemented by
|
|
|
|
writing plugins that are simply distributed with Packer. For example, all the
|
2018-10-26 20:02:51 -04:00
|
|
|
builders, provisioners, and more that ship with Packer are implemented as
|
|
|
|
Plugins that are simply hardcoded to load with Packer.
|
2017-03-25 18:13:52 -04:00
|
|
|
|
2018-01-24 19:59:32 -05:00
|
|
|
This section will cover how to install and use plugins. If you're interested in
|
2018-10-26 20:02:51 -04:00
|
|
|
developing plugins, the documentation for that is available below, in the
|
|
|
|
[developing plugins](#developing-plugins) section.
|
2017-03-25 18:13:52 -04:00
|
|
|
|
2019-09-04 14:11:44 -04:00
|
|
|
The current official listing of available Packer plugins can be found
|
2020-03-31 17:40:07 -04:00
|
|
|
[here](/community-tools#third-party-plugins). This is an incomplete list,
|
2019-09-04 14:11:44 -04:00
|
|
|
and more plugins can be found by searching. Typically, searching "packer plugin
|
2020-03-18 18:46:47 -04:00
|
|
|
_x_" will find what you're looking for if it exists. We hope to create an
|
2019-09-04 14:11:44 -04:00
|
|
|
offical registry for third party plugins in the future.
|
2017-03-25 18:13:52 -04:00
|
|
|
|
|
|
|
## How Plugins Work
|
|
|
|
|
2018-10-26 20:02:51 -04:00
|
|
|
Packer plugins are completely separate, standalone applications that the core
|
|
|
|
of Packer starts and communicates with.
|
2017-03-25 18:13:52 -04:00
|
|
|
|
|
|
|
These plugin applications aren't meant to be run manually. Instead, Packer core
|
2018-01-24 19:59:32 -05:00
|
|
|
executes them as a sub-process, run as a sub-command (`packer plugin`) and
|
|
|
|
communicates with them. For example, the VMware builder is actually run as
|
|
|
|
`packer plugin packer-builder-vmware`. The next time you run a Packer build,
|
|
|
|
look at your process list and you should see a handful of `packer-` prefixed
|
|
|
|
applications running.
|
2017-03-25 18:13:52 -04:00
|
|
|
|
|
|
|
## Installing Plugins
|
|
|
|
|
|
|
|
The easiest way to install a plugin is to name it correctly, then place it in
|
|
|
|
the proper directory. To name a plugin correctly, make sure the binary is named
|
|
|
|
`packer-TYPE-NAME`. For example, `packer-builder-amazon-ebs` for a "builder"
|
2018-10-26 20:02:51 -04:00
|
|
|
type plugin named "amazon-ebs". Valid types for plugins are down this page
|
|
|
|
more.
|
2017-03-25 18:13:52 -04:00
|
|
|
|
2018-10-26 20:02:51 -04:00
|
|
|
Once the plugin is named properly, Packer automatically discovers plugins in
|
|
|
|
the following directories in the given order. If a conflicting plugin is found
|
2017-03-25 18:13:52 -04:00
|
|
|
later, it will take precedence over one found earlier.
|
|
|
|
|
|
|
|
1. The directory where `packer` is, or the executable directory.
|
|
|
|
|
2019-07-24 23:33:56 -04:00
|
|
|
2. The `$HOME/.packer.d/plugins` directory, if `$HOME` is defined (unix)
|
2017-03-25 18:13:52 -04:00
|
|
|
|
2019-01-04 08:10:30 -05:00
|
|
|
3. The `%APPDATA%/packer.d/plugins` if `%APPDATA%` is defined (windows)
|
|
|
|
|
2019-01-11 17:06:15 -05:00
|
|
|
4. The `%USERPROFILE%/packer.d/plugins` if `%USERPROFILE%` is defined
|
|
|
|
(windows)
|
2019-01-04 08:10:30 -05:00
|
|
|
|
2019-01-08 10:33:15 -05:00
|
|
|
5. The current working directory.
|
2017-03-25 18:13:52 -04:00
|
|
|
|
2020-03-18 18:46:47 -04:00
|
|
|
6. The directory defined in the env var `PACKER_PLUGIN_PATH`. There can be more
|
|
|
|
than one directory defined; for example, `~/custom-dir-1:~/custom-dir-2`.
|
|
|
|
Separate directories in the PATH string using a colon (`:`) on posix systems and
|
|
|
|
a semicolon (`;`) on windows systems. The above example path would be able to
|
|
|
|
find a provisioner named `packer-provisioner-foo` in either
|
|
|
|
`~/custom-dir-1/packer-provisioner-foo` or
|
|
|
|
`~/custom-dir-2/packer-provisioner-foo`.
|
2020-01-16 16:02:31 -05:00
|
|
|
|
2017-03-25 18:13:52 -04:00
|
|
|
The valid types for plugins are:
|
|
|
|
|
2020-03-18 18:46:47 -04:00
|
|
|
- `builder` - Plugins responsible for building images for a specific
|
|
|
|
platform.
|
2017-03-25 18:13:52 -04:00
|
|
|
|
2020-03-18 18:46:47 -04:00
|
|
|
- `post-processor` - A post-processor responsible for taking an artifact from
|
|
|
|
a builder and turning it into something else.
|
2017-03-25 18:13:52 -04:00
|
|
|
|
2020-03-18 18:46:47 -04:00
|
|
|
- `provisioner` - A provisioner to install software on images created by a
|
|
|
|
builder.
|
2013-06-11 00:47:16 -04:00
|
|
|
|
2017-03-25 18:13:52 -04:00
|
|
|
## Developing Plugins
|
2013-06-11 00:47:16 -04:00
|
|
|
|
2015-07-22 22:31:00 -04:00
|
|
|
This page will document how you can develop your own Packer plugins. Prior to
|
|
|
|
reading this, it is assumed that you're comfortable with Packer and also know
|
2020-03-31 17:40:07 -04:00
|
|
|
the [basics of how Plugins work](/docs/extending/plugins), from a user
|
2015-07-22 22:31:00 -04:00
|
|
|
standpoint.
|
2013-06-11 00:47:16 -04:00
|
|
|
|
2016-01-14 15:31:19 -05:00
|
|
|
Packer plugins must be written in [Go](https://golang.org/), so it is also
|
2015-07-22 22:31:00 -04:00
|
|
|
assumed that you're familiar with the language. This page will not be a Go
|
|
|
|
language tutorial. Thankfully, if you are familiar with Go, the Go toolchain
|
2017-05-09 14:37:49 -04:00
|
|
|
provides many conveniences to help to develop Packer plugins.
|
2013-06-11 00:47:16 -04:00
|
|
|
|
2020-03-23 20:02:12 -04:00
|
|
|
~> **Warning!** This is an advanced topic. If you're new to Packer, we
|
2014-10-20 13:55:16 -04:00
|
|
|
recommend getting a bit more comfortable before you dive into writing plugins.
|
2013-06-11 00:47:16 -04:00
|
|
|
|
2017-03-25 18:13:52 -04:00
|
|
|
### Plugin System Architecture
|
2013-06-11 00:47:16 -04:00
|
|
|
|
|
|
|
Packer has a fairly unique plugin architecture. Instead of loading plugins
|
2020-03-18 18:46:47 -04:00
|
|
|
directly into a running application, Packer runs each plugin as a _separate
|
|
|
|
application_. Inter-process communication and RPC is then used to communicate
|
2018-10-26 20:02:51 -04:00
|
|
|
between the many running Packer processes. Packer core itself is responsible
|
|
|
|
for orchestrating the processes and handles cleanup.
|
2013-06-11 00:47:16 -04:00
|
|
|
|
|
|
|
The beauty of this is that your plugin can have any dependencies it wants.
|
|
|
|
Dependencies don't need to line up with what Packer core or any other plugin
|
2015-07-22 22:31:00 -04:00
|
|
|
uses, because they're completely isolated into the process space of the plugin
|
|
|
|
itself.
|
2013-06-11 00:47:16 -04:00
|
|
|
|
2015-07-22 22:31:00 -04:00
|
|
|
And, thanks to Go's
|
2016-01-14 15:31:19 -05:00
|
|
|
[interfaces](https://golang.org/doc/effective_go.html#interfaces_and_types), it
|
2015-07-22 22:31:00 -04:00
|
|
|
doesn't even look like inter-process communication is occurring. You just use
|
|
|
|
the interfaces like normal, but in fact they're being executed in a remote
|
|
|
|
process. Pretty cool.
|
2013-06-11 00:47:16 -04:00
|
|
|
|
2017-03-25 18:13:52 -04:00
|
|
|
### Plugin Development Basics
|
2013-06-11 00:47:16 -04:00
|
|
|
|
2017-05-09 14:37:49 -04:00
|
|
|
Developing a plugin allows you to create additional functionality for Packer.
|
2018-10-26 20:02:51 -04:00
|
|
|
All the various kinds of plugins have a corresponding interface. The plugin
|
|
|
|
needs to implement this interface and expose it using the Packer plugin package
|
2017-05-09 14:37:49 -04:00
|
|
|
(covered here shortly), and that's it!
|
2013-06-11 00:47:16 -04:00
|
|
|
|
2018-10-26 20:02:51 -04:00
|
|
|
There are two packages that really matter that every plugin must use. Other
|
|
|
|
than the following two packages, you're encouraged to use whatever packages you
|
|
|
|
want. Because plugins are their own processes, there is no danger of colliding
|
2015-07-22 22:31:00 -04:00
|
|
|
dependencies.
|
2013-06-11 00:47:16 -04:00
|
|
|
|
2020-03-18 18:46:47 -04:00
|
|
|
- `github.com/hashicorp/packer` - Contains all the interfaces that you have
|
|
|
|
to implement for any given plugin.
|
2013-06-11 00:47:16 -04:00
|
|
|
|
2020-03-18 18:46:47 -04:00
|
|
|
- `github.com/hashicorp/packer/packer/plugin` - Contains the code to serve
|
|
|
|
the plugin. This handles all the inter-process communication stuff.
|
2013-06-11 00:47:16 -04:00
|
|
|
|
|
|
|
There are two steps involved in creating a plugin:
|
|
|
|
|
2015-07-22 23:25:58 -04:00
|
|
|
1. Implement the desired interface. For example, if you're building a builder
|
|
|
|
plugin, implement the `packer.Builder` interface.
|
2013-06-11 00:47:16 -04:00
|
|
|
|
2018-10-26 20:02:51 -04:00
|
|
|
2. Serve the interface by calling the appropriate plugin serving method in
|
2019-07-24 23:46:37 -04:00
|
|
|
your main method.
|
2013-06-11 00:47:16 -04:00
|
|
|
|
|
|
|
A basic example is shown below. In this example, assume the `Builder` struct
|
|
|
|
implements the `packer.Builder` interface:
|
|
|
|
|
2020-03-18 18:46:47 -04:00
|
|
|
```go
|
2013-06-11 00:47:16 -04:00
|
|
|
import (
|
2017-04-04 16:39:01 -04:00
|
|
|
"github.com/hashicorp/packer/packer/plugin"
|
2013-06-11 00:47:16 -04:00
|
|
|
)
|
|
|
|
|
|
|
|
// Assume this implements packer.Builder
|
|
|
|
type Builder struct{}
|
|
|
|
|
|
|
|
func main() {
|
2019-07-24 23:46:37 -04:00
|
|
|
server, err := plugin.Server()
|
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
server.RegisterBuilder(new(Builder))
|
2019-09-04 14:11:44 -04:00
|
|
|
server.Serve()
|
2013-06-11 00:47:16 -04:00
|
|
|
}
|
2014-10-20 13:55:16 -04:00
|
|
|
```
|
2013-06-11 00:47:16 -04:00
|
|
|
|
2019-07-24 23:46:37 -04:00
|
|
|
**That's it!** `plugin.Server` handles all the nitty gritty of
|
2015-07-22 22:31:00 -04:00
|
|
|
communicating with Packer core and serving your builder over RPC. It can't get
|
|
|
|
much easier than that.
|
2013-06-11 00:47:16 -04:00
|
|
|
|
2015-07-22 22:31:00 -04:00
|
|
|
Next, just build your plugin like a normal Go application, using `go build` or
|
|
|
|
however you please. The resulting binary is the plugin that can be installed
|
|
|
|
using standard installation procedures.
|
2013-06-11 00:47:16 -04:00
|
|
|
|
2015-07-22 22:31:00 -04:00
|
|
|
The specifics of how to implement each type of interface are covered in the
|
|
|
|
relevant subsections available in the navigation to the left.
|
2013-06-11 00:47:16 -04:00
|
|
|
|
2020-03-23 20:02:12 -04:00
|
|
|
~> **Lock your dependencies!** Using `go mod` is highly recommended since
|
2018-01-24 19:59:32 -05:00
|
|
|
the Packer codebase will continue to improve, potentially breaking APIs along
|
|
|
|
the way until there is a stable release. By locking your dependencies, your
|
|
|
|
plugins will continue to work with the version of Packer you lock to.
|
2013-06-27 13:43:19 -04:00
|
|
|
|
2017-03-25 18:13:52 -04:00
|
|
|
### Logging and Debugging
|
2013-06-11 00:47:16 -04:00
|
|
|
|
2018-10-26 20:02:51 -04:00
|
|
|
Plugins can use the standard Go `log` package to log. Anything logged using
|
|
|
|
this will be available in the Packer log files automatically. The Packer log is
|
2015-07-22 22:31:00 -04:00
|
|
|
visible on stderr when the `PACKER_LOG` environmental is set.
|
2013-06-11 00:47:16 -04:00
|
|
|
|
2018-10-26 20:02:51 -04:00
|
|
|
Packer will prefix any logs from plugins with the path to that plugin to make
|
|
|
|
it identifiable where the logs come from. Some example logs are shown below:
|
2013-06-11 00:47:16 -04:00
|
|
|
|
2020-03-18 18:46:47 -04:00
|
|
|
```text
|
2017-07-04 10:39:41 -04:00
|
|
|
2013/06/10 21:44:43 Loading builder: custom
|
|
|
|
2013/06/10 21:44:43 packer-builder-custom: 2013/06/10 21:44:43 Plugin minimum port: 10000
|
|
|
|
2013/06/10 21:44:43 packer-builder-custom: 2013/06/10 21:44:43 Plugin maximum port: 25000
|
|
|
|
2013/06/10 21:44:43 packer-builder-custom: 2013/06/10 21:44:43 Plugin address: :10000
|
2013-06-11 00:47:16 -04:00
|
|
|
```
|
|
|
|
|
2017-07-04 10:41:40 -04:00
|
|
|
As you can see, the log messages from the custom builder plugin are prefixed
|
2020-03-18 18:46:47 -04:00
|
|
|
with "packer-builder-custom". Log output is _extremely_ helpful in debugging
|
2018-10-26 20:02:51 -04:00
|
|
|
issues and you're encouraged to be as verbose as you need to be in order for
|
|
|
|
the logs to be helpful.
|
2013-06-11 00:47:16 -04:00
|
|
|
|
2017-03-25 18:13:52 -04:00
|
|
|
### Plugin Development Tips
|
2013-06-11 00:47:16 -04:00
|
|
|
|
2015-07-22 22:31:00 -04:00
|
|
|
Here are some tips for developing plugins, often answering common questions or
|
|
|
|
concerns.
|
2013-06-11 00:47:16 -04:00
|
|
|
|
2017-03-25 18:13:52 -04:00
|
|
|
#### Naming Conventions
|
2013-06-20 17:30:02 -04:00
|
|
|
|
2015-07-22 22:31:00 -04:00
|
|
|
It is standard practice to name the resulting plugin application in the format
|
|
|
|
of `packer-TYPE-NAME`. For example, if you're building a new builder for
|
|
|
|
CustomCloud, it would be standard practice to name the resulting plugin
|
|
|
|
`packer-builder-custom-cloud`. This naming convention helps users identify the
|
|
|
|
purpose of a plugin.
|
2013-06-11 00:47:16 -04:00
|
|
|
|
2017-03-25 18:13:52 -04:00
|
|
|
#### Testing Plugins
|
2013-06-20 17:30:02 -04:00
|
|
|
|
2015-07-22 22:31:00 -04:00
|
|
|
While developing plugins, you can configure your Packer configuration to point
|
|
|
|
directly to the compiled plugin in order to test it. For example, building the
|
|
|
|
CustomCloud plugin, I may configure packer like so:
|
2013-06-11 00:47:16 -04:00
|
|
|
|
2020-03-12 10:05:08 -04:00
|
|
|
```json
|
2013-06-11 00:47:16 -04:00
|
|
|
{
|
|
|
|
"builders": {
|
|
|
|
"custom-cloud": "/an/absolute/path/to/packer-builder-custom-cloud"
|
|
|
|
}
|
|
|
|
}
|
2014-10-20 13:55:16 -04:00
|
|
|
```
|
2013-06-11 00:47:16 -04:00
|
|
|
|
2015-07-22 22:31:00 -04:00
|
|
|
This would configure Packer to have the "custom-cloud" plugin, and execute the
|
|
|
|
binary that I am building during development. This is extremely useful during
|
|
|
|
development.
|
2013-06-11 00:47:16 -04:00
|
|
|
|
2017-03-25 18:13:52 -04:00
|
|
|
#### Distributing Plugins
|
2013-06-20 17:30:02 -04:00
|
|
|
|
2015-07-22 22:31:00 -04:00
|
|
|
It is recommended you use a tool like [goxc](https://github.com/laher/goxc) in
|
|
|
|
order to cross-compile your plugin for every platform that Packer supports,
|
|
|
|
since Go applications are platform-specific. goxc will allow you to build for
|
|
|
|
every platform from your own computer.
|