---
page_title: 'Data Sources: Migrating from SDKv2 to the Framework'
description: >-
  Migrate a data source from SDKv2 to the plugin Framework.
---

# Data Sources

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](/terraform/plugin/framework/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](/terraform/plugin/framework/migrating/data-sources/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.

```go
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.

```go
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.

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

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

The `Schema` method returns a `schema.Schema` struct which defines your data source's 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.

```go
type dataSourceExample struct{}

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

func (d *dataSourceExample) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) {
    /* ... */
}

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](/terraform/plugin/framework/resources#read) for resources in the Framework documentation for more details.

## Example

### SDKv2

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

```go
func New() (*schema.Provider, error) {
    return &schema.Provider {
        DataSourcesMap: map[string]*schema.Resource {
            "example_datasource": exampleDataSource(),
            /* ... */
```

The following example shows how the `ReadContext` function and `Schema` are defined for
the `exampleResource` data source with SDKv2.

```go
func exampleDataSource() *schema.Resource {
    return &schema.Resource{
        ReadContext: dataSourceRead,

        Schema: map[string]*schema.Schema{
            "example_attribute": {
                Type:        schema.TypeString,
                Required:    true,
            },
            /* ... */
        },
    }
}
```

### Framework

The following example shows how the `exampleDataSource` data source is defined with the Framework after
the migration.

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

This code defines the methods for the `exampleDataSource` data source with the
Framework.

```go
func (d *exampleDataSource) Metadata(ctx context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) {
    resp.TypeName = "example_datasource"
}

func (d *exampleDataSource) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) {
    resp.Schema = schema.Schema{
        Attributes: map[string]schema.Attribute{
            "example_attribute": schema.StringAttribute{
                Required:    true,
            },
            /* ... */

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