github.com/raghuse92/packer@v1.3.2/website/source/docs/extending/custom-provisioners.html.md (about) 1 --- 2 description: | 3 Packer Provisioners are the components of Packer that install and configure 4 software into a running machine prior to turning that machine into an image. 5 An example of a provisioner is the shell provisioner, which runs shell scripts 6 within the machines. 7 layout: docs 8 page_title: 'Custom Provisioners - Extending' 9 sidebar_current: 'docs-extending-custom-provisioners' 10 --- 11 12 # Custom Provisioners 13 14 Packer Provisioners are the components of Packer that install and configure 15 software into a running machine prior to turning that machine into an image. An 16 example of a provisioner is the [shell 17 provisioner](/docs/provisioners/shell.html), which runs shell scripts within the 18 machines. 19 20 Prior to reading this page, it is assumed you have read the page on [plugin 21 development basics](/docs/extending/plugins.html). 22 23 Provisioner plugins implement the `packer.Provisioner` interface and are served 24 using the `plugin.ServeProvisioner` function. 25 26 ~> **Warning!** This is an advanced topic. If you're new to Packer, we 27 recommend getting a bit more comfortable before you dive into writing plugins. 28 29 ## The Interface 30 31 The interface that must be implemented for a provisioner is the 32 `packer.Provisioner` interface. It is reproduced below for reference. The 33 actual interface in the source code contains some basic documentation as well 34 explaining what each method should do. 35 36 ``` go 37 type Provisioner interface { 38 Prepare(...interface{}) error 39 Provision(Ui, Communicator) error 40 } 41 ``` 42 43 ### The "Prepare" Method 44 45 The `Prepare` method for each provisioner is called prior to any runs with the 46 configuration that was given in the template. This is passed in as an array of 47 `interface{}` types, but is generally `map[string]interface{}`. The prepare 48 method is responsible for translating this configuration into an internal 49 structure, validating it, and returning any errors. 50 51 For multiple parameters, they should be merged together into the final 52 configuration, with later parameters overwriting any previous configuration. The 53 exact semantics of the merge are left to the builder author. 54 55 For decoding the `interface{}` into a meaningful structure, the 56 [mapstructure](https://github.com/mitchellh/mapstructure) library is 57 recommended. Mapstructure will take an `interface{}` and decode it into an 58 arbitrarily complex struct. If there are any errors, it generates very human 59 friendly errors that can be returned directly from the prepare method. 60 61 While it is not actively enforced, **no side effects** should occur from running 62 the `Prepare` method. Specifically, don't create files, don't launch virtual 63 machines, etc. Prepare's purpose is solely to configure the builder and validate 64 the configuration. 65 66 The `Prepare` method is called very early in the build process so that errors 67 may be displayed to the user before anything actually happens. 68 69 ### The "Provision" Method 70 71 The `Provision` method is called when a machine is running and ready to be 72 provisioned. The provisioner should do its real work here. 73 74 The method takes two parameters: a `packer.Ui` and a `packer.Communicator`. The 75 UI can be used to communicate with the user what is going on. The communicator 76 is used to communicate with the running machine, and is guaranteed to be 77 connected at this point. 78 79 The provision method should not return until provisioning is complete. 80 81 ## Using the Communicator 82 83 The `packer.Communicator` parameter and interface is used to communicate with 84 running machine. The machine may be local (in a virtual machine or container of 85 some sort) or it may be remote (in a cloud). The communicator interface 86 abstracts this away so that communication is the same overall. 87 88 The documentation around the [code 89 itself](https://github.com/hashicorp/packer/blob/master/packer/communicator.go) 90 is really great as an overview of how to use the interface. You should begin by 91 reading this. Once you have read it, you can see some example usage below: 92 93 ``` go 94 // Build the remote command. 95 var cmd packer.RemoteCmd 96 cmd.Command = "echo foo" 97 98 // We care about stdout, so lets collect that into a buffer. Since 99 // we don't set stderr, that will just be discarded. 100 var stdout bytes.Buffer 101 cmd.Stdout = &stdout 102 103 // Start the command 104 if err := comm.Start(&cmd); err != nil { 105 panic(err) 106 } 107 108 // Wait for it to complete 109 cmd.Wait() 110 111 // Read the stdout! 112 fmt.Printf("Command output: %s", stdout.String()) 113 ```