github.com/mmcquillan/packer@v1.1.1-0.20171009221028-c85cf0483a5d/website/source/docs/extending/plugins.html.md (about)

     1  ---
     2  description: |
     3      Packer Plugins allow new functionality to be added to Packer without modifying
     4      the core source code. Packer plugins are able to add new builders,
     5      provisioners, hooks, and more.
     6  layout: docs
     7  page_title: 'Plugins - Extending'
     8  sidebar_current: 'docs-extending-plugins'
     9  ---
    10  
    11  # Plugins
    12  
    13  Packer Plugins allow new functionality to be added to Packer without modifying
    14  the core source code. Packer plugins are able to add new builders,
    15  provisioners, hooks, and more. In fact, much of Packer itself is implemented by
    16  writing plugins that are simply distributed with Packer. For example, all the
    17  builders, provisioners, and more that ship with Packer are implemented
    18  as Plugins that are simply hardcoded to load with Packer.
    19  
    20  This page will cover how to install and use plugins. If you're interested in
    21  developing plugins, the documentation for that is available the [developing
    22  plugins](/docs/extending/plugins.html) page.
    23  
    24  Because Packer is so young, there is no official listing of available Packer
    25  plugins. Plugins are best found via Google. Typically, searching "packer plugin
    26  *x*" will find what you're looking for if it exists. As Packer gets older, an
    27  official plugin directory is planned.
    28  
    29  ## How Plugins Work
    30  
    31  Packer plugins are completely separate, standalone applications that the core of
    32  Packer starts and communicates with.
    33  
    34  These plugin applications aren't meant to be run manually. Instead, Packer core
    35  executes these plugin applications in a certain way and communicates with them.
    36  For example, the VMware builder is actually a standalone binary named
    37  `packer-builder-vmware`. The next time you run a Packer build, look at your
    38  process list and you should see a handful of `packer-` prefixed applications
    39  running.
    40  
    41  ## Installing Plugins
    42  
    43  The easiest way to install a plugin is to name it correctly, then place it in
    44  the proper directory. To name a plugin correctly, make sure the binary is named
    45  `packer-TYPE-NAME`. For example, `packer-builder-amazon-ebs` for a "builder"
    46  type plugin named "amazon-ebs". Valid types for plugins are down this page more.
    47  
    48  Once the plugin is named properly, Packer automatically discovers plugins in the
    49  following directories in the given order. If a conflicting plugin is found
    50  later, it will take precedence over one found earlier.
    51  
    52  1.  The directory where `packer` is, or the executable directory.
    53  
    54  2.  `~/.packer.d/plugins` on Unix systems or `%APPDATA%/packer.d/plugins`
    55      on Windows.
    56  
    57  3.  The current working directory.
    58  
    59  The valid types for plugins are:
    60  
    61  -   `builder` - Plugins responsible for building images for a specific platform.
    62  
    63  -   `post-processor` - A post-processor responsible for taking an artifact from
    64      a builder and turning it into something else.
    65  
    66  -   `provisioner` - A provisioner to install software on images created by
    67      a builder.
    68  
    69  ## Developing Plugins
    70  
    71  This page will document how you can develop your own Packer plugins. Prior to
    72  reading this, it is assumed that you're comfortable with Packer and also know
    73  the [basics of how Plugins work](/docs/extending/plugins.html), from a user
    74  standpoint.
    75  
    76  Packer plugins must be written in [Go](https://golang.org/), so it is also
    77  assumed that you're familiar with the language. This page will not be a Go
    78  language tutorial. Thankfully, if you are familiar with Go, the Go toolchain
    79  provides many conveniences to help to develop Packer plugins.
    80  
    81  ~> **Warning!** This is an advanced topic. If you're new to Packer, we
    82  recommend getting a bit more comfortable before you dive into writing plugins.
    83  
    84  ### Plugin System Architecture
    85  
    86  Packer has a fairly unique plugin architecture. Instead of loading plugins
    87  directly into a running application, Packer runs each plugin as a *separate
    88  application*. Inter-process communication and RPC is then used to communicate
    89  between the many running Packer processes. Packer core itself is responsible for
    90  orchestrating the processes and handles cleanup.
    91  
    92  The beauty of this is that your plugin can have any dependencies it wants.
    93  Dependencies don't need to line up with what Packer core or any other plugin
    94  uses, because they're completely isolated into the process space of the plugin
    95  itself.
    96  
    97  And, thanks to Go's
    98  [interfaces](https://golang.org/doc/effective_go.html#interfaces_and_types), it
    99  doesn't even look like inter-process communication is occurring. You just use
   100  the interfaces like normal, but in fact they're being executed in a remote
   101  process. Pretty cool.
   102  
   103  ### Plugin Development Basics
   104  
   105  Developing a plugin allows you to create additional functionality for Packer.
   106  All the various kinds of plugins have a corresponding interface. The plugin needs
   107  to implement this interface and expose it using the Packer plugin package
   108  (covered here shortly), and that's it!
   109  
   110  There are two packages that really matter that every plugin must use. Other than
   111  the following two packages, you're encouraged to use whatever packages you want.
   112  Because plugins are their own processes, there is no danger of colliding
   113  dependencies.
   114  
   115  -   `github.com/hashicorp/packer` - Contains all the interfaces that you have to
   116      implement for any given plugin.
   117  
   118  -   `github.com/hashicorp/packer/packer/plugin` - Contains the code to serve
   119      the plugin. This handles all the inter-process communication stuff.
   120  
   121  There are two steps involved in creating a plugin:
   122  
   123  1.  Implement the desired interface. For example, if you're building a builder
   124      plugin, implement the `packer.Builder` interface.
   125  
   126  2.  Serve the interface by calling the appropriate plugin serving method in your
   127      main method. In the case of a builder, this is `plugin.ServeBuilder`.
   128  
   129  A basic example is shown below. In this example, assume the `Builder` struct
   130  implements the `packer.Builder` interface:
   131  
   132  ``` go
   133  import (
   134    "github.com/hashicorp/packer/packer/plugin"
   135  )
   136  
   137  // Assume this implements packer.Builder
   138  type Builder struct{}
   139  
   140  func main() {
   141    plugin.ServeBuilder(new(Builder))
   142  }
   143  ```
   144  
   145  **That's it!** `plugin.ServeBuilder` handles all the nitty gritty of
   146  communicating with Packer core and serving your builder over RPC. It can't get
   147  much easier than that.
   148  
   149  Next, just build your plugin like a normal Go application, using `go build` or
   150  however you please. The resulting binary is the plugin that can be installed
   151  using standard installation procedures.
   152  
   153  The specifics of how to implement each type of interface are covered in the
   154  relevant subsections available in the navigation to the left.
   155  
   156  ~> **Lock your dependencies!** Unfortunately, Go's dependency management
   157  story is fairly sad. There are various unofficial methods out there for locking
   158  dependencies, and using one of them is highly recommended since the Packer
   159  codebase will continue to improve, potentially breaking APIs along the way until
   160  there is a stable release. By locking your dependencies, your plugins will
   161  continue to work with the version of Packer you lock to.
   162  
   163  ### Logging and Debugging
   164  
   165  Plugins can use the standard Go `log` package to log. Anything logged using this
   166  will be available in the Packer log files automatically. The Packer log is
   167  visible on stderr when the `PACKER_LOG` environmental is set.
   168  
   169  Packer will prefix any logs from plugins with the path to that plugin to make it
   170  identifiable where the logs come from. Some example logs are shown below:
   171  
   172  ``` text
   173  2013/06/10 21:44:43 Loading builder: custom
   174  2013/06/10 21:44:43 packer-builder-custom: 2013/06/10 21:44:43 Plugin minimum port: 10000
   175  2013/06/10 21:44:43 packer-builder-custom: 2013/06/10 21:44:43 Plugin maximum port: 25000
   176  2013/06/10 21:44:43 packer-builder-custom: 2013/06/10 21:44:43 Plugin address: :10000
   177  ```
   178  
   179  As you can see, the log messages from the custom builder plugin are prefixed
   180  with "packer-builder-custom". Log output is *extremely* helpful in debugging
   181  issues and you're encouraged to be as verbose as you need to be in order for the
   182  logs to be helpful.
   183  
   184  ### Plugin Development Tips
   185  
   186  Here are some tips for developing plugins, often answering common questions or
   187  concerns.
   188  
   189  #### Naming Conventions
   190  
   191  It is standard practice to name the resulting plugin application in the format
   192  of `packer-TYPE-NAME`. For example, if you're building a new builder for
   193  CustomCloud, it would be standard practice to name the resulting plugin
   194  `packer-builder-custom-cloud`. This naming convention helps users identify the
   195  purpose of a plugin.
   196  
   197  #### Testing Plugins
   198  
   199  While developing plugins, you can configure your Packer configuration to point
   200  directly to the compiled plugin in order to test it. For example, building the
   201  CustomCloud plugin, I may configure packer like so:
   202  
   203  ``` json
   204  {
   205    "builders": {
   206      "custom-cloud": "/an/absolute/path/to/packer-builder-custom-cloud"
   207    }
   208  }
   209  ```
   210  
   211  This would configure Packer to have the "custom-cloud" plugin, and execute the
   212  binary that I am building during development. This is extremely useful during
   213  development.
   214  
   215  #### Distributing Plugins
   216  
   217  It is recommended you use a tool like [goxc](https://github.com/laher/goxc) in
   218  order to cross-compile your plugin for every platform that Packer supports,
   219  since Go applications are platform-specific. goxc will allow you to build for
   220  every platform from your own computer.