Terraform Advanced — Simple CRUD Provider

less than 1 minute read

Build a minimal Terraform provider that manages a fictional “server” resource.


Project Structure

terraform-provider-example/
├── main.go
├── go.mod
├── internal/
│   └── provider/
│       ├── provider.go
│       └── server_resource.go
└── examples/
    └── main.tf

Step 1 — Provider Definition

// internal/provider/provider.go
package provider

import (
    "context"
    "github.com/hashicorp/terraform-plugin-framework/datasource"
    "github.com/hashicorp/terraform-plugin-framework/provider"
    "github.com/hashicorp/terraform-plugin-framework/resource"
)

type ExampleProvider struct{}

func (p *ExampleProvider) Metadata(ctx context.Context, req provider.MetadataRequest, resp *provider.MetadataResponse) {
    resp.TypeName = "example"
}

func (p *ExampleProvider) Resources(ctx context.Context) []func() resource.Resource {
    return []func() resource.Resource{
        func() resource.Resource { return &ServerResource{} },
    }
}

func (p *ExampleProvider) DataSources(ctx context.Context) []func() datasource.DataSource {
    return nil
}

Step 2 — Build and Test Locally

# Build the provider
go build -o terraform-provider-example

# Tell Terraform to use local binary
cat > ~/.terraformrc <<EOF
provider_installation {
  dev_overrides {
    "example.com/myorg/example" = "/path/to/binary"
  }
  direct {}
}
EOF

# Test it
cd examples/
terraform plan

Step 3 — Use It

terraform {
  required_providers {
    example = {
      source = "example.com/myorg/example"
    }
  }
}

resource "example_server" "web" {
  name = "web-1"
  size = "large"
}

What’s Next?

Explore alternatives to building a full provider.

← Plugin Framework vs SDK Provider Alternatives →

Updated: