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.