Terraform
Schemas
Schemas specify the constraints of Terraform configuration blocks. They define what fields a provider, resource, or data source configuration block has, and give Terraform metadata about those fields. You can think of the schema as the "type information" or the "shape" of a resource, data source, or provider.
Each concept has its own schema
package and Schema
type, which defines functionality available to that concept:
- Providers:
provider/schema.Schema
- Resources:
resource/schema.Schema
- Data Sources:
datasource/schema.Schema
- Ephemeral Resources:
ephemeral/schema.Schema
During execution of the terraform validate
, terraform plan
and terraform apply
commands, Terraform calls the provider GetProviderSchema
RPC, in which the framework calls the provider.Provider
interface Schema
method, the resource.Resource
interface Schema
method, datasource.DataSource
interface Schema
method, and the ephemeral.EphemeralResource
interface Schema
method on each of the resource types, respectively.
Version
Version is only valid for resources.
Every schema has a version, which is an integer that allows you to track changes to your schemas. It is generally only used when upgrading resource state, to help massage resources created with earlier schemas into the shape defined by the current schema. It will never be used for provider or data source schemas and can be omitted.
DeprecationMessage
Not every resource, data source, ephemeral resource, or provider will be supported forever.
Sometimes designs change or APIs are deprecated. Schemas that have their
DeprecationMessage
property set will display that message as a warning when
that provider, data source, or resource is used. A good message will tell
practitioners that the provider, resource, or data source is deprecated, and
will indicate a migration strategy.
Description
Various tooling like
terraform-plugin-docs and
the language server can use
metadata in the schema to generate documentation or offer a better editor
experience for practitioners. Use the Description
property to add a description of a resource, data source, or provider that these tools can leverage.
MarkdownDescription
Similar to the Description
property, the MarkdownDescription
is used to
provide a markdown-formatted version of the description to tooling like
terraform-plugin-docs. It
is a best practice to only alter the formatting, not the content, between the
Description
and MarkdownDescription
.
At the moment, if the MarkdownDescription
property is set it will always be
used instead of the Description
property. It is possible that a different strategy may be employed in the future to surface descriptions to other tooling in a different format, so we recommend specifying both fields.
Unit Testing
Schemas can be unit tested via each of the schema.Schema
type ValidateImplementation()
methods. This unit testing raises schema implementation issues more quickly in comparison to acceptance tests, but does not replace the purpose of acceptance testing.
In this example, a thing_resource_test.go
file is created alongside the thing_resource.go
implementation file:
import (
"context"
"testing"
// The fwresource import alias is so there is no collistion
// with the more typical acceptance testing import:
// "github.com/hashicorp/terraform-plugin-testing/helper/resource"
fwresource "github.com/hashicorp/terraform-plugin-framework/resource"
)
func TestThingResourceSchema(t *testing.T) {
t.Parallel()
ctx := context.Background()
schemaRequest := fwresource.SchemaRequest{}
schemaResponse := &fwresource.SchemaResponse{}
// Instantiate the resource.Resource and call its Schema method
NewThingResource().Schema(ctx, schemaRequest, schemaResponse)
if schemaResponse.Diagnostics.HasError() {
t.Fatalf("Schema method diagnostics: %+v", schemaResponse.Diagnostics)
}
// Validate the schema
diagnostics := schemaResponse.Schema.ValidateImplementation(ctx)
if diagnostics.HasError() {
t.Fatalf("Schema validation diagnostics: %+v", diagnostics)
}
}