2013-06-20 17:46:21 -04:00
|
|
|
---
|
2020-03-18 18:46:47 -04:00
|
|
|
description: >
|
|
|
|
Packer Provisioners are the components of Packer that install and configure
|
|
|
|
|
|
|
|
software into a running machine prior to turning that machine into an image.
|
|
|
|
An
|
|
|
|
|
|
|
|
example of a provisioner is the shell provisioner, which runs shell scripts
|
|
|
|
|
|
|
|
within the machines.
|
2015-07-22 22:31:00 -04:00
|
|
|
layout: docs
|
2020-03-18 18:46:47 -04:00
|
|
|
page_title: Custom Provisioners - Extending
|
2020-03-24 19:48:37 -04:00
|
|
|
sidebar_title: 'Custom Provisioners'
|
2020-03-18 18:46:47 -04:00
|
|
|
sidebar_current: docs-extending-custom-provisioners
|
2017-03-25 18:13:52 -04:00
|
|
|
---
|
2013-06-20 17:46:21 -04:00
|
|
|
|
2017-03-25 18:13:52 -04:00
|
|
|
# Custom Provisioners
|
2013-06-20 17:46:21 -04:00
|
|
|
|
2014-10-20 16:47:30 -04:00
|
|
|
Packer Provisioners are the components of Packer that install and configure
|
2015-07-22 22:31:00 -04:00
|
|
|
software into a running machine prior to turning that machine into an image. An
|
|
|
|
example of a provisioner is the [shell
|
2020-03-31 17:40:07 -04:00
|
|
|
provisioner](/docs/provisioners/shell), which runs shell scripts within
|
2018-10-26 20:02:51 -04:00
|
|
|
the machines.
|
2013-06-20 17:46:21 -04:00
|
|
|
|
2015-07-22 22:31:00 -04:00
|
|
|
Prior to reading this page, it is assumed you have read the page on [plugin
|
2020-03-31 17:40:07 -04:00
|
|
|
development basics](/docs/extending/plugins).
|
2013-06-20 17:46:21 -04:00
|
|
|
|
2015-07-22 22:31:00 -04:00
|
|
|
Provisioner plugins implement the `packer.Provisioner` interface and are served
|
|
|
|
using the `plugin.ServeProvisioner` function.
|
2013-06-20 17:46:21 -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-20 17:46:21 -04:00
|
|
|
|
|
|
|
## The Interface
|
|
|
|
|
|
|
|
The interface that must be implemented for a provisioner is the
|
2017-05-09 14:37:49 -04:00
|
|
|
`packer.Provisioner` interface. It is reproduced below for reference. The
|
2015-07-22 22:31:00 -04:00
|
|
|
actual interface in the source code contains some basic documentation as well
|
|
|
|
explaining what each method should do.
|
2013-06-24 12:39:20 -04:00
|
|
|
|
2020-03-18 18:46:47 -04:00
|
|
|
```go
|
2013-06-20 17:46:21 -04:00
|
|
|
type Provisioner interface {
|
2019-12-18 10:13:52 -05:00
|
|
|
ConfigSpec() hcldec.ObjectSpec
|
2015-07-22 22:31:00 -04:00
|
|
|
Prepare(...interface{}) error
|
2019-12-18 10:13:52 -05:00
|
|
|
Provision(context.Context, Ui, Communicator, map[string]interface{}) error
|
2013-06-20 17:46:21 -04:00
|
|
|
}
|
2014-10-20 13:55:16 -04:00
|
|
|
```
|
2013-06-20 17:46:21 -04:00
|
|
|
|
|
|
|
### The "Prepare" Method
|
|
|
|
|
2015-07-22 22:31:00 -04:00
|
|
|
The `Prepare` method for each provisioner is called prior to any runs with the
|
|
|
|
configuration that was given in the template. This is passed in as an array of
|
|
|
|
`interface{}` types, but is generally `map[string]interface{}`. The prepare
|
2013-06-20 17:46:21 -04:00
|
|
|
method is responsible for translating this configuration into an internal
|
|
|
|
structure, validating it, and returning any errors.
|
|
|
|
|
|
|
|
For multiple parameters, they should be merged together into the final
|
2018-10-26 20:02:51 -04:00
|
|
|
configuration, with later parameters overwriting any previous configuration.
|
|
|
|
The exact semantics of the merge are left to the builder author.
|
2013-06-20 17:46:21 -04:00
|
|
|
|
|
|
|
For decoding the `interface{}` into a meaningful structure, the
|
2015-07-22 22:31:00 -04:00
|
|
|
[mapstructure](https://github.com/mitchellh/mapstructure) library is
|
|
|
|
recommended. Mapstructure will take an `interface{}` and decode it into an
|
|
|
|
arbitrarily complex struct. If there are any errors, it generates very human
|
|
|
|
friendly errors that can be returned directly from the prepare method.
|
2013-06-20 17:46:21 -04:00
|
|
|
|
2018-10-26 20:02:51 -04:00
|
|
|
While it is not actively enforced, **no side effects** should occur from
|
|
|
|
running the `Prepare` method. Specifically, don't create files, don't launch
|
|
|
|
virtual machines, etc. Prepare's purpose is solely to configure the builder and
|
|
|
|
validate the configuration.
|
2013-06-20 17:46:21 -04:00
|
|
|
|
2015-07-22 22:31:00 -04:00
|
|
|
The `Prepare` method is called very early in the build process so that errors
|
|
|
|
may be displayed to the user before anything actually happens.
|
2013-06-20 17:46:21 -04:00
|
|
|
|
2019-12-20 15:05:01 -05:00
|
|
|
### The "ConfigSpec" Method
|
|
|
|
|
|
|
|
This method returns a hcldec.ObjectSpec, which is a spec necessary for using
|
|
|
|
HCL2 templates with Packer. For information on how to use and implement this
|
|
|
|
function, check our
|
|
|
|
[object spec docs](https://www.packer.io/guides/hcl/component-object-spec)
|
|
|
|
|
2013-06-20 17:46:21 -04:00
|
|
|
### The "Provision" Method
|
|
|
|
|
2015-07-22 22:31:00 -04:00
|
|
|
The `Provision` method is called when a machine is running and ready to be
|
|
|
|
provisioned. The provisioner should do its real work here.
|
2013-06-20 17:46:21 -04:00
|
|
|
|
2015-07-22 22:31:00 -04:00
|
|
|
The method takes two parameters: a `packer.Ui` and a `packer.Communicator`. The
|
|
|
|
UI can be used to communicate with the user what is going on. The communicator
|
|
|
|
is used to communicate with the running machine, and is guaranteed to be
|
|
|
|
connected at this point.
|
2013-06-20 17:46:21 -04:00
|
|
|
|
|
|
|
The provision method should not return until provisioning is complete.
|
|
|
|
|
2019-12-20 15:05:01 -05:00
|
|
|
The map[string]interface{} provides users with build-specific information,
|
|
|
|
like host and IP, provided by the `build` template engine. Provisioners may use
|
|
|
|
this information however they please, or not use it.
|
|
|
|
|
2013-06-20 17:46:21 -04:00
|
|
|
## Using the Communicator
|
|
|
|
|
2015-07-22 22:31:00 -04:00
|
|
|
The `packer.Communicator` parameter and interface is used to communicate with
|
|
|
|
running machine. The machine may be local (in a virtual machine or container of
|
|
|
|
some sort) or it may be remote (in a cloud). The communicator interface
|
|
|
|
abstracts this away so that communication is the same overall.
|
2013-06-20 17:46:21 -04:00
|
|
|
|
2015-07-22 22:31:00 -04:00
|
|
|
The documentation around the [code
|
2017-04-04 16:39:01 -04:00
|
|
|
itself](https://github.com/hashicorp/packer/blob/master/packer/communicator.go)
|
2015-07-22 22:31:00 -04:00
|
|
|
is really great as an overview of how to use the interface. You should begin by
|
|
|
|
reading this. Once you have read it, you can see some example usage below:
|
2013-06-20 17:46:21 -04:00
|
|
|
|
2020-03-18 18:46:47 -04:00
|
|
|
```go
|
2013-06-20 17:46:21 -04:00
|
|
|
// Build the remote command.
|
|
|
|
var cmd packer.RemoteCmd
|
|
|
|
cmd.Command = "echo foo"
|
|
|
|
|
|
|
|
// We care about stdout, so lets collect that into a buffer. Since
|
|
|
|
// we don't set stderr, that will just be discarded.
|
|
|
|
var stdout bytes.Buffer
|
|
|
|
cmd.Stdout = &stdout
|
|
|
|
|
|
|
|
// Start the command
|
|
|
|
if err := comm.Start(&cmd); err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Wait for it to complete
|
|
|
|
cmd.Wait()
|
|
|
|
|
|
|
|
// Read the stdout!
|
|
|
|
fmt.Printf("Command output: %s", stdout.String())
|
2014-10-20 13:55:16 -04:00
|
|
|
```
|