---
page_title: 'Attribute ForceNew triggers: Migrating from SDKv2 to the Framework'
description: >-
  Migrate attribute force new in SDKv2 to an attribute plan modifier in the Framework.
---

# ForceNew

In Terraform, sometimes a resource must be replaced when the value of an attribute changes. In SDKv2, this is
accomplished via the `ForceNew` field. In the Framework, you implement the same behavior via a `RequiresReplace` plan
modifier. Refer to
[Plan Modification - Attribute Plan Modification](/terraform/plugin/framework/resources/plan-modification#attribute-plan-modification)
in the Framework documentation for details.

This page explains how to migrate this behavior from SDKv2 to the Framework.

## SDKv2

In SDKv2, setting the `ForceNew` field on an attribute's `schema.Schema` triggers a replace (i.e., a destroy-create
cycle) whenever the attribute's value is changed.

```go
func resourceExample() *schema.Resource {
    return &schema.Resource{
        /* ... */
        Schema: map[string]*schema.Schema{
            "attribute_example": {
                ForceNew:    true
                /* ... */
```

## Framework

In the Framework, you implement the same behavior by using the `resource.RequiresReplace` plan modifier on your
attribute's `schema.Attribute` implementation.

```go
func (r *ThingResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) {
    resp.Schema = schema.Schema{
        /* ... */
        Attributes: map[string]schema.Attribute{
            "attribute_example": schema.StringAttribute{
                PlanModifiers: []planmodifier.String{
                    stringplanmodifier.RequiresReplace(),
                    /* ... */
```

## Migration Notes

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

- In both SDKv2 and Framework, `ForceNew` and `RequiresReplace`, respectively, only trigger a replace if the attribute
is not computed. In the Framework, if an attribute which is computed requires that the resource be replaced when it is
changed, implement a plan modifier that triggers the replacement. Refer to
[RequiresReplacePlanModifier](https://github.com/hashicorp/terraform-provider-random/blob/v3.4.1/internal/planmodifiers/attribute.go#L63)
for an example, but bear in mind that each implementation requires different logic and you may need to detect whether
the plan has already been modified.

## Example

### SDKv2

The following example shows the implementation of the `ForceNew` field of the
`exampleResource` resource's `example_attribute` attribute with SDKv2.

```go
func exampleResource() *schema.Resource {
    return &schema.Resource{
        Schema: map[string]*schema.Schema{
            "example_attribute": {
                ForceNew: true,
				Type:     schema.TypeMap,
                /* ... */
            },
            /* ... */
        },
        /* ... */
    }
}
```

### Framework

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

This code forces the replacement of a `exampleResource` resource when the value of the `example_attribute` attribute is changed.
The example does this using the `PlanModifiers` field within the `exampleResource` attribute's schema.

```go
func (r *exampleResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) {
    resp.Schema = schema.Schema{
        Attributes: map[string]schema.Attribute{
            "example_attribute": schema.MapAttribute{
                PlanModifiers: []planmodifier.Map{
                    mapplanmodifier.RequiresReplace(),
                },
                /* ... */
            },
            /* ... */
        },
    }
}
```
