github.com/raghuse92/packer@v1.3.2/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 section will cover how to install and use plugins. If you're interested in 21 developing plugins, the documentation for that is available below, in the [developing 22 plugins](#developing-plugins) section. 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 them as a sub-process, run as a sub-command (`packer plugin`) and 36 communicates with them. For example, the VMware builder is actually run as 37 `packer plugin packer-builder-vmware`. The next time you run a Packer build, 38 look at your process list and you should see a handful of `packer-` prefixed 39 applications 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.RegisterBuilder`. 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.RegisterBuilder(new(Builder)) 142 } 143 ``` 144 145 **That's it!** `plugin.RegisterBuilder` 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!** Using `govendor` is highly recommended since 157 the Packer codebase will continue to improve, potentially breaking APIs along 158 the way until there is a stable release. By locking your dependencies, your 159 plugins will continue to work with the version of Packer you lock to. 160 161 ### Logging and Debugging 162 163 Plugins can use the standard Go `log` package to log. Anything logged using this 164 will be available in the Packer log files automatically. The Packer log is 165 visible on stderr when the `PACKER_LOG` environmental is set. 166 167 Packer will prefix any logs from plugins with the path to that plugin to make it 168 identifiable where the logs come from. Some example logs are shown below: 169 170 ``` text 171 2013/06/10 21:44:43 Loading builder: custom 172 2013/06/10 21:44:43 packer-builder-custom: 2013/06/10 21:44:43 Plugin minimum port: 10000 173 2013/06/10 21:44:43 packer-builder-custom: 2013/06/10 21:44:43 Plugin maximum port: 25000 174 2013/06/10 21:44:43 packer-builder-custom: 2013/06/10 21:44:43 Plugin address: :10000 175 ``` 176 177 As you can see, the log messages from the custom builder plugin are prefixed 178 with "packer-builder-custom". Log output is *extremely* helpful in debugging 179 issues and you're encouraged to be as verbose as you need to be in order for the 180 logs to be helpful. 181 182 ### Plugin Development Tips 183 184 Here are some tips for developing plugins, often answering common questions or 185 concerns. 186 187 #### Naming Conventions 188 189 It is standard practice to name the resulting plugin application in the format 190 of `packer-TYPE-NAME`. For example, if you're building a new builder for 191 CustomCloud, it would be standard practice to name the resulting plugin 192 `packer-builder-custom-cloud`. This naming convention helps users identify the 193 purpose of a plugin. 194 195 #### Testing Plugins 196 197 While developing plugins, you can configure your Packer configuration to point 198 directly to the compiled plugin in order to test it. For example, building the 199 CustomCloud plugin, I may configure packer like so: 200 201 ``` json 202 { 203 "builders": { 204 "custom-cloud": "/an/absolute/path/to/packer-builder-custom-cloud" 205 } 206 } 207 ``` 208 209 This would configure Packer to have the "custom-cloud" plugin, and execute the 210 binary that I am building during development. This is extremely useful during 211 development. 212 213 #### Distributing Plugins 214 215 It is recommended you use a tool like [goxc](https://github.com/laher/goxc) in 216 order to cross-compile your plugin for every platform that Packer supports, 217 since Go applications are platform-specific. goxc will allow you to build for 218 every platform from your own computer.