» Terraform Plugin SDK

As of September 2019, Terraform provider developers importing the Go module github.com/hashicorp/terraform, known as Terraform Core, should switch to github.com/hashicorp/terraform-plugin-sdk, the Terraform Plugin SDK, instead.

» Why a separate module?

While the helper/* and other packages in Terraform Core has served us well, in order for provider development to evolve, the SDK needed to break out into its own repository. Terraform Core's versioning has been oriented towards practitioners. With the "unofficial" SDK existing in the core repository, the SDK becomes tied to Core releases and cannot follow semantic versioning. The new standalone SDK github.com/hashicorp/terraform-plugin-sdk follows sematic versioning starting with v1.0.0.

We will use the term "legacy Terraform plugin SDK" when referring to the version of Terraform Core imported and used by providers.

» What do providers need to do?

The first release of the standalone plugin SDK aims to keep nearly 100% backwards compatibility, aside from a handful of APIs, so only the imports within your provider need to be replaced.

The migration process can be automated with the migrator tool. This tool will check eligibility of a provider codebase, ensuring the use of Go modules and that the provider is upgrading from at least v0.12.7 of github.com/hashicorp/terraform. It will also identify if the handful of removed APIs are being used.

You can also migrate your provider manually by replacing references to github.com/hashicorp/terraform with github.com/hashicorp/terraform-plugin-sdk. We recommend using the official migrator tool as it has a number of checks that will make this process safer. Please also read the deprecation notices below.

» How do I migrate my provider to the standalone SDK?

» Using tf-sdk-migrator

» Step 0: Install the migrator tool

$ go install github.com/hashicorp/tf-sdk-migrator

The migrator binary is now available at $GOBIN/tf-sdk-migrator. Examples below assume you have added $GOBIN to your PATH.

» Step 1: Check eligibility for migration

$ cd /provider/source/directory/
$ tf-sdk-migrator check

If this command succeeds, proceed to Step 2.

Otherwise, the tool will output the steps you need to take to ensure the provider can be migrated. Please see https://github.com/hashicorp/tf-sdk-migrator for more information about the eligibility checks, and see the Deprecations section below for what to do if you are using deprecated packages or identifiers.

Projects that are on an old version of the legacy Terraform plugin SDK, particularly < v0.12, should first upgrade to v0.12.

» Step 2: Migrate

$ tf-sdk-migrator migrate

The migrate subcommand runs the check subcommand, and migration will not proceed if the eligibility check fails.

If migration succeeds, you will see something like the following:

$ tf-sdk-migrator migrate
Checking Go runtime version ...
Go version 1.12.9: OK.
Checking whether provider uses Go modules...
Go modules in use: OK.
Checking version of github.com/hashicorp/terraform SDK used in provider...
SDK version 0.12.7: OK.
Checking whether provider uses deprecated SDK packages or identifiers...
No imports of deprecated SDK packages or identifiers: OK.

All constraints satisfied. Provider can be migrated to the new SDK.

Rewriting provider go.mod file...
Rewriting SDK package imports...
Success! Provider is migrated to github.com/hashicorp/terraform-plugin-sdk v1.0.0.

Remember to vendor the dependencies if the project still uses vendoring.

$ go mod vendor

Congratulations! Your Terraform provider is migrated to the standalone SDK. You can now run your tests and commit the changed files.

» Manually

» Step 0: Check requirements

Below is a list of requirements. It is possible to migrate without meeting these requirements, but it may be much more difficult. It is therefore highly recommended to try to meet all of these, or meet as many as possible.

  • Go 1.12
    • go version should yield the current version in use
  • Dependencies managed via Go modules
    • go.mod and go.sum should be present in the root
  • github.com/hashicorp/terraform >=0.12.7
    • go.mod should contain a line which starts with github.com/hashicorp/terraform and version that is greater than or equal to 0.12.7

» Step 1: Check for deprecations

See the list of deprecations below and take actions to remove all occurrences of deprecated packages, functions or identifiers.

You may find a full list of SDK packages in tf-sdk-migrator source code. Any package which is not on the list is considered as deprecated in the context of SDK and/or doesn't classify as SDK.

You can use standard Go tooling, jq and grep to list all packages which are in use by your provider:

go list -json ./... | \
    jq -r .Imports[] | \
    grep '^github.com/hashicorp/terraform/'

You can use go-refs to list all identifiers of a given package which are in use.

» Step 2: Replace import paths

The simplest way to replace all import paths is to find all Go files using the standard Go tooling and jq, and sed for replacing the paths:

go list -json ./... | \
    jq -r '.Dir + "/" + .GoFiles[]' | \
    xargs -n1 sed -i 's;"github.com/hashicorp/terraform/;"github.com/hashicorp/terraform-plugin-sdk/;'

» Step 3: Go Modules

Tidy up dependencies after removing Terraform and adding standalone SDK:

go mod tidy

re-vendor dependencies, if you're vendoring

go mod vendor

and finally run your tests, review changes and commit.

» What if my provider is not eligible for migration?

Version 1.0.0 of the standalone plugin SDK is intended to differ as little as possible from the legacy plugin SDK. However, we have had to deprecate some packages and identifiers. Some of the rationale behind which packages made up SDK v1.0.0 can be seen from the analysis we performed.

» Deprecations

The following packages, functions, and identifiers have been deprecated as of v0.12.7 of the legacy SDK in Core, and have removed altogether in the standalone SDK.

  • config.NewRawConfig()/terraform.NewResourceConfig() were sometimes used in tandem for testing provider block configuration. The config package has been removed entirely from the SDK as well as terraform.NewResourceConfig, you should now use terraform.NewResourceConfigRaw(). See example

  • Passing along a user agent header to backend APIs has been done a few ways. The new standalone SDK tries to standardize the creation of a user agent header, as well as provide an accurate version of Terraform calling the provider.

    • terraform.VersionString() has been removed, it provided the version of terraform the dependency, which was not accurate. The version of terraform can now be accessed at runtime in a provider's ConfigureFunc. See example
    • httpclient.UserAgentString()/terraform.UserAgentString() have been removed. Please use httpclient.TerraformUserAgent() instead.
    • httpclient.New() has been removed. Please use github.com/hashicorp/go-cleanhttp.DefaultPooledClient() directly with a custom transport. This is how httpclient.New() was implemented in Core.
  • A small number of providers have used the flatmap package. Unfortunately it will not be a part of the standalone SDK. It is recommended to just move away from using that altogether, but as a quick solution, copy paste whatever is needed over and strip away the parts that are Terraform Core specific. This package was never intended to be used outside of Terraform Core.