2014-08-27 06:31:53 +02:00
---
layout: "docs"
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
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-10-22 16:01:17 +02:00
~> **Advanced topic!** Plugin development is a highly advanced
2014-08-27 06:31:53 +02:00
topic in Terraform, and is not required knowledge for day-to-day usage.
If you don't plan on writing any plugins, we recommend not reading
this section of the documentation.
## 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
2016-08-16 21:21:33 +02:00
[Internal Docs ](/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.
## Installing a Plugin
To install a plugin, put the binary somewhere on your filesystem, then
configure Terraform to be able to find it. The configuration where plugins
are defined is `~/.terraformrc` for Unix-like systems and
`%APPDATA%/terraform.rc` for Windows.
An example that configures a new provider is shown below:
2017-04-05 17:29:27 +02:00
```hcl
2014-08-27 06:31:53 +02:00
providers {
2017-04-05 17:29:27 +02:00
privatecloud = "/path/to/privatecloud"
2014-08-27 06:31:53 +02:00
}
```
The key `privatecloud` is the _prefix_ of the resources for that provider.
For example, if there is `privatecloud_instance` resource, then the above
configuration would work. The value is the name of the executable. This
can be a full path. If it isn't a full path, the executable will be looked
up on the `PATH` .
## 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.
With the directory made, create a `main.go` file. This project will
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))
}
```
And that's basically it! You'll have to change the argument given to
`plugin.Serve` to be your actual plugin, but that is the only change
you'll have to make. The argument should be a structure implementing
one of the plugin interfaces (depending on what sort of plugin
you're creating).
2015-03-04 02:26:11 +01:00
Terraform plugins must follow a very specific naming convention of
`terraform-TYPE-NAME` . For example, `terraform-provider-aws` , which
tells Terraform that the plugin is a provider that can be referenced
as "aws".