---
page_title: 'Plugin Development - Framework: Provider Servers'
description: >-
  How to implement a provider server in the provider development framework.
  Provider servers are plugins that allow Terraform to interact with APIs.
---

# Provider Servers

Before a [provider](/terraform/plugin/framework/providers) can be used with Terraform, it must implement a [gRPC server](https://grpc.io) that supports Terraform-specific connection and handshake handling on startup. The server must then implement the [Terraform Plugin Protocol](/terraform/plugin/how-terraform-works#terraform-plugin-protocol).

The framework handles the majority of the server implementation details, however it is useful from a provider developer perspective to understand the provider server details at least at a high level.

## Protocol Version

The [Terraform Plugin Protocol](/terraform/plugin/how-terraform-works#terraform-plugin-protocol) defines the compatibility between Terraform CLI and the underlying provider. It is versioned, with newer versions implementing support for enhanced provider functionality but also requiring newer Terraform CLI versions. The framework implements two versions of the protocol.

* **Version 6**: The latest and recommended version, [protocol version 6](/terraform/plugin/how-terraform-works#protocol-version-6) implements enhanced provider functionality and requires Terraform CLI 1.0 or later. If [combining providers with terraform-plugin-sdk provider code](/terraform/plugin/mux/combining-protocol-version-6-providers), such as [migrating to the framework](/terraform/plugin/framework/migrating), then Terraform CLI 1.1 or later is required.
* **Version 5**: The prior version, [protocol version 5](/terraform/plugin/how-terraform-works#protocol-version-5) implements base provider functionality and requires Terraform CLI 0.12 or later.

Provider developers must choose either version 6 or version 5 and should consistently use that one version across implementations.

## Implementations

Terraform and provider developers have multiple ways to interact with the provider server implementation:

* **Production**: Terraform CLI expects a binary that starts the provider server on process startup and stops the provider when called.
* **Developer Overrides Testing**: The [CLI configuration file](/terraform/cli/config/config-file#development-overrides-for-provider-developers) maps provider addresses to locally built binaries, which then operate similar to production.
* **Acceptance Testing**: The [acceptance testing framework](/terraform/plugin/framework/acctests) maps provider names to functions that directly start the provider server and will automatically stop the provider between test steps.
* **Debugging**: Provider developers, typically via a code editor or debugger tool, manually start a provider server for [debugging](/terraform/plugin/framework/debugging) which Terraform CLI is then configured to use rather than a normal binary.

### Production and Developer Overrides

Go language programs implement startup logic via a `main` function. Conventionally, this is done in a `main.go` file at the root of a project. The `main` function must eventually call the framework functionality for managing provider servers in the [`providerserver` package](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-framework/providerserver).

An example `main.go` file for starting a protocol version 6 provider server:

```go
package main

import (
	"context"
	"flag"
	"log"

	"github.com/example-namespace/terraform-provider-example/internal/provider"
	"github.com/hashicorp/terraform-plugin-framework/providerserver"
)

var (
	// Example version string that can be overwritten by a release process
	version string = "dev"
)

func main() {
	opts := providerserver.ServeOpts{
		// TODO: Update this string with the published name of your provider.
		Address: "registry.terraform.io/example-namespace/example",
	}

	err := providerserver.Serve(context.Background(), provider.New(version), opts)

	if err != nil {
		log.Fatal(err.Error())
	}
}
```

To configure the provider server for protocol version 5, set the [`providerserver.ServeOpts` type `ProtocolVersion` field](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-framework/providerserver#ServeOpts.ProtocolVersion) to `5`:

```go
opts := providerserver.ServeOpts{
	// TODO: Update this string with the published name of your provider.
	Address:         "registry.terraform.io/example-namespace/example",
	ProtocolVersion: 5,
}
```

It is also possible to combine provider server implementations, such as migrating resources and data sources individually from [terraform-plugin-sdk/v2](/terraform/plugin/sdkv2) to the framework. This advanced use case would alter the `main.go` code further. Refer to the [Combining and Translating Providers](/terraform/plugin/mux) page for implementation details.

### Acceptance Testing

Refer to the [acceptance testing](/terraform/plugin/framework/acctests) page for implementation details.

### Debugging

Refer to the [debugging](/terraform/plugin/framework) page for implementation details.
