2014-08-27 06:31:53 +02:00
---
2020-10-27 02:03:46 +01:00
layout: "extend"
2014-08-27 06:31:53 +02:00
page_title: "Plugin Basics"
sidebar_current: "docs-plugins-basics"
2014-10-22 05:21:56 +02:00
description: |-
This page documents the basics of how the plugin system in Terraform works, and how to setup a basic development environment for plugin development if you're writing a Terraform plugin.
2014-08-27 06:31:53 +02:00
---
# Plugin Basics
2017-08-21 22:44:27 +02:00
~> **Advanced topic!** Plugin development is a highly advanced
topic in Terraform, and is not required knowledge for day-to-day usage.
2018-10-03 01:53:29 +02:00
If you don't plan on writing any plugins, this section of the documentation is
2020-10-02 20:02:59 +02:00
not necessary to read. For general use of Terraform, please see
[Intro to Terraform ](/intro/index.html ) or the
[Terraform: Get Started ](https://learn.hashicorp.com/collections/terraform/aws-get-started?utm_source=WEBSITE&utm_medium=WEB_IO&utm_offer=ARTICLE_PAGE&utm_content=DOCS )
collection on HashiCorp Learn.
2017-08-21 22:44:27 +02:00
2014-08-27 06:31:53 +02:00
This page documents the basics of how the plugin system in Terraform
works, and how to setup a basic development environment for plugin development
if you're writing a Terraform plugin.
## How it Works
2016-08-16 21:21:33 +02:00
Terraform providers and provisioners are provided via plugins. Each plugin
exposes an implementation for a specific service, such as AWS, or provisioner,
such as bash. Plugins are executed as a separate process and communicate with
the main Terraform binary over an RPC interface.
2017-04-05 17:29:27 +02:00
More details are available in
2017-09-08 01:43:13 +02:00
_[Plugin Internals](/docs/internals/internal-plugins.html)_.
2014-08-27 06:31:53 +02:00
The code within the binaries must adhere to certain interfaces.
The network communication and RPC is handled automatically by higher-level
Terraform libraries. The exact interface to implement is documented
in its respective documentation section.
2018-10-03 01:53:29 +02:00
## Installing Plugins
2014-08-27 06:31:53 +02:00
2018-10-03 01:53:29 +02:00
The [provider plugins distributed by HashiCorp ](/docs/providers/index.html ) are
automatically installed by `terraform init` . Third-party plugins (both
providers and provisioners) can be manually installed into the user plugins
2018-11-21 01:54:18 +01:00
directory, located at `%APPDATA%\terraform.d\plugins` on Windows and
2018-10-03 01:53:29 +02:00
`~/.terraform.d/plugins` on other systems.
2014-08-27 06:31:53 +02:00
2018-10-03 01:53:29 +02:00
For more information, see:
- [Configuring Providers ](/docs/configuration/providers.html )
- [Configuring Providers: Third-party Plugins ](/docs/configuration/providers.html#third-party-plugins )
For developer-centric documentation, see:
- [How Terraform Works: Plugin Discovery ](/docs/extend/how-terraform-works.html#discovery )
2014-08-27 06:31:53 +02:00
## Developing a Plugin
Developing a plugin is simple. The only knowledge necessary to write
a plugin is basic command-line skills and basic knowledge of the
[Go programming language ](http://golang.org ).
2014-10-22 16:01:17 +02:00
-> **Note:** A common pitfall is not properly setting up a
2014-08-27 06:31:53 +02:00
< code > $GOPATH< / code > . This can lead to strange errors. You can read more about
2014-10-22 16:01:17 +02:00
this [here ](https://golang.org/doc/code.html ) to familiarize
2014-08-27 06:31:53 +02:00
yourself.
Create a new Go project somewhere in your `$GOPATH` . If you're a
GitHub user, we recommend creating the project in the directory
`$GOPATH/src/github.com/USERNAME/terraform-NAME` , where `USERNAME`
is your GitHub username and `NAME` is the name of the plugin you're
developing. This structure is what Go expects and simplifies things down
the road.
2017-09-08 01:43:13 +02:00
The `NAME` should either begin with `provider-` or `provisioner-` ,
depending on what kind of plugin it will be. The repository name will,
by default, be the name of the binary produced by `go install` for
your plugin package.
With the package directory made, create a `main.go` file. This project will
2014-08-27 06:31:53 +02:00
be a binary so the package is "main":
2017-04-05 17:29:27 +02:00
```golang
2014-08-27 06:31:53 +02:00
package main
import (
"github.com/hashicorp/terraform/plugin"
)
func main() {
plugin.Serve(new(MyPlugin))
}
```
2017-09-08 01:43:13 +02:00
The name `MyPlugin` is a placeholder for the struct type that represents
your plugin's implementation. This must implement either
`terraform.ResourceProvider` or `terraform.ResourceProvisioner` , depending
on the plugin type.
2014-08-27 06:31:53 +02:00
2017-09-08 01:43:13 +02:00
To test your plugin, the easiest method is to copy your `terraform` binary
to `$GOPATH/bin` and ensure that this copy is the one being used for testing.
`terraform init` will search for plugins within the same directory as the
`terraform` binary, and `$GOPATH/bin` is the directory into which `go install`
will place the plugin executable.