This page explains how to migrate a resource's schema from SDKv2 to the plugin framework. To migrate a resource, implement the resource schema and related functions in the framework, and then add the resource to your provider. In SDKv2, developers usually implement resources as functions that return a resource schema. In the framework, resources are defined as types that implement the correct interface.
Resources are an abstraction that allow Terraform to manage infrastructure. objects. To develop a resource for your provider, define functionality that maps to API operations so that Terraform can create, read, update, and delete infrastructure of that resource's type. Resource schemas define resource fields, give Terraform metadata about those fields, and define how the resource behaves.
Refer to Resources in the framework documentation for details on implementing resources in the framework.
In SDKv2, resources are defined by the ResourcesMap
field in the schema.Provider
struct, which maps resource names (strings) to their schema. Each schema is a schema.Resource
struct that includes:
Schema
field, which defines resource attributesCreate
and CreateContext
StateUpgraders
), import (Importer
), and customize diff (CustomizeDiff
)In the framework, you define your provider's resources by adding them to your provider's Resources
method.
The Resources
method on your provider.Provider
returns a slice of functions that return types that implement the resource.Resource
interface for each resource your provider supports.
The following code shows a basic implementation of resource schema with SDKv2.
SDKv2
func New() *schema.Provider {
return &schema.Provider{
ResourcesMap: map[string]*schema.Resource {
"resource_example": resourceExample(),
/* ... */
},
/* ... */
}
}
SDKv2 defines the schema.Resource
struct as follows.
SDKv2
schema.Resource{
Schema map[string]*Schema
SchemaVersion int
MigrateState StateMigrateFunc
StateUpgraders []StateUpgrader
Create CreateFunc
Read ReadFunc
Update UpdateFunc
Delete DeleteFunc
Exists ExistsFunc
CreateContext CreateContextFunc
ReadContext ReadContextFunc
UpdateContext UpdateContextFunc
DeleteContext DeleteContextFunc
CreateWithoutTimeout CreateContextFunc
ReadWithoutTimeout ReadContextFunc
UpdateWithoutTimeout UpdateContextFunc
DeleteWithoutTimeout DeleteContextFunc
CustomizeDiff CustomizeDiffFunc
Importer *ResourceImporter
DeprecationMessage string
Timeouts *ResourceTimeout
Description string
UseJSONNumber bool
}
The following code shows how you add a resource to your provider with the framework.
Framework
func (p *provider) Resources(ctx context.Context) []func() resource.Resource {
return []func() resource.Resource{
func() resource.Resource {
return resourceTypeExample{}
},
}
}
The resource.Resource
interface requires Metadata
, Schema
, Create
, Read
, Update
, and Delete
methods.
The Schema
method returns a schema.Schema
struct which defines your resource's attributes.
The Metadata
method returns a type name that you define.
The following code shows how you define an example resource that implements resource.Resource
interface.
Framework
type resourceExample struct{}
func (r *resourceExample) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) {
/* ... */
}
func (r *resourceExample) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) {
/* ... */
}
func (r *resourceExample) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
/* ... */
}
func (r *resourceExample) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) {
/* ... */
}
func (r *resourceExample) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) {
/* ... */
}
func (r *resourceExample) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) {
/* ... */
}
Refer to the Resources - CRUD functions page in this guide to learn how to implement the resource.Resource
interface.
Remember the following differences between SDKv2 and the framework when migrating resource schema.
schema.Resource
structs to define resources. These structs have a Schema
field, which holds a schema.Schema
struct that defines the resource's attributes and behavior. In the framework, you define a type that implements the resource.Resource
interface, which includes a Schema
method that returns your resource's schema.schema.Resource
. In the framework, you define a type that implements the resource.Resource
interface. The resource interface contains the functions that define your resource's CRUD operations.The following examples demonstrate migrating a resource from SDKv2 to the framework.
Migrate a resourceMigrating a resource from the SDKv2 to the framework typically involves implmenting a type that satisfies the resource.Resource
interface and adding it to the return value of your providers Resources
function.
In SDKv2, the ResourcesMap
field on the schema.Provider
struct holds a map[string]*schemaResource
. A typical pattern is to implement a function that returns schema.Resource
.
SDKv2
func New() (*schema.Provider, error) {
return &schema.Provider {
ResourcesMap: map[string]*schema.Resource {
"example_resource": exampleResource(),
/* ... */
This code defines the example_resource
resource by mapping the resource name to the exampleResource
struct.
SDKv2
func exampleResource() *schema.Resource {
return &schema.Resource{
CreateContext: createResource,
DeleteContext: deleteResource,
ReadContext: readResource,
Schema: map[string]*schema.Schema{
"attribute": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
ValidateDiagFunc: validation.ToDiagFunc(validation.StringInSlice([]string{'a', 'b'}, false)),
},
/* ... */
The following shows the same section of provider code after the migration.
Framework
func (p *exampleProvider) Resources(_ context.Context) []func() resource.Resource {
return []func() resource.Resource{
func() resource.Resource {
return &exampleResource{}
},
/* ... */
}
}
This code defines the Schema
and Metadata
methods for the Resource
.
Framework
func (r *exampleResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) {
resp.TypeName = "example_resource"
}
func (r *exampleResource) Schema(_ context.Context, _ resource.SchemaRequest, resp *resource.SchemaResponse) {
resp.Schema = schema.Schema{
Attributes: map[string]schema.Attribute{
// Required attributes
"attribute": schema.StringAttribute{
Required: true,
PlanModifiers: []planmodifier.String{
stringplanmodifier.RequiresReplace(),
},
Validators: []validator.String{
stringvalidator.OneOf([]string{"a", "b"}...),
},
},
/* ... */
},
}
}
Refer to the Migrating schema page in this migration guide to learn how to migrate your resource's schema to the framework.
Once you have migrated your resource schema to the framework, you must implement the resource functionality in your resource's type. To do so, write code that satisfies the resource.Resource
interface. At a minimum, you must migrate the create, read, update, delete (CRUD) functions for your resource, as well as import functionality if your SDKv2 provider supports it. Some resources may implement additional functionality that you must migrate to the framework, as well.
CustomizeDiff
functions to modify the plan, refer to the Resources - Plan modification page in this guide.StateUpgraders
, refer to the Resources - State upgrading page in this guide to migrate them to UpgradeState
functions in the framework.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