tfmux

package module
v0.4.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 7, 2021 License: MPL-2.0 Imports: 6 Imported by: 0

README

PkgGoDev

terraform-plugin-mux

terraform-plugin-mux provides a method for combining Terraform providers built in multiple different SDKs and frameworks to be combined into a single logical provider for Terraform to work with. It is designed to allow provider developers to implement resources and data sources at the level of abstraction that is most suitable for that specific resource or data source, and to allow provider developers to upgrade between SDKs or frameworks on a resource-by-resource basis instead of all at once.

Status

terraform-plugin-mux is a Go module versioned using semantic versioning.

The module is currently on a v0 major version, indicating our lack of confidence in the stability of its exported API. Developers depending on it should do so with an explicit understanding that the API may change and shift until we hit v1.0.0, as we learn more about the needs and expectations of developers working with the module.

We are confident in the correctness of the code and it is safe to build on so long as the developer understands that the API may change in backwards incompatible ways and they are expected to be tracking these changes.

Compatibility

Providers built on terraform-plugin-mux will only be usable with Terraform v0.12.0 and later. Developing providers for versions of Terraform below 0.12.0 is unsupported by the Terraform Plugin SDK team.

Providers built on the Terraform Plugin SDK must be using version 2.2.0 of the Plugin SDK or higher to be able to be used with terraform-plugin-mux.

Getting Started

terraform-plugin-mux exposes a minimal interface:

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

	// the ProviderServer from SDKv2
	sdkv2 := sdkv2provider.Provider().GRPCProvider

	// the terraform-plugin-go provider
	tpg := protoprovider.Provider

	factory, err := tfmux.NewSchemaServerFactory(ctx, sdkv2, tpg)
	if err != nil {
		log.Println(err.Error())
		os.Exit(1)
	}

	tf5server.Serve("registry.terraform.io/myorg/myprovider", factory.Server)
}

Each server needs a function that returns a tfprotov5.ProviderServer. Those get passed into a NewSchemaServerFactory function, which returns a factory capable of standing up Terraform provider servers. Passing that factory into the tf5server.Serve function starts the server and lets Terraform connect to it.

Testing

The Terraform Plugin SDK's helper/resource package can be used to test any provider that implements the tfprotov5.ProviderServer interface, which includes muxed providers created using tfmux.NewSchemaServerFactory.

You may wish to test a terraform-plugin-go provider's resources by supplying only that provider, and not the muxed provider, to the test framework: please see the example in https://github.com/hashicorp/terraform-plugin-go#testing in this case.

Otherwise, you should initialise a muxed provider in your testing code (conventionally in provider_test.go), and set this as the value of ProtoV5ProviderFactories in each TestCase. For example:

var testAccProtoV5ProviderFactories = map[string]func() (tfprotov5.ProviderServer, error){}

func init() {
  testAccProtoV5ProviderFactories["myprovider"] = func() (tfprotov5.ProviderServer, error) {
    ctx := context.Background()
    
    // the ProviderServer from SDKv2
    sdkv2 := sdkv2provider.Provider().GRPCProvider

    // the terraform-plugin-go provider
    tpg := protoprovider.Provider

    factory, err := tfmux.NewSchemaServerFactory(ctx, sdkv2, tpg)
    if err != nil {
      return nil, err
    }
    return factory.Server(), nil
  }
}

Here each TestCase in which you want to use the muxed provider should include ProtoV5ProviderFactories: testAccProtoV5ProviderFactories. Note that the test framework will return an error if you attempt to register the same provider using both ProviderFactories and ProtoV5ProviderFactories.

Documentation

Documentation is a work in progress. The GoDoc for packages, types, functions, and methods should have complete information, but we're working to add a section to terraform.io with more information about the module, its common uses, and patterns developers may wish to take advantage of.

Please bear with us as we work to get this information published, and please open issues with requests for the kind of documentation you would find useful.

Contributing

Please see .github/CONTRIBUTING.md.

License

This module is licensed under the Mozilla Public License v2.0.

Documentation

Overview

Package tfmux provides a multiplexer that allows joining multiple Terraform provider servers into a single gRPC server.

This allows providers to use any framework or SDK built on github.com/hashicorp/terraform-plugin-go to build resources for their provider, and to join all the resources into a single logical provider even though they're implemented in different SDKs or frameworks.

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type SchemaServer

type SchemaServer struct {
	// contains filtered or unexported fields
}

SchemaServer is a gRPC server implementation that stands in front of other gRPC servers, routing requests to them as if they were a single server. It should always be instantiated by calling SchemaServerFactory.Server().

func (SchemaServer) ApplyResourceChange

ApplyResourceChange calls the ApplyResourceChange method, passing `req`, on the provider that returned the resource specified by req.TypeName in its schema.

func (SchemaServer) ConfigureProvider

ConfigureProvider calls each provider's ConfigureProvider method, one at a time, passing `req`. Any Diagnostic with severity error will abort the process and return immediately; non-Error severity Diagnostics will be combined and returned.

func (SchemaServer) GetProviderSchema

GetProviderSchema merges the schemas returned by the tfprotov5.ProviderServers associated with SchemaServer into a single schema. Resources and data sources must be returned from only one server. Provider and ProviderMeta schemas must be identical between all servers.

func (SchemaServer) ImportResourceState

ImportResourceState calls the ImportResourceState method, passing `req`, on the provider that returned the resource specified by req.TypeName in its schema.

func (SchemaServer) PlanResourceChange

PlanResourceChange calls the PlanResourceChange method, passing `req`, on the provider that returned the resource specified by req.TypeName in its schema.

func (SchemaServer) PrepareProviderConfig

PrepareProviderConfig calls the PrepareProviderConfig method on each server in order, passing `req`. Only one may respond with a non-nil PreparedConfig or a non-empty Diagnostics.

func (SchemaServer) ReadDataSource

ReadDataSource calls the ReadDataSource method, passing `req`, on the provider that returned the data source specified by req.TypeName in its schema.

func (SchemaServer) ReadResource

ReadResource calls the ReadResource method, passing `req`, on the provider that returned the resource specified by req.TypeName in its schema.

func (SchemaServer) StopProvider

StopProvider calls the StopProvider function for each provider associated with the SchemaServer, one at a time. All Error fields will be joined together and returned, but will not prevent the rest of the providers' StopProvider methods from being called.

func (SchemaServer) UpgradeResourceState

UpgradeResourceState calls the UpgradeResourceState method, passing `req`, on the provider that returned the resource specified by req.TypeName in its schema.

func (SchemaServer) ValidateDataSourceConfig

ValidateDataSourceConfig calls the ValidateDataSourceConfig method, passing `req`, on the provider that returned the data source specified by req.TypeName in its schema.

func (SchemaServer) ValidateResourceTypeConfig

ValidateResourceTypeConfig calls the ValidateResourceTypeConfig method, passing `req`, on the provider that returned the resource specified by req.TypeName in its schema.

type SchemaServerFactory

type SchemaServerFactory struct {
	// contains filtered or unexported fields
}

SchemaServerFactory is a generator for SchemaServers, which are Terraform gRPC servers that route requests to different gRPC provider implementations based on which gRPC provider implementation supports the resource the request is for.

SchemaServerFactory should always be instantiated by NewSchemaServerFactory.

func NewSchemaServerFactory

func NewSchemaServerFactory(ctx context.Context, servers ...func() tfprotov5.ProviderServer) (SchemaServerFactory, error)

NewSchemaServerFactory returns a SchemaServerFactory that will route gRPC requests between the tfprotov5.ProviderServers specified. Each function specified is called, and the tfprotov5.ProviderServer has its GetProviderSchema method called. The schemas are used to determine which server handles each request, with requests for resources and data sources directed to the server that specified that data source or resource in its schema. Data sources and resources can only be specified in the schema of one ProviderServer.

Example (V2protocol)
ctx := context.Background()

// the ProviderServer from SDKv2
// usually this is the Provider function
var sdkv2 func() tfprotov5.ProviderServer

// the ProviderServer from the new protocol package
var protocolServer func() tfprotov5.ProviderServer

// requests will be routed to whichever server advertises support for
// them in the GetSchema response. Only one server may advertise
// support for any given resource, data source, or the provider or
// provider_meta schemas. An error will be returned if more than one
// server claims support.
_, err := NewSchemaServerFactory(ctx, sdkv2, protocolServer)
if err != nil {
	log.Println(err.Error())
	os.Exit(1)
}

// use the result when instantiating the terraform-plugin-sdk.plugin.Serve
/*
	plugin.Serve(&plugin.ServeOpts{
		GRPCProviderFunc: plugin.GRPCProviderFunc(factory),
	})
*/
*/
Output:

func (SchemaServerFactory) Server

func (s SchemaServerFactory) Server() SchemaServer

Server returns the SchemaServer that muxes between the tfprotov5.ProviderServers associated with the SchemaServerFactory.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL