A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from https://developer.hashicorp.com/terraform/plugin/framework/migrating/mux below:

Migration using a mux server | Terraform

You can install the terraform-plugin-mux Go module to help you migrate to the plugin framework over two or more release cycles. The module allows you to multiplex, also called mux, data from providers built on SDKv2 and the plugin framework with your provider server. Each underlying provider implementation serves different managed resources and data sources. Refer to the Combining and Translating documentation for more details about implementing the terraform-plugin-mux module in your provider.

Use terraform-plugin-mux when:

When possible, we recommend migrating directly to the framework in a single release cycle without temporarily implementing terraform-plugin-mux in your provider.

Complete the following steps to mux your provider server:

  1. Introduce a Go type implementing the framework's provider.Provider interface. Refer to the provider definition section of the migration guide for additional details.
  2. Implement the provider.Provider type's Schema and Configure methods so it is compatible with terraform-plugin-mux. The schema and configuration handling must exactly match between all underlying providers in the provider server. Refer to the provider schema section of the migration guide for additional details.
  3. Introduce a mux server using the terraform-plugin-mux module. Your provider's main() function will reference this code. The main() function is responsible for starting the provider server. Refer to the Mux Server Examples section for additional details.
  4. Introduce an acceptance test for the mux server implementation. Refer to the Example tests for additional details.
  5. Ensure github.com/hashicorp/terraform-plugin-mux is added to the provider Go module dependencies. For example, by running the go get github.com/hashicorp/terraform-plugin-mux@latest command.
  6. Migrate your provider to the framework. Refer to the Workflow - Migrating with mux section of this guide for additional details.
  7. Once the migration is complete, remove the mux configuration from your provider, as well as any remaining references to SDKv2 libraries.
  8. Verify that all of your tests continue to pass.
  9. Release a new version of your provider.

The following examples demonstrate how to implement the terraform-plugin-mux module in your provider for various scenarios.

Terraform 0.12 compatibility

If your provider maintains compatability with Terraform 0.12, implement the terraform-plugin-mux module with protocol version 5.

The following main.go example shows how to set up a mux server for a provider that uses protocol version 5 to maintain compatibility with Terraform 0.12 and later.

This example also shows how to use the debug flag to optionally run the provider in debug mode.

import (
    "context"
    "flag"
    "log"

    "github.com/hashicorp/terraform-plugin-framework/providerserver"
    "github.com/hashicorp/terraform-plugin-go/tfprotov5"
    "github.com/hashicorp/terraform-plugin-go/tfprotov5/tf5server"
    "github.com/hashicorp/terraform-plugin-mux/tf5muxserver"

    "example.com/terraform-provider-examplecloud/internal/provider"
)

func main() {
    ctx := context.Background()

    var debug bool

    flag.BoolVar(&debug, "debug", false, "set to true to run the provider with support for debuggers like delve")
    flag.Parse()

    providers := []func() tfprotov5.ProviderServer{
        providerserver.NewProtocol5(provider.New()), // Example terraform-plugin-framework provider
        provider.Provider().GRPCProvider, // Example terraform-plugin-sdk provider
    }

    muxServer, err := tf5muxserver.NewMuxServer(ctx, providers...)

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

    var serveOpts []tf5server.ServeOpt

    if debug {
        serveOpts = append(serveOpts, tf5server.WithManagedDebug())
    }

    err = tf5server.Serve(
        "registry.terraform.io/<namespace>/<provider_name>",
        muxServer.ProviderServer,
        serveOpts...,
    )

    if err != nil {
        log.Fatal(err)
    }
}
Terraform 1.X compatibility

You can set the mux server up to be incompatible with Terraform 0.12 through 1.1.6 so that you can enable protocol version 6 capabilities, such as nested attributes, in the framework provider. You should only introduce breaking changes to your provider in major version updates.

The following main.go example shows how to use a mux server to upgrade a provider based on terraform-plugin-sdk so that it uses protocol version 6 and supports features in the framework provider.

This example also shows how to use the debug flag to optionally run the provider in debug mode.

import (
    "context"
    "flag"
    "log"

    "github.com/hashicorp/terraform-plugin-framework/providerserver"
    "github.com/hashicorp/terraform-plugin-go/tfprotov6"
    "github.com/hashicorp/terraform-plugin-go/tfprotov6/tf6server"
    "github.com/hashicorp/terraform-plugin-mux/tf5to6server"
    "github.com/hashicorp/terraform-plugin-mux/tf6muxserver"

    "example.com/terraform-provider-examplecloud/internal/provider"
)

func main() {
    ctx := context.Background()

    var debug bool

    flag.BoolVar(&debug, "debug", false, "set to true to run the provider with support for debuggers like delve")
    flag.Parse()

    upgradedSdkServer, err := tf5to6server.UpgradeServer(
        ctx,
        provider.Provider().GRPCProvider, // Example terraform-plugin-sdk provider
    )

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

    providers := []func() tfprotov6.ProviderServer{
        providerserver.NewProtocol6(provider.New()()), // Example terraform-plugin-framework provider
        func() tfprotov6.ProviderServer {
            return upgradedSdkServer,
        },
    }

    muxServer, err := tf6muxserver.NewMuxServer(ctx, providers...)

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

    var serveOpts []tf6server.ServeOpt

    if debug {
        serveOpts = append(serveOpts, tf6server.WithManagedDebug())
    }

    err = tf6server.Serve(
        "registry.terraform.io/<namespace>/<provider_name>",
        muxServer.ProviderServer,
        serveOpts...,
    )

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

The following examples demonstrate adding tests to verify that the mux server configuration works correctly during migration.

Protocol version 5

The following acceptance test example would be included in the same Go package that defines the provider code to verify the mux server setup using protocol version 5:

import (
    "context"
    "testing"

    "github.com/hashicorp/terraform-plugin-go/tfprotov5"
    "github.com/hashicorp/terraform-plugin-mux/tf5muxserver"
    "github.com/hashicorp/terraform-plugin-testing/helper/resource"
)

func TestMuxServer(t *testing.T) {
    resource.Test(t, resource.TestCase{
        ProtoV5ProviderFactories: map[string]func() (tfprotov5.ProviderServer, error) {
            "examplecloud": func() (tfprotov5.ProviderServer, error) {
                ctx := context.Background()
                providers := []func() tfprotov5.ProviderServer{
                    providerserver.NewProtocol5(New()), // Example terraform-plugin-framework provider
                    Provider().GRPCProvider, // Example terraform-plugin-sdk provider
                }

                muxServer, err := tf5muxserver.NewMuxServer(ctx, providers...)

                if err != nil {
                    return nil, err
                }

                return muxServer.ProviderServer(), nil
            },
        },
        Steps: []resource.TestStep{
            {
                Config: "... configuration including simplest data source or managed resource",
            },
        },
    })
}
Protocol Version 6

The following acceptance test example would be included in the same Go package that defines the provider code to verify the mux server setup:

import (
    "context"
    "testing"

    "github.com/hashicorp/terraform-plugin-go/tfprotov6"
    "github.com/hashicorp/terraform-plugin-mux/tf5to6server"
    "github.com/hashicorp/terraform-plugin-mux/tf6muxserver"
    "github.com/hashicorp/terraform-plugin-testing/helper/resource"
)

func TestMuxServer(t *testing.T) {
    resource.Test(t, resource.TestCase{
        ProtoV6ProviderFactories: map[string]func() (tfprotov6.ProviderServer, error) {
            "examplecloud": func() (tfprotov6.ProviderServer, error) {
                ctx := context.Background()

                upgradedSdkServer, err := tf5to6server.UpgradeServer(
                    ctx,
                    Provider().GRPCProvider, // Example terraform-plugin-sdk provider
                )

                if err != nil {
                    return nil, err
                }

                providers := []func() tfprotov6.ProviderServer{
                    providerserver.NewProtocol6(New()), // Example terraform-plugin-framework provider
                    func() tfprotov6.ProviderServer {
                        return upgradedSdkServer
                    },
                }

                muxServer, err := tf6muxserver.NewMuxServer(ctx, providers...)

                if err != nil {
                    return nil, err
                }

                return muxServer.ProviderServer(), nil
            },
        },
        Steps: []resource.TestStep{
            {
                Config: "... configuration including simplest data source or managed resource",
            },
        },
    })
}

Use the following guidance to help you troubleshoot if the module returns an error.

PreparedConfig response from multiple servers

Muxed provider servers may receive a new error, such as:

Error: Plugin error

  with provider["registry.terraform.io/example/examplecloud"],
  on <empty> line 0:
  (source code not available)

The plugin returned an unexpected error from
plugin.(*GRPCProvider).ValidateProviderConfig: rpc error: code = Unknown desc
= got different PrepareProviderConfig PreparedConfig response from multiple
servers, not sure which to use

If the terraform-plugin-sdk based provider was using Default or DefaultFunc, you must remove the usage of Default and DefaultFunc in that provider implementation. Transfer the logic into the provider ConfigureFunc or ConfigureContextFunc, similar to how it must be implemented in a terraform-plugin-framework based provider.


RetroSearch is an open source project built by @garambo | Open a GitHub Issue

Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo

HTML: 3.2 | Encoding: UTF-8 | Version: 0.7.4