<commit_before>---
page_title: "Writing Custom Terraform Providers"
title: "Writing Custom Terraform Providers"
list_image_url: "/images/blog/terraform/small.png"
post_image_url: "/images/blog/terraform/big.png"
tags: terraform
author: <NAME>
---

Custom providers in Terraform let you use Terraform to build and
manage new infrastructure components. These custom providers can be written
for public components (such as a new SaaS provider) or private
components (such as a private cloud). In this blog post, we'll show you
how easy it is to write a complete custom provider.

With the release of [Terraform 0.2](/blog/terraform-0-2.html), we made
writing custom providers incredibly easy by introducing a framework that
eliminates almost all the boilerplate of writing Terraform providers.

Using this new framework, we wrote a complete
[Google Compute provider](http://www.terraform.io/docs/providers/google/index.html)
in less than 8 hours of coding time. In this blog post, we'll write a dummy
provider that doesn't talk to a real system, but shows you how easy it is
to implement a custom provider in Terraform.

READMORE

## Project Setup

Terraform plugins are [Go](http://golang.org) binaries, so we'll need
a development environment for Go. Make sure you have Go properly installed,
then create a folder to work in somewhere. Open a terminal to this directory.

For the remainder of this post, we'll assume you have basic Go knowledge.
You don't need be an expert at Go. By completing the
[Tour of Go](http://tour.golang.org/), you'll be proficient enough
in Go to write a Terraform plugin.

If at any time during the post you want to see a more realistic example
of a provider, we recommend keeping the source for the
[built-in providers](https://github.com/hashicorp/terraform/tree/master/builtin/providers)
open in a tab. A good starting point there is the Heroku provider.

## The Provider Schema

To start, create a file `provider.go`. In this file, write the following
contents. This will setup the base boilerplate we need to get going.
We'll cover details about what everything is doing below the
code.

<pre class="prettyprint">
package main

import (
	"github.com/hashicorp/terraform/helper/schema"
)

func Provider() *schema.Provider {
	return &schema.Provider{
		ResourcesMap: map[string]*schema.Resource{},
	}
}
</pre>

The `helper/schema` library within the Terraform project is the framework
we'll use throughout this process. In the file above, we've simply defined
an empty provider.

The `*schema.Provider` type is the basic structure that describes a
provider: the configuration keys it takes, the resources it supports,
a callback to configure, etc. We haven't yet defined any of these components
except for an empty mapping of resources, but we'll get there.

## Building the Empty Plugin

Next, create a file `main.go` with the following contents:

<pre class="prettyprint">
package main

import (
	"github.com/hashicorp/terraform/plugin"
)

func main() {
	plugin.Serve(Provider())
}
</pre>

This sets up our `main` function so that this is a valid Go binary.
The contents of the main function uses the `plugin` library within
Terraform. This library knows how to serve a plugin and handles all the
details of communicating with the main Terraform application.

Build it using `go`:

<pre class="prettyprint">
$ go build -o terraform-provider-dummy
...
</pre><commit_msg>Update custom provider example in blog post<commit_after>---
page_title: "Writing Custom Terraform Providers"
title: "Writing Custom Terraform Providers"
list_image_url: "/images/blog/terraform/small.png"
post_image_url: "/images/blog/terraform/big.png"
tags: terraform
author: <NAME>
---

Custom providers in Terraform let you use Terraform to build and
manage new infrastructure components. These custom providers can be written
for public components (such as a new SaaS provider) or private
components (such as a private cloud). In this blog post, we'll show you
how easy it is to write a complete custom provider.

With the release of [Terraform 0.2](/blog/terraform-0-2.html), we made
writing custom providers incredibly easy by introducing a framework that
eliminates almost all the boilerplate of writing Terraform providers.

Using this new framework, we wrote a complete
[Google Compute provider](http://www.terraform.io/docs/providers/google/index.html)
in less than 8 hours of coding time. In this blog post, we'll write a dummy
provider that doesn't talk to a real system, but shows you how easy it is
to implement a custom provider in Terraform.

READMORE

## Project Setup

Terraform plugins are [Go](http://golang.org) binaries, so we'll need
a development environment for Go. Make sure you have Go properly installed,
then create a folder to work in somewhere. Open a terminal to this directory.

For the remainder of this post, we'll assume you have basic Go knowledge.
You don't need be an expert at Go. By completing the
[Tour of Go](http://tour.golang.org/), you'll be proficient enough
in Go to write a Terraform plugin.

If at any time during the post you want to see a more realistic example
of a provider, we recommend keeping the source for the
[built-in providers](https://github.com/hashicorp/terraform/tree/master/builtin/providers)
open in a tab. A good starting point there is the Heroku provider.

## The Provider Schema

To start, create a file `provider.go`. In this file, write the following
contents. This will setup the base boilerplate we need to get going.
We'll cover details about what everything is doing below the
code.

<pre class="prettyprint">
package main

import (
	"github.com/hashicorp/terraform/helper/schema"
)

func Provider() *schema.Provider {
	return &schema.Provider{
		ResourcesMap: map[string]*schema.Resource{},
	}
}
</pre>

The `helper/schema` library within the Terraform project is the framework
we'll use throughout this process. In the file above, we've simply defined
an empty provider.

The `*schema.Provider` type is the basic structure that describes a
provider: the configuration keys it takes, the resources it supports,
a callback to configure, etc. We haven't yet defined any of these components
except for an empty mapping of resources, but we'll get there.

## Building the Empty Plugin

Next, create a file `main.go` with the following contents:

<pre class="prettyprint">
package main

import (
	"github.com/hashicorp/terraform/plugin"
)

func main() {
	plugin.Serve(&plugin.ServeOpts{
		ProviderFunc: func() terraform.ResourceProvider {
			return Provider()
		},
	})
}
</pre>

This sets up our `main` function so that this is a valid Go binary.
The contents of the main function uses the `plugin` library within
Terraform. This library knows how to serve a plugin and handles all the
details of communicating with the main Terraform application.

Build it using `go`:

<pre class="prettyprint">
$ go build -o terraform-provider-dummy
...
</pre>
{'fraction_non_alphanumeric': 0.07496749963888488, 'fraction_numerical': 0.001444460494005489, 'mean_word_length': 4.56144578313253, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 17, 'https://': 2, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5935453', 'n_tokens_mistral': 1951, 'n_tokens_neox': 1887, 'n_words': 942}