Skip to content

Latest commit

 

History

History
185 lines (142 loc) · 6.58 KB

File metadata and controls

185 lines (142 loc) · 6.58 KB
page_title description
Data Sources: Migrating from SDKv2 to the Framework
Migrate a data source from SDKv2 to the plugin Framework.

Data Sources

-> Note: The Plugin Framework is in beta.

Data sources let Terraform reference external data. Unlike resources, Terraform does not create, update, or delete data sources, and makes no attempt to modify the underlying API. Data Sources are a read-only resource type, so they only implement a subset of the operations that resources do. Refer to Data Sources in the Framework documentation for details.

This page explains how to migrate a data source from SDKv2 to the plugin Framework. We also recommend reviewing these additional guides for data sources throughout the migration:

  • Timeouts: The data source uses timeouts during a read operation.

SDKv2

In SDKv2, data sources are defined by the DataSourcesMap field on the schema.Provider struct, which maps data source names (strings) to their schema. The schema.Resource struct is used for both resources and data sources.

The following example shows a typical implementation.

func New() *schema.Provider {
    return &schema.Provider{
        DataSourcesMap:   map[string]*schema.Resource{
        /* ... */
},

In SDKv2, you define both resources and data sources with schema.Resource structs. The following example shows a resource struct. For clarity, the example omits fields that are not available for data sources.

schema.Resource {
    Schema:               map[string]*schema.Schema,
    Read:                 ReadFunc,
    ReadContext:          ReadContextFunc,
    ReadWithoutTimeout:   ReadContextFunc,
    DeprecationMessage:   string,
    Timeouts:             *ResourceTimeout,
    Description:          string,
}

Framework

In the Framework, you define data sources by adding them to the map returned by your provider's DataSources method.

The DataSources method on your provider.Provider returns a slice of functions that return types that implement the datasource.DataSource interface for each data source your provider supports.

The following code shows how you add a data source to your provider with the Framework.

func (p *provider) DataSources(ctx context.Context) []func() datasource.DataSource {
    return []func() datasource.DataSource{
		/* ... */
    }
}

Like the resource.Resource interface, datasource.DataSource requires GetSchema and Metadata methods. These methods work the same way for data sources as they do for resources. The Read method is also required.

The GetSchema method returns a tfsdk.Schema struct which defines your data source's attributes. This is the same struct you use to define provider and resource attributes.

The Metadata method returns a type name that you define.

The Read method implements the logic for writing into the Terraform state.

The following code shows how you define a datasource.DataSource which implements these methods with the Framework.

type dataSourceExample struct{}

func (d *dataSourceExample) Metadata(ctx context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) {
    /* ... */
}

func (d *dataSourceExample) GetSchema(context.Context) (tfsdk.Schema, diag.Diagnostics) {
    /* ... */
}

func (d *dataSourceExample) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
    /* ... */
}

Migration Notes

Remember the following details when completing the migration from SDKv2 to the Framework.

  • As data sources are read-only, you only implement read functionality for your provider's data sources. Refer to the Read function for resources in the Framework documentation for more details.

Example

The following examples show how to migrate portions of the http provider.

For a complete example, clone the terraform-provider-http repository and compare the data_source.go file in v2.2.0 and the data_source_http.go file after the migration.

SDKv2

The following example from the provider.go file shows an implementation of the DataSourcesMap field on the provider schema with SDKv2.

func New() (*schema.Provider, error) {
    return &schema.Provider {
        DataSourcesMap: map[string]*schema.Resource {
            "http": dataSource(),
            /* ... */

The following example from the data_source.go file shows how the ReadContext function and Schema are defined for the http data source with SDKv2.

func dataSource() *schema.Resource {
    return &schema.Resource{
        ReadContext: dataSourceRead,

        Schema: map[string]*schema.Schema{
            "url": {
                Description: "The URL for the request. Supported schemes are `http` and `https`.",
                Type:        schema.TypeString,
                Required:    true,
            },
            /* ... */
        },
    }
}

Framework

The following example from the provider.go file shows how the http data source is defined with the Framework after the migration.

func (p *provider) DataSources(context.Context) []func() datasource.DataSource {
    return []func() datasource.DataSource{
        func() datasource.DataSource {
            return &httpDataSource{}
        },
    }
}

This code from the data_source_http.go file defines the methods for the http data source with the Framework.

func (d *httpDataSource) Metadata(ctx context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) {
    // This is unconventional in that the data source name matches the provider name.
    // Typically these should have the provider name, an underscore, then the type name.
    // e.g. http_request
    resp.TypeName = "http"
}

func (d *httpDataSource) GetSchema(context.Context) (tfsdk.Schema, diag.Diagnostics) {
    return tfsdk.Schema{
        Attributes: map[string]tfsdk.Attribute{
            "url": {
                Description: "The URL for the request. Supported schemes are `http` and `https`.",
                Type:        types.StringType,
                Required:    true,
            },
            /* ... */

func (d *httpDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
    /* ... */
}