---
page_title: 'Resources - State Upgrading: Migrating from SDKv2 to the Framework'
description: >-
  State upgraders let users update resources provisioned with old schema configurations.
  Migrate resource StateUpgraders in SDKv2 to UpgradeState in the plugin Framework.
---

# State Upgraders

When you update a resource's implementation in your provider, some changes may not be compatible with old versions. You
can create state upgraders to automatically migrate resources provisioned with old schema configurations. Refer to
[State Upgrade](/terraform/plugin/framework/resources/state-upgrade) in the Framework documentation for details.

This page explains how to migrate resource `StateUpgraders` in SDKv2 to `UpgradeState` in the plugin Framework.

## SDKv2

In SDKv2, state upgraders are defined by populating the `StateUpgraders` field on the `schema.Resource` struct. Refer
to [State Migration](/terraform/plugin/sdkv2/resources/state-migration) in the SDKv2 documentation for details.

The following code shows a basic implementation of the `stateUpgraders` field in SDKv2.

```go
func resourceExample() *schema.Resource {
    return &schema.Resource{
        StateUpgraders: []schema.StateUpgrader{
            {
                Version: int,
                Type:    cty.Type,
                Upgrade: StateUpgradeFunc,
            },
            /* ... */
```

## Framework

In the Framework, you implement the `ResourceWithUpgradeState` interface on your resource to upgrade your
resource's state when required.

The following code shows how you define an `UpgradeState` function with the Framework.

```go
func (r *resourceExample) UpgradeState(context.Context) map[int64]resource.StateUpgrader {
    return map[int64]resource.StateUpgrader{
        0: {
            PriorSchema:   *schema.Schema,
            StateUpgrader: func(context.Context, UpgradeStateRequest, *UpgradeStateResponse),
        },
        /* ... */
```

The `UpgradeState` function returns a map from state versions to structs that implement state upgrade from the given
version to the latest version.

## Migration Notes

Remember the following differences between SDKv2 and the Framework when completing the migration.

- In SDKv2, you implement state upgraders populating the `StateUpgraders` field on the `schema.Resource` struct. In the
Framework, you define an `UpgradeState` function on the resource itself.
- In SDKv2, state upgraders apply each state upgrader in turn. For example, version 0 => version 1, version 1 =>
version 2. In the Framework, each `UpgradeState` function is required to perform all of the necessary transformations in
a single step. For example, version 0 => version 2, version 1 => version 2.

## Example

### SDKv2

In SDKv2 the `schema.Resource` struct has a `StateUpgraders` field that holds `[]schema.StateUpgrader` struct(s).

The following example from the shows the state upgrade functions for the `example_resource`
resource with SDKv2.

```go
func exampleResource() *schema.Resource {
    return &schema.Resource{
        Schema:        exampleSchemaV2(),
        SchemaVersion: 2,
        StateUpgraders: []schema.StateUpgrader{
            {
                Version: 0,
                Type:    exampleResourceV0().CoreConfigSchema().ImpliedType(),
                Upgrade: exampleResourceStateUpgradeV0,
            },
            {
                Version: 1,
                Type:    exampleResourceV1().CoreConfigSchema().ImpliedType(),
                Upgrade: exampleResourceStateUpgradeV1,
            },
        },
        /* ... */
```

The following example shows the implementation of the `exampleResourceStateUpgradeV0` function with SDKv2.

```go
func exampleResourceStateUpgradeV0(_ context.Context, rawState map[string]interface{}, _ interface{}) (map[string]interface{}, error) {
    if rawState == nil {
        return nil, fmt.Errorf("example resource state upgrade failed, state is nil")
    }

    rawState["example_attribute"] = "value"

    return rawState, nil
}
```

### Framework

The following shows the same section of provider code after the migration.

This code implements the `ResourceWithUpgradeState` interface on the `exampleResource` type by defining an
`UpgradeState` function. The `UpgradeState` function returns a map from each state version (int64) to a
`ResourceStateUpgrader` struct.

```go
func (r *exampleResource) UpgradeState(context.Context) map[int64]resource.StateUpgrader {
    schemaV0 := exampleSchemaV0()
    schemaV1 := exampleSchemaV1()

    return map[int64]resource.StateUpgrader{
        0: {
            PriorSchema:   &schemaV0,
            StateUpgrader: upgradeExampleResourceStateV0toV2,
        },
        1: {
            PriorSchema:   &schemaV1,
            StateUpgrader: upgradeExampleResourceStateV1toV2,
        },
    }
}
```

This code implements the `upgradeExampleResourceStateV0toV2` state upgrade function.

```go
func upgradeExampleResourceStateV0toV2(ctx context.Context, req resource.UpgradeStateRequest, resp *resource.UpgradeStateResponse) {
	type modelV0 struct {
		ID    types.String `tfsdk:"id"`
	}

	var exampleDataV0 modelV0

	resp.Diagnostics.Append(req.State.Get(ctx, &exampleDataV0)...)
	if resp.Diagnostics.HasError() {
		return
	}

	exampleDataV2 := exampleModelV2{
		ID:    exampleDataV0.ID,
	}

	exampleDataV2.ExampleAttribute = types.StringValue("value")

	diags := resp.State.Set(ctx, exampleDataV2)
	resp.Diagnostics.Append(diags...)
```
