Terraform: Provider plugin example

Created on 5 Oct 2015  ยท  6Comments  ยท  Source: hashicorp/terraform

Hi,

I'm trying to create a custom provider plugin and could do with a simple "Hello World" or maybe something a little more creative such as an HTTP GET example. I've created Chef Recipes before bit I'm new to Go. Anything that helps reduce the learning curve and gives me a kickstart would be much appreciated here. I've already looked through the existing providers in GitHub but they are all (at least at this stage) fairly complex. So something basic to ease me and new users into the process would be a great addition to the docs.

I also tried to follow the example at https://hashicorp.com/blog/terraform-custom-providers.html

However, I can't get passed the provider.go and the main.go to compile without it throwing the following error:

./main.go:8: cannot use Provider() (type *schema.Provider) as type *plugin.ServeOpts in argument to plugin.Serve

Thanks.

core question

Most helpful comment

fix is easy for the blog mistake.. just update your import as follows
import (
"github.com/hashicorp/terraform/plugin"
"github.com/hashicorp/terraform/terraform"
)

If you can update the blog, it will prevent people falling the same mistake

All 6 comments

The null, terraform, atlas and template providers are on the simpler side, with each providing only one resource.

Can you share the code from your main function, where you call plugin.Serve? From that error message it sounds like you're passing the provider directly into plugin.Serve, whereas it expects a ServeOpts structure containing a provider _factory_ function.

Here's the canonical main for a plugin:

func main() {
    plugin.Serve(&plugin.ServeOpts{
        ProviderFunc: func() terraform.ResourceProvider {
            return yourpluginpackage.Provider()
        },
    })
}

Hi, I was just following the Blog to get a simple provider example up and running. Here's my main file/function:

package main

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

func main() {
    plugin.Serve(Provider())
}

Here's the provider.go:

package main

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

func Provider() *schema.Provider {
    return &schema.Provider{
        ResourcesMap: map[string]*schema.Resource{
            "dummy_server": resourceServer(),
        },
    }
}

And the resource_server.go

package main

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

func resourceServer() *schema.Resource {
    return &schema.Resource{
        Create: resourceServerCreate,
        Read:   resourceServerRead,
        Update: resourceServerUpdate,
        Delete: resourceServerDelete,

        Schema: map[string]*schema.Schema{
            "address": &schema.Schema{
                Type:     schema.TypeString,
                Required: true,
            },
        },
    }
}

func resourceServerCreate(d *schema.ResourceData, m interface{}) error {
    return nil
}

func resourceServerRead(d *schema.ResourceData, m interface{}) error {
    return nil
}

func resourceServerUpdate(d *schema.ResourceData, m interface{}) error {
    return nil
}

func resourceServerDelete(d *schema.ResourceData, m interface{}) error {
    return nil
}

Are there any simple working examples for creating providers ?

Thanks

If you're looking to create a standalone plugin, outside of the main Terraform code, I have a fairly simple LXC plugin that might help as an example:

https://github.com/jtopjian/terraform-provider-lxc

Edit: Just came across this one, which is quite simple, though I have not actually tested it:

https://github.com/takebayashi/terraform-provider-dozens

We could probably do with either making an update to that blog or writing a canonical guide, but at this point the best way to learn is by looking at working examples in builtin/ and elsewhere on GitHub.

Thanks for swooping in with some good examples, @apparentlymart and @jtopjian!

fix is easy for the blog mistake.. just update your import as follows
import (
"github.com/hashicorp/terraform/plugin"
"github.com/hashicorp/terraform/terraform"
)

If you can update the blog, it will prevent people falling the same mistake

I'm going to lock this issue because it has been closed for _30 days_ โณ. This helps our maintainers find and focus on the active issues.

If you have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.

Was this page helpful?
0 / 5 - 0 ratings