Documentation

Overview

Package tfprotov5 provides the interfaces and types needed to build a Terraform provider server.

All Terraform provider servers should be built on these types, to take advantage of the ecosystem and tooling built around them.

These types are small wrappers around the Terraform protocol. It is assumed that developers using tfprotov5 are familiar with the protocol, its requirements, and its semantics. Developers not comfortable working with the raw protocol should use the github.com/hashicorp/terraform-plugin-sdk/v2 Go module instead, which offers a less verbose, safer way to develop a Terraform provider, albeit with less flexibility and power.

Provider developers should start by defining a type that implements the `ProviderServer` interface. A struct is recommended, as it will allow you to store the configuration information attached to your provider for use in requests, but any type is technically possible.

`ProviderServer` implementations will need to implement the composed interfaces, `ResourceServer` and `DataSourceServer`. It is recommended, but not required, to use an embedded `ResourceRouter` and `DataSourceRouter` in your `ProviderServer` to achieve this, which will let you handle requests for each resource and data source in a resource-specific or data source-specific function.

To serve the `ProviderServer` implementation as a gRPC server that Terraform can connect to, use the `tfprotov5/server.Serve` function.

Index

Constants

This section is empty.

Variables

View Source
var ErrUnknownDynamicValueType = errors.New("DynamicValue had no JSON or msgpack data set")

ErrUnknownDynamicValueType is returned when a DynamicValue has no MsgPack or JSON bytes set. This should never be returned during the normal operation of a provider, and indicates one of the following:

1. terraform-plugin-go is out of sync with the protocol and should be updated.

2. terrafrom-plugin-go has a bug.

3. The `DynamicValue` was generated or modified by something other than terraform-plugin-go and is no longer a valid value.

View Source
var ErrUnknownRawStateType = errors.New("RawState had no JSON or flatmap data set")

ErrUnknownRawStateType is returned when a RawState has no Flatmap or JSON bytes set. This should never be returned during the normal operation of a provider, and indicates one of the following:

1. terraform-plugin-go is out of sync with the protocol and should be updated.

2. terrafrom-plugin-go has a bug.

3. The `RawState` was generated or modified by something other than terraform-plugin-go and is no longer a valid value.

Functions

This section is empty.

Types

type ApplyResourceChangeRequest

type ApplyResourceChangeRequest struct {
	// TypeName is the type of resource Terraform wants to change.
	TypeName string

	// PriorState is the state of the resource before the changes are
	// applied, represented as a `DynamicValue`. See the documentation for
	// `DynamicValue` for information about safely accessing the state.
	//
	// The state is represented as a tftypes.Object, with each attribute
	// and nested block getting its own key and value.
	PriorState *DynamicValue

	// PlannedState is Terraform's plan for what the state should look like
	// after the changes are applied, represented as a `DynamicValue`. See
	// the documentation for `DynamicValue` for information about safely
	// accessing the state.
	//
	// This is the PlannedState returned during PlanResourceChange.
	//
	// The state is represented as a tftypes.Object, with each attribute
	// and nested block getting its own key and value.
	PlannedState *DynamicValue

	// Config is the configuration the user supplied for the resource. See
	// the documentation on `DynamicValue` for more information about
	// safely accessing the configuration.
	//
	// The configuration is represented as a tftypes.Object, with each
	// attribute and nested block getting its own key and value.
	//
	// This configuration may contain unknown values.
	Config *DynamicValue

	// PlannedPrivate is any provider-defined private state stored with the
	// resource. It is used for keeping state with the resource that is not
	// meant to be included when calculating diffs.
	PlannedPrivate []byte

	// ProviderMeta supplies the provider metadata configuration for the
	// module this resource is in. Module-specific provider metadata is an
	// advanced feature and usage of it should be coordinated with the
	// Terraform Core team by raising an issue at
	// https://github.com/hashicorp/terraform/issues/new/choose. See the
	// documentation on `DynamicValue` for information about safely
	// accessing the configuration.
	//
	// The configuration is represented as a tftypes.Object, with each
	// attribute and nested block getting its own key and value.
	//
	// This configuration will have known values for all fields.
	ProviderMeta *DynamicValue
}

ApplyResourceChangeRequest is the request Terraform sends when it needs to apply a planned set of changes to a resource.

type ApplyResourceChangeResponse

type ApplyResourceChangeResponse struct {
	// NewState is the provider's understanding of what the resource's
	// state is after changes are applied, represented as a `DynamicValue`.
	// See the documentation for `DynamicValue` for information about
	// safely creating the `DynamicValue`.
	//
	// Any attribute, whether computed or not, that has a known value in
	// the PlannedState in the ApplyResourceChangeRequest must be preserved
	// exactly as it was in NewState.
	//
	// Any attribute in the PlannedState in the ApplyResourceChangeRequest
	// that is unknown must take on a known value at this time. No unknown
	// values are allowed in the NewState.
	//
	// The state should be represented as a tftypes.Object, with each
	// attribute and nested block getting its own key and value.
	NewState *DynamicValue

	// Private should be set to any state that the provider would like sent
	// with requests for this resource. This state will be associated with
	// the resource, but will not be considered when calculating diffs.
	Private []byte

	// Diagnostics report errors or warnings related to applying changes to
	// the requested resource. Returning an empty slice indicates a
	// successful validation with no warnings or errors generated.
	Diagnostics []*Diagnostic

	// UnsafeToUseLegacyTypeSystem should only be set by
	// hashicorp/terraform-plugin-sdk. It modifies Terraform's behavior to
	// work with the legacy expectations of that SDK.
	//
	// Nobody else should use this. Ever. For any reason. Just don't do it.
	//
	// We have to expose it here for terraform-plugin-sdk to be muxable, or
	// we wouldn't even be including it in this type. Don't use it. It may
	// go away or change behavior on you with no warning. It is
	// explicitly unsupported and not part of our SemVer guarantees.
	//
	// Deprecated: Really, just don't use this, you don't need it.
	UnsafeToUseLegacyTypeSystem bool
}

ApplyResourceChangeResponse is the response from the provider about what the state of a resource is after planned changes have been applied.

type ConfigureProviderRequest

type ConfigureProviderRequest struct {
	// TerraformVersion is the version of Terraform executing the request.
	// This is supplied for logging, analytics, and User-Agent purposes
	// *only*. Providers should not try to gate provider behavior on
	// Terraform versions. It will make you sad. We can't stop you from
	// doing it, but we really highly recommend you do not do it.
	TerraformVersion string

	// Config is the configuration the user supplied for the provider. This
	// information should usually be persisted to the underlying type
	// that's implementing the ProviderServer interface, for use in later
	// RPC requests. See the documentation on `DynamicValue` for more
	// information about safely accessing the configuration.
	//
	// The configuration is represented as a tftypes.Object, with each
	// attribute and nested block getting its own key and value.
	//
	// The ConfigureProvider RPC call will be called twice; once when
	// generating a plan, once when applying the plan. When called during
	// plan, Config can contain unknown values if fields with unknown
	// values are interpolated into it. At apply time, all fields will have
	// known values. Values that are not set in the configuration will be
	// null.
	Config *DynamicValue
}

ConfigureProviderRequest represents a Terraform RPC request to supply the provider with information about what the user entered in the provider's configuration block.

type ConfigureProviderResponse

type ConfigureProviderResponse struct {
	// Diagnostics report errors or warnings related to the provider's
	// configuration. Returning an empty slice indicates success, with no
	// errors or warnings generated.
	Diagnostics []*Diagnostic
}

ConfigureProviderResponse represents a Terraform RPC response to the configuration block that Terraform supplied for the provider.

type DataSourceServer

type DataSourceServer interface {
	// ValidateDataSourceConfig is called when Terraform is checking that a
	// data source's configuration is valid. It is guaranteed to have types
	// conforming to your schema, but it is not guaranteed that all values
	// will be known. This is your opportunity to do custom or advanced
	// validation prior to a plan being generated.
	ValidateDataSourceConfig(context.Context, *ValidateDataSourceConfigRequest) (*ValidateDataSourceConfigResponse, error)

	// ReadDataSource is called when Terraform is refreshing a data
	// source's state.
	ReadDataSource(context.Context, *ReadDataSourceRequest) (*ReadDataSourceResponse, error)
}

DataSourceServer is an interface containing the methods a data source implementation needs to fill.

type Diagnostic

type Diagnostic struct {
	// Severity indicates how Terraform should handle the Diagnostic.
	Severity DiagnosticSeverity

	// Summary is a brief description of the problem, roughly
	// sentence-sized, and should provide a concise description of what
	// went wrong. For example, a Summary could be as simple as "Invalid
	// value.".
	Summary string

	// Detail is a lengthier, more complete description of the problem.
	// Detail should provide enough information that a user can resolve the
	// problem entirely. For example, a Detail could be "Values must be
	// alphanumeric and lowercase only."
	Detail string

	// Attribute indicates which field, specifically, has the problem. Not
	// setting this will indicate the entire resource; setting it will
	// indicate that the problem is with a certain field in the resource,
	// which helps users find the source of the problem.
	Attribute *tftypes.AttributePath
}

Diagnostic is used to convey information back the user running Terraform.

type DiagnosticSeverity

type DiagnosticSeverity int32

DiagnosticSeverity represents different classes of Diagnostic which affect how Terraform handles the Diagnostics.

const (
	// DiagnosticSeverityInvalid is used to indicate an invalid
	// `DiagnosticSeverity`. Provider developers should not use it.
	DiagnosticSeverityInvalid DiagnosticSeverity = 0

	// DiagnosticSeverityError is used to indicate that a `Diagnostic`
	// represents an error and should halt Terraform execution.
	DiagnosticSeverityError DiagnosticSeverity = 1

	// DiagnosticSeverityWarning is used to indicate that a `Diagnostic`
	// represents a warning and should not halt Terraform's execution, but
	// it should be surfaced to the user.
	DiagnosticSeverityWarning DiagnosticSeverity = 2
)

func (DiagnosticSeverity) String

func (d DiagnosticSeverity) String() string

type DynamicValue

type DynamicValue struct {
	MsgPack []byte
	JSON    []byte
}

DynamicValue represents a nested encoding value that came from the protocol. The only way providers should ever interact with it is by calling its `Unmarshal` method to retrive a `tftypes.Value`. Although the type system allows for other interactions, they are explicitly not supported, and will not be considered when evaluating for breaking changes. Treat this type as an opaque value, and *only* call its `Unmarshal` method.

func NewDynamicValue

func NewDynamicValue(t tftypes.Type, v tftypes.Value) (DynamicValue, error)

NewDynamicValue creates a DynamicValue from a tftypes.Value. You must specify the tftype.Type you want to send the value as, and it must be a type that is compatible with the Type of the Value. Usually it should just be the Type of the Value, but it can also be the DynamicPseudoType.

func (DynamicValue) Unmarshal

func (d DynamicValue) Unmarshal(typ tftypes.Type) (tftypes.Value, error)

Unmarshal returns a `tftypes.Value` that represents the information contained in the DynamicValue in an easy-to-interact-with way. It is the main purpose of the DynamicValue type, and is how provider developers should obtain config, state, and other values from the protocol.

Pass in the type you want the `Value` to be interpreted as. Terraform's type system encodes in a lossy manner, meaning the type information is not preserved losslessly when going over the wire. Sets, lists, and tuples all look the same, as do user-specified values when the provider has a DynamicPseudoType in its schema. Objects and maps all look the same, as well, as do DynamicPseudoType values sometimes. Fortunately, the provider should already know the type; it should be the type of the schema, or PseudoDynamicType if that's what's in the schema. `Unmarshal` will then parse the value as though it belongs to that type, if possible, and return a `tftypes.Value` with the appropriate information. If the data can't be interpreted as that type, an error will be returned saying so. In these cases, double check to make sure the schema is declaring the same type being passed into `Unmarshal`.

In the event an ErrUnknownDynamicValueType is returned, one of three things has happened:

1. terraform-plugin-go is out of date and out of sync with the protocol, and an issue should be opened on its repo to get it updated.

2. terraform-plugin-go has a bug somewhere, and an issue should be opened on its repo to get it fixed.

3. The provider or a dependency has modified the `DynamicValue` in an unsupported way, or has created one from scratch, and should treat it as opaque and not modify it, only calling `Unmarshal` on `DynamicValue`s received from RPC requests.

type GetProviderSchemaRequest

type GetProviderSchemaRequest struct{}

GetProviderSchemaRequest represents a Terraform RPC request for the provider's schemas.

type GetProviderSchemaResponse

type GetProviderSchemaResponse struct {
	// Provider defines the schema for the provider configuration, which
	// will be specified in the provider block of the user's configuration.
	Provider *Schema

	// ProviderMeta defines the schema for the provider's metadta, which
	// will be specified in the provider_meta blocks of the terraform block
	// for a module. This is an advanced feature and its usage should be
	// coordinated with the Terraform Core team by opening an issue at
	// https://github.com/hashicorp/terraform/issues/new/choose.
	ProviderMeta *Schema

	// ResourceSchemas is a map of resource names to the schema for the
	// configuration specified in the resource. The name should be a
	// resource name, and should be prefixed with your provider's shortname
	// and an underscore. It should match the first label after `resource`
	// in a user's configuration.
	ResourceSchemas map[string]*Schema

	// DataSourceSchemas is a map of data source names to the schema for
	// the configuration specified in the data source. The name should be a
	// data source name, and should be prefixed with your provider's
	// shortname and an underscore. It should match the first label after
	// `data` in a user's configuration.
	DataSourceSchemas map[string]*Schema

	// Diagnostics report errors or warnings related to returning the
	// provider's schemas. Returning an empty slice indicates success, with
	// no errors or warnings generated.
	Diagnostics []*Diagnostic
}

GetProviderSchemaResponse represents a Terraform RPC response containing the provider's schemas.

type ImportResourceStateRequest

type ImportResourceStateRequest struct {
	// TypeName is the type of resource Terraform wants to import.
	TypeName string

	// ID is the user-supplied identifying information about the resource
	// or resources. Providers decide and communicate to users the format
	// for the ID, and use it to determine what resource or resources to
	// import.
	ID string
}

ImportResourceStateRequest is the request Terraform sends when it wants a provider to import one or more resources specified by an ID.

type ImportResourceStateResponse

type ImportResourceStateResponse struct {
	// ImportedResources are the resources the provider found and was able
	// to import.
	ImportedResources []*ImportedResource

	// Diagnostics report errors or warnings related to importing the
	// requested resource or resources. Returning an empty slice indicates
	// a successful validation with no warnings or errors generated.
	Diagnostics []*Diagnostic
}

ImportResourceStateResponse is the response from the provider about the imported resources.

type ImportedResource

type ImportedResource struct {
	// TypeName is the type of resource that was imported.
	TypeName string

	// State is the provider's understanding of the imported resource's
	// state, represented as a `DynamicValue`. See the documentation for
	// `DynamicValue` for information about safely creating the
	// `DynamicValue`.
	//
	// The state should be represented as a tftypes.Object, with each
	// attribute and nested block getting its own key and value.
	State *DynamicValue

	// Private should be set to any state that the provider would like sent
	// with requests for this resource. This state will be associated with
	// the resource, but will not be considered when calculating diffs.
	Private []byte
}

ImportedResource represents a single resource that a provider has successfully imported into state.

type PlanResourceChangeRequest

type PlanResourceChangeRequest struct {
	// TypeName is the type of resource Terraform is generating a plan for.
	TypeName string

	// PriorState is the state of the resource before the plan is applied,
	// represented as a `DynamicValue`. See the documentation for
	// `DynamicValue` for information about safely accessing the state.
	//
	// The state is represented as a tftypes.Object, with each attribute
	// and nested block getting its own key and value.
	PriorState *DynamicValue

	// ProposedNewState is the state that Terraform is proposing for the
	// resource, with the changes in the configuration applied, represented
	// as a `DynamicValue`. See the documentation for `DynamicValue` for
	// information about safely accessing the state.
	//
	// The ProposedNewState merges any non-null values in the configuration
	// with any computed attributes in PriorState as a utility to help
	// providers avoid needing to implement such merging functionality
	// themselves.
	//
	// The state is represented as a tftypes.Object, with each attribute
	// and nested block getting its own key and value.
	//
	// The ProposedNewState will be null when planning a delete operation.
	ProposedNewState *DynamicValue

	// Config is the configuration the user supplied for the resource. See
	// the documentation on `DynamicValue` for more information about
	// safely accessing the configuration.
	//
	// The configuration is represented as a tftypes.Object, with each
	// attribute and nested block getting its own key and value.
	//
	// This configuration may contain unknown values if a user uses
	// interpolation or other functionality that would prevent Terraform
	// from knowing the value at request time.
	Config *DynamicValue

	// PriorPrivate is any provider-defined private state stored with the
	// resource. It is used for keeping state with the resource that is not
	// meant to be included when calculating diffs.
	PriorPrivate []byte

	// ProviderMeta supplies the provider metadata configuration for the
	// module this resource is in. Module-specific provider metadata is an
	// advanced feature and usage of it should be coordinated with the
	// Terraform Core team by raising an issue at
	// https://github.com/hashicorp/terraform/issues/new/choose. See the
	// documentation on `DynamicValue` for information about safely
	// accessing the configuration.
	//
	// The configuration is represented as a tftypes.Object, with each
	// attribute and nested block getting its own key and value.
	//
	// This configuration will have known values for all fields.
	ProviderMeta *DynamicValue
}

PlanResourceChangeRequest is the request Terraform sends when it is generating a plan for a resource and wants the provider's input on what the planned state should be.

type PlanResourceChangeResponse

type PlanResourceChangeResponse struct {
	// PlannedState is the provider's indication of what the state for the
	// resource should be after apply, represented as a `DynamicValue`. See
	// the documentation for `DynamicValue` for information about safely
	// creating the `DynamicValue`.
	//
	// This is usually derived from the ProposedNewState passed in the
	// PlanResourceChangeRequest, with default values substituted for any
	// null values and overriding any computed values that are expected to
	// change as a result of the apply operation. This may contain unknown
	// values if the value could change but its new value won't be known
	// until apply time.
	//
	// Any value that was non-null in the configuration must either
	// preserve the exact configuration value or return the corresponding
	// value from the prior state. The value from the prior state should be
	// returned when the configuration value is semantically equivalent to
	// the state value.
	//
	// Any value that is marked as computed in the schema and is null in
	// the configuration may be set by the provider to any value of the
	// expected type.
	//
	// PlanResourceChange will actually be called twice; once when
	// generating the plan for the user to approve, once during the apply.
	// During the apply, additional values from the configuration--upstream
	// values interpolated in that were computed at apply time--will be
	// populated. During this second call, any attribute that had a known
	// value in the first PlannedState must have an identical value in the
	// second PlannedState. Any unknown values may remain unknown or may
	// take on any value of the appropriate type. This means the values
	// returned in PlannedState should be deterministic and unknown values
	// should be used if a field's value may change depending on what value
	// ends up filling an unknown value in the config.
	//
	// The state should be represented as a tftypes.Object, with each
	// attribute and nested block getting its own key and value.
	PlannedState *DynamicValue

	// RequiresReplace is a list of tftypes.AttributePaths that require the
	// resource to be replaced. They should point to the specific field
	// that changed that requires the resource to be destroyed and
	// recreated.
	RequiresReplace []*tftypes.AttributePath

	// PlannedPrivate should be set to any state that the provider would
	// like sent with requests for this resource. This state will be
	// associated with the resource, but will not be considered when
	// calculating diffs.
	PlannedPrivate []byte

	// Diagnostics report errors or warnings related to determining the
	// planned state of the requested resource. Returning an empty slice
	// indicates a successful validation with no warnings or errors
	// generated.
	Diagnostics []*Diagnostic

	// UnsafeToUseLegacyTypeSystem should only be set by
	// hashicorp/terraform-plugin-sdk. It modifies Terraform's behavior to
	// work with the legacy expectations of that SDK.
	//
	// Nobody else should use this. Ever. For any reason. Just don't do it.
	//
	// We have to expose it here for terraform-plugin-sdk to be muxable, or
	// we wouldn't even be including it in this type. Don't use it. It may
	// go away or change behavior on you with no warning. It is
	// explicitly unsupported and not part of our SemVer guarantees.
	//
	// Deprecated: Really, just don't use this, you don't need it.
	UnsafeToUseLegacyTypeSystem bool
}

PlanResourceChangeResponse is the response from the provider about what the planned state for a given resource should be.

type PrepareProviderConfigRequest

type PrepareProviderConfigRequest struct {
	// Config is the configuration the user supplied for the provider. See
	// the documentation on `DynamicValue` for more information about
	// safely accessing the configuration.
	//
	// The configuration is represented as a tftypes.Object, with each
	// attribute and nested block getting its own key and value.
	//
	// The PrepareProviderConfig RPC call will be called twice; once when
	// generating a plan, once when applying the plan. When called during
	// plan, Config can contain unknown values if fields with unknown
	// values are interpolated into it. At apply time, all fields will have
	// known values. Values that are not set in the configuration will be
	// null.
	Config *DynamicValue
}

PrepareProviderConfigRequest represents a Terraform RPC request for the provider to modify the provider configuration in preparation for Terraform validating it.

type PrepareProviderConfigResponse

type PrepareProviderConfigResponse struct {
	// PreparedConfig should be set to the modified configuration. See the
	// documentation on `DynamicValue` for information about safely
	// creating the `DynamicValue`.
	//
	// This RPC call exists because early versions of the Terraform Plugin
	// SDK allowed providers to set defaults for provider configurations in
	// such a way that Terraform couldn't validate the provider config
	// without retrieving the default values first. As providers using
	// terraform-plugin-go directly and new frameworks built on top of it
	// have no such requirement, it is safe and recommended to simply set
	// PreparedConfig to the value of the PrepareProviderConfigRequest's
	// Config property, indicating that no changes are needed to the
	// configuration.
	//
	// The configuration should be represented as a tftypes.Object, with
	// each attribute and nested block getting its own key and value.
	//
	// TODO: should we provide an implementation that does that that
	// provider developers can just embed and not need to implement the
	// method themselves, then?
	PreparedConfig *DynamicValue

	// Diagnostics report errors or warnings related to preparing the
	// provider's configuration. Returning an empty slice indicates
	// success, with no errors or warnings generated.
	Diagnostics []*Diagnostic
}

PrepareProviderConfigResponse represents a Terraform RPC response containing a modified provider configuration that Terraform can now validate and use.

type ProviderServer

type ProviderServer interface {
	// GetProviderSchema is called when Terraform needs to know what the
	// provider's schema is, along with the schemas of all its resources
	// and data sources.
	GetProviderSchema(context.Context, *GetProviderSchemaRequest) (*GetProviderSchemaResponse, error)

	// PrepareProviderConfig is called to give a provider a chance to
	// modify the configuration the user specified before validation.
	PrepareProviderConfig(context.Context, *PrepareProviderConfigRequest) (*PrepareProviderConfigResponse, error)

	// ConfigureProvider is called to pass the user-specified provider
	// configuration to the provider.
	ConfigureProvider(context.Context, *ConfigureProviderRequest) (*ConfigureProviderResponse, error)

	// StopProvider is called when Terraform would like providers to shut
	// down as quickly as possible, and usually represents an interrupt.
	StopProvider(context.Context, *StopProviderRequest) (*StopProviderResponse, error)

	// ResourceServer is an interface encapsulating all the
	// resource-related RPC requests. ProviderServer implementations must
	// implement them, but they are a handy interface for defining what a
	// resource is to terraform-plugin-go, so they're their own interface
	// that is composed into ProviderServer.
	ResourceServer

	// DataSourceServer is an interface encapsulating all the data
	// source-related RPC requests. ProviderServer implementations must
	// implement them, but they are a handy interface for defining what a
	// data source is to terraform-plugin-go, so they're their own
	// interface that is composed into ProviderServer.
	DataSourceServer
}

ProviderServer is an interface that reflects that Terraform protocol. Providers must implement this interface.

type RawState

type RawState struct {
	JSON    []byte
	Flatmap map[string]string
}

RawState is the raw, undecoded state for providers to upgrade. It is undecoded as Terraform, for whatever reason, doesn't have the previous schema available to it, and so cannot decode the state itself and pushes that responsibility off onto providers.

It is safe to assume that Flatmap can be ignored for any state written by Terraform 0.12.0 or higher, but it is not safe to assume that all states written by 0.12.0 or higher will be in JSON format; future versions may switch to an alternate encoding for states.

func (RawState) Unmarshal

func (s RawState) Unmarshal(typ tftypes.Type) (tftypes.Value, error)

Unmarshal returns a `tftypes.Value` that represents the information contained in the RawState in an easy-to-interact-with way. It is the main purpose of the RawState type, and is how provider developers should obtain state values from the UpgradeResourceState RPC call.

Pass in the type you want the `Value` to be interpreted as. Terraform's type system encodes in a lossy manner, meaning the type information is not preserved losslessly when going over the wire. Sets, lists, and tuples all look the same. Objects and maps all look the same, as well, as do user-specified values when DynamicPseudoType is used in the schema. Fortunately, the provider should already know the type; it should be the type of the schema, or DynamicPseudoType if that's what's in the schema. `Unmarshal` will then parse the value as though it belongs to that type, if possible, and return a `tftypes.Value` with the appropriate information. If the data can't be interpreted as that type, an error will be returned saying so. In these cases, double check to make sure the schema is declaring the same type being passed into `Unmarshal`.

In the event an ErrUnknownRawStateType is returned, one of three things has happened:

1. terraform-plugin-go is out of date and out of sync with the protocol, and an issue should be opened on its repo to get it updated.

2. terraform-plugin-go has a bug somewhere, and an issue should be opened on its repo to get it fixed.

3. The provider or a dependency has modified the `RawState` in an unsupported way, or has created one from scratch, and should treat it as opaque and not modify it, only calling `Unmarshal` on `RawState`s received from RPC requests.

State files written before Terraform 0.12 that haven't been upgraded yet cannot be unmarshaled, and must have their Flatmap property read directly.

type ReadDataSourceRequest

type ReadDataSourceRequest struct {
	// TypeName is the type of data source Terraform is requesting an
	// updated state for.
	TypeName string

	// Config is the configuration the user supplied for that data source.
	// See the documentation on `DynamicValue` for information about safely
	// accessing the configuration.
	//
	// The configuration is represented as a tftypes.Object, with each
	// attribute and nested block getting its own key and value.
	//
	// This configuration may have unknown values.
	Config *DynamicValue

	// ProviderMeta supplies the provider metadata configuration for the
	// module this data source is in. Module-specific provider metadata is
	// an advanced feature and usage of it should be coordinated with the
	// Terraform Core team by raising an issue at
	// https://github.com/hashicorp/terraform/issues/new/choose. See the
	// documentation on `DynamicValue` for information about safely
	// accessing the configuration.
	//
	// The configuration is represented as a tftypes.Object, with each
	// attribute and nested block getting its own key and value.
	//
	// This configuration will have known values for all fields.
	ProviderMeta *DynamicValue
}

ReadDataSourceRequest is the request Terraform sends when it wants to get the latest state for a data source.

type ReadDataSourceResponse

type ReadDataSourceResponse struct {
	// State is the current state of the data source, represented as a
	// `DynamicValue`. See the documentation on `DynamicValue` for
	// information about safely creating the `DynamicValue`.
	//
	// The state should be represented as a tftypes.Object, with each
	// attribute and nested block getting its own key and value.
	State *DynamicValue

	// Diagnostics report errors or warnings related to retrieving the
	// current state of the requested data source. Returning an empty slice
	// indicates a successful validation with no warnings or errors
	// generated.
	Diagnostics []*Diagnostic
}

ReadDataSourceResponse is the response from the provider about the current state of the requested data source.

type ReadResourceRequest

type ReadResourceRequest struct {
	// TypeName is the type of resource Terraform is requesting an upated
	// state for.
	TypeName string

	// CurrentState is the current state of the resource as far as
	// Terraform knows, represented as a `DynamicValue`. See the
	// documentation for `DynamicValue` for information about safely
	// accessing the state.
	//
	// The state is represented as a tftypes.Object, with each attribute
	// and nested block getting its own key and value.
	CurrentState *DynamicValue

	// Private is any provider-defined private state stored with the
	// resource. It is used for keeping state with the resource that is not
	// meant to be included when calculating diffs.
	Private []byte

	// ProviderMeta supplies the provider metadata configuration for the
	// module this resource is in. Module-specific provider metadata is an
	// advanced feature and usage of it should be coordinated with the
	// Terraform Core team by raising an issue at
	// https://github.com/hashicorp/terraform/issues/new/choose. See the
	// documentation on `DynamicValue` for information about safely
	// accessing the configuration.
	//
	// The configuration is represented as a tftypes.Object, with each
	// attribute and nested block getting its own key and value.
	//
	// This configuration will have known values for all fields.
	ProviderMeta *DynamicValue
}

ReadResourceRequest is the request Terraform sends when it wants to get the latest state for a resource.

type ReadResourceResponse

type ReadResourceResponse struct {
	// NewState is the current state of the resource according to the
	// provider, represented as a `DynamicValue`. See the documentation for
	// `DynamicValue` for information about safely creating the
	// `DynamicValue`.
	//
	// The state should be represented as a tftypes.Object, with each
	// attribute and nested block getting its own key and value.
	NewState *DynamicValue

	// Diagnostics report errors or warnings related to retrieving the
	// current state of the requested resource. Returning an empty slice
	// indicates a successful validation with no warnings or errors
	// generated.
	Diagnostics []*Diagnostic

	// Private should be set to any state that the provider would like sent
	// with requests for this resource. This state will be associated with
	// the resource, but will not be considered when calculating diffs.
	Private []byte
}

ReadResourceResponse is the response from the provider about the current state of the requested resource.

type ResourceServer

type ResourceServer interface {
	// ValidateResourceTypeConfig is called when Terraform is checking that
	// a resource's configuration is valid. It is guaranteed to have types
	// conforming to your schema. This is your opportunity to do custom or
	// advanced validation prior to a plan being generated.
	ValidateResourceTypeConfig(context.Context, *ValidateResourceTypeConfigRequest) (*ValidateResourceTypeConfigResponse, error)

	// UpgradeResourceState is called when Terraform has encountered a
	// resource with a state in a schema that doesn't match the schema's
	// current version. It is the provider's responsibility to modify the
	// state to upgrade it to the latest state schema.
	UpgradeResourceState(context.Context, *UpgradeResourceStateRequest) (*UpgradeResourceStateResponse, error)

	// ReadResource is called when Terraform is refreshing a resource's
	// state.
	ReadResource(context.Context, *ReadResourceRequest) (*ReadResourceResponse, error)

	// PlanResourceChange is called when Terraform is attempting to
	// calculate a plan for a resource. Terraform will suggest a proposed
	// new state, which the provider can modify or return unmodified to
	// influence Terraform's plan.
	PlanResourceChange(context.Context, *PlanResourceChangeRequest) (*PlanResourceChangeResponse, error)

	// ApplyResourceChange is called when Terraform has detected a diff
	// between the resource's state and the user's config, and the user has
	// approved a planned change. The provider is to apply the changes
	// contained in the plan, and return the resulting state.
	ApplyResourceChange(context.Context, *ApplyResourceChangeRequest) (*ApplyResourceChangeResponse, error)

	// ImportResourceState is called when a user has requested Terraform
	// import a resource. The provider should fetch the information
	// specified by the passed ID and return it as one or more resource
	// states for Terraform to assume control of.
	ImportResourceState(context.Context, *ImportResourceStateRequest) (*ImportResourceStateResponse, error)
}

ResourceServer is an interface containing the methods a resource implementation needs to fill.

type Schema

type Schema struct {
	// Version indicates which version of the schema this is. Versions
	// should be monotonically incrementing numbers. When Terraform
	// encounters a resource stored in state with a schema version lower
	// that the schema version the provider advertises for that resource,
	// Terraform requests the provider upgrade the resource's state.
	Version int64

	// Block is the root level of the schema, the collection of attributes
	// and blocks that make up a resource, data source, provider, or other
	// configuration block.
	Block *SchemaBlock
}

Schema is how Terraform defines the shape of data. It can be thought of as the type information for resources, data sources, provider configuration, and all the other data that Terraform sends to providers. It is how providers express their requirements for that data.

type SchemaAttribute

type SchemaAttribute struct {
	// Name is the name of the attribute. This is what the user will put
	// before the equals sign to assign a value to this attribute.
	Name string

	// Type indicates the type of data the attribute expects. See the
	// documentation for the tftypes package for information on what types
	// are supported and their behaviors.
	Type tftypes.Type

	// Description offers an end-user friendly description of what the
	// attribute is for. This will be surfaced to users through editor
	// integrations, documentation generation, and other settings.
	Description string

	// Required, when set to true, indicates that this attribute must have
	// a value assigned to it by the user or Terraform will throw an error.
	Required bool

	// Optional, when set to true, indicates that the user does not need to
	// supply a value for this attribute, but may.
	Optional bool

	// Computed, when set to true, indicates the the provider will supply a
	// value for this field. If Optional and Required are false and
	// Computed is true, the user will not be able to specify a value for
	// this field without Terraform throwing an error. If Optional is true
	// and Computed is true, the user can specify a value for this field,
	// but the provider may supply a value if the user does not. It is
	// always a violation of Terraform's protocol to substitute a value for
	// what the user entered, even if Computed is true.
	Computed bool

	// Sensitive, when set to true, indicates that the contents of this
	// attribute should be considered sensitive and not included in output.
	// This does not encrypt or otherwise protect these values in state, it
	// only offers protection from them showing up in plans or other
	// output.
	Sensitive bool

	// DescriptionKind indicates the formatting and encoding that the
	// Description field is using.
	DescriptionKind StringKind

	// Deprecated, when set to true, indicates that a attribute should no
	// longer be used and users should migrate away from it. At the moment
	// it is unused and will have no impact, but it will be used in future
	// tooling that is powered by provider schemas to enable richer user
	// experiences. Providers should set it when deprecating attributes in
	// preparation for these tools.
	Deprecated bool
}

SchemaAttribute represents a single attribute within a schema block. Attributes are the fields users can set in configuration using the equals sign, can assign to variables, can interpolate, and can use list comprehensions on.

type SchemaBlock

type SchemaBlock struct {
	// TODO: why do we have version in the block, too?
	Version int64

	// Attributes are the attributes defined within the block. These are
	// the fields that users can set using the equals sign or reference in
	// interpolations.
	Attributes []*SchemaAttribute

	// BlockTypes are the nested blocks within the block. These are used to
	// have blocks within blocks.
	BlockTypes []*SchemaNestedBlock

	// Description offers an end-user friendly description of what the
	// block is for. This will be surfaced to users through editor
	// integrations, documentation generation, and other settings.
	Description string

	// DescriptionKind indicates the formatting and encoding that the
	// Description field is using.
	DescriptionKind StringKind

	// Deprecated, when set to true, indicates that a block should no
	// longer be used and users should migrate away from it. At the moment
	// it is unused and will have no impact, but it will be used in future
	// tooling that is powered by provider schemas to enable richer user
	// experiences. Providers should set it when deprecating blocks in
	// preparation for these tools.
	Deprecated bool
}

SchemaBlock represents a block in a schema. Blocks are how Terraform creates groupings of attributes. In configurations, they don't use the equals sign and use dynamic instead of list comprehensions.

Blocks will show up in state and config Values as a tftypes.Object, with the attributes and nested blocks defining the tftypes.Object's AttributeTypes.

type SchemaNestedBlock

type SchemaNestedBlock struct {
	// TypeName is the name of the block. It is what the user will specify
	// when using the block in configuration.
	TypeName string

	// Block is the block being nested inside another block. See the
	// SchemaBlock documentation for more information on blocks.
	Block *SchemaBlock

	// Nesting is the kind of nesting the block is using. Different nesting
	// modes have different behaviors and imply different kinds of data.
	Nesting SchemaNestedBlockNestingMode

	// MinItems is the minimum number of instances of this block that a
	// user must specify or Terraform will return an error.
	//
	// MinItems can only be set for SchemaNestedBlockNestingModeList and
	// SchemaNestedBlockNestingModeSet. SchemaNestedBlockNestingModeSingle
	// can also set MinItems and MaxItems both to 1 to indicate that the
	// block is required to be set. All other SchemaNestedBlockNestingModes
	// must leave MinItems set to 0.
	MinItems int64

	// MaxItems is the maximum number of instances of this block that a
	// user may specify before Terraform returns an error.
	//
	// MaxItems can only be set for SchemaNestedBlockNestingModeList and
	// SchemaNestedBlockNestingModeSet. SchemaNestedBlockNestingModeSingle
	// can also set MinItems and MaxItems both to 1 to indicate that the
	// block is required to be set. All other SchemaNestedBlockNestingModes
	// must leave MaxItems set to 0.
	MaxItems int64
}

SchemaNestedBlock is a nested block within another block. See SchemaBlock for more information on blocks.

type SchemaNestedBlockNestingMode

type SchemaNestedBlockNestingMode int32

SchemaNestedBlockNestingMode indicates the nesting mode for SchemaNestedBlocks. The nesting mode determines the number of instances of the block allowed, how many labels the block expects, and the data structure used for the block in config and state values.

const (
	// SchemaNestedBlockNestingModeInvalid indicates that the nesting mode
	// for a nested block in the schema is invalid. This generally
	// indicates a nested block that was created incorrectly.
	SchemaNestedBlockNestingModeInvalid SchemaNestedBlockNestingMode = 0

	// SchemaNestedBlockNestingModeSingle indicates that the nested block
	// should be treated as a single block with no labels, and there should
	// not be more than one of these blocks in the containing block. The
	// block will appear in config and state values as a tftypes.Object.
	SchemaNestedBlockNestingModeSingle SchemaNestedBlockNestingMode = 1

	// SchemaNestedBlockNestingModeList indicates that multiple instances
	// of the nested block should be permitted, with no labels, and that
	// the instances of the block should appear in config and state values
	// as a tftypes.List, with an ElementType of tftypes.Object.
	SchemaNestedBlockNestingModeList SchemaNestedBlockNestingMode = 2

	// SchemaNestedBlockNestingModeSet indicates that multiple instances
	// of the nested block should be permitted, with no labels, and that
	// the instances of the block should appear in config and state values
	// as a tftypes.Set, with an ElementType of tftypes.Object.
	SchemaNestedBlockNestingModeSet SchemaNestedBlockNestingMode = 3

	// SchemaNestedBlockNestingModeMap indicates that multiple instances of
	// the nested block should be permitted, each with a single label, and
	// that they should be represented in state and config values as a
	// tftypes.Map, with an AttributeType of tftypes.Object. The labels on
	// the blocks will be used as the map keys. It is an error, therefore,
	// to use the same label value on multiple block instances.
	SchemaNestedBlockNestingModeMap SchemaNestedBlockNestingMode = 4

	// SchemaNestedBlockNestingModeGroup indicates that the nested block
	// should be treated as a single block with no labels, and there should
	// not be more than one of these blocks in the containing block. The
	// block will appear in config and state values as a tftypes.Object.
	//
	// SchemaNestedBlockNestingModeGroup is distinct from
	// SchemaNestedBlockNestingModeSingle in that it guarantees that the
	// block will never be null. If it is omitted from a config, the block
	// will still be set, but its attributes and nested blocks will all be
	// null. This is an exception to the rule that any block not set in the
	// configuration cannot be set in config by the provider; this ensures
	// the block is always considered "set" in the configuration, and is
	// therefore settable in state by the provider.
	SchemaNestedBlockNestingModeGroup SchemaNestedBlockNestingMode = 5
)

func (SchemaNestedBlockNestingMode) String

type StopProviderRequest

type StopProviderRequest struct{}

StopProviderRequest represents a Terraform RPC request to interrupt a provider's work and terminate a provider's processes as soon as possible.

type StopProviderResponse

type StopProviderResponse struct {
	// Error should be set to a string describing the error if the provider
	// cannot currently shut down for some reason. Because this always
	// represents a system error and not a user error, it is returned as a
	// string, not a Diagnostic.
	Error string
}

StopProviderResponse represents a Terraform RPC response surfacing an issues the provider encountered in terminating.

type StringKind

type StringKind int32

StringKind indicates a formatting or encoding scheme for a string.

const (
	// StringKindPlain indicates a string is plaintext, and should be
	// interpreted as having no formatting information.
	StringKindPlain StringKind = 0

	// StringKindMarkdown indicates a string is markdown-formatted, and
	// should be rendered using a Markdown renderer to correctly display
	// its formatting.
	StringKindMarkdown StringKind = 1
)

func (StringKind) String

func (s StringKind) String() string

type UpgradeResourceStateRequest

type UpgradeResourceStateRequest struct {
	// TypeName is the type of resource that Terraform needs to upgrade the
	// state for.
	TypeName string

	// Version is the version of the state the resource currently has.
	Version int64

	// RawState is the state as Terraform sees it right now. See the
	// documentation for `RawState` for information on how to work with the
	// data it contains.
	RawState *RawState
}

UpgradeResourceStateRequest is the request Terraform sends when it needs a provider to upgrade the state of a given resource.

type UpgradeResourceStateResponse

type UpgradeResourceStateResponse struct {
	// UpgradedState is the upgraded state for the resource, represented as
	// a `DynamicValue`. See the documentation on `DynamicValue` for
	// information about safely creating the `DynamicValue`.
	//
	// The state should be represented as a tftypes.Object, with each
	// attribute and nested block getting its own key and value.
	UpgradedState *DynamicValue

	// Diagnostics report errors or warnings related to upgrading the
	// state of the requested resource. Returning an empty slice indicates
	// a successful validation with no warnings or errors generated.
	Diagnostics []*Diagnostic
}

UpgradeResourceStateResponse is the response from the provider containing the upgraded state for the given resource.

type ValidateDataSourceConfigRequest

type ValidateDataSourceConfigRequest struct {
	// TypeName is the type of data source Terraform is validating.
	TypeName string

	// Config is the configuration the user supplied for that data source.
	// See the documentation on `DynamicValue` for more information about
	// safely accessing the configuration.
	//
	// The configuration is represented as a tftypes.Object, with each
	// attribute and nested block getting its own key and value.
	//
	// This configuration may contain unknown values if a user uses
	// interpolation or other functionality that would prevent Terraform
	// from knowing the value at request time.
	Config *DynamicValue
}

ValidateDataSourceConfigRequest is the request Terraform sends when it wants to validate a data source's configuration.

type ValidateDataSourceConfigResponse

type ValidateDataSourceConfigResponse struct {
	// Diagnostics report errors or warnings related to the given
	// configuration. Returning an empty slice indicates a successful
	// validation with no warnings or errors generated.
	Diagnostics []*Diagnostic
}

ValidateDataSourceConfigResponse is the response from the provider about the validity of a data source's configuration.

type ValidateResourceTypeConfigRequest

type ValidateResourceTypeConfigRequest struct {
	// TypeName is the type of resource Terraform is validating.
	TypeName string

	// Config is the configuration the user supplied for that resource. See
	// the documentation on `DynamicValue` for more information about
	// safely accessing the configuration.
	//
	// The configuration is represented as a tftypes.Object, with each
	// attribute and nested block getting its own key and value.
	//
	// This configuration may contain unknown values if a user uses
	// interpolation or other functionality that would prevent Terraform
	// from knowing the value at request time. Any attributes not directly
	// set in the configuration will be null.
	Config *DynamicValue
}

ValidateResourceTypeConfigRequest is the request Terraform sends when it wants to validate a resource's configuration.

type ValidateResourceTypeConfigResponse

type ValidateResourceTypeConfigResponse struct {
	// Diagnostics report errors or warnings related to the given
	// configuration. Returning an empty slice indicates a successful
	// validation with no warnings or errors generated.
	Diagnostics []*Diagnostic
}

ValidateResourceTypeConfigResponse is the response from the provider about the validity of a resource's configuration.

Directories

Path Synopsis
Package tf5server implements a server implementation to run tfprotov5.ProviderServers as gRPC servers.
Package tf5server implements a server implementation to run tfprotov5.ProviderServers as gRPC servers.
internal