---
page_title: 'Blocks: Migrating from SDKv2 to the Framework'
description: >-
  Migrate blocks from SDKv2 to attribute validators in the plugin Framework.
---

# Blocks

Some providers, resources, and data sources include repeatable nested blocks in their attributes. These nested blocks
typically represent separate objects that are related to (or embedded within) the containing object.

This page explains how to migrate nested blocks that are not computed (i.e., do not set
`Computed: true`) from SDKv2 to the Framework. Refer to
[Blocks with Computed Fields](/terraform/plugin/framework/migrating/attributes-blocks/blocks-computed) for more details
about migrating nested blocks that contain fields that are computed.

The following table describes the mapping between [SDK Schema Fields](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-sdk/helper/schema#Schema) and the Framework.

| SDK Schema Field      | Framework                                                                                                                                                                                                                                                                                                                                     |
|-----------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Type                  | [ListNestedBlock](/terraform/plugin/framework/migrating/attributes-blocks/blocks), [SetNestedBlock](/terraform/plugin/framework/migrating/attributes-blocks/blocks)                                                                                                                                                                           |
| ConfigMode            | Schema must be explictly defined using [Attributes](/terraform/plugin/framework/migrating/attributes-blocks/attribute-schema) and [Blocks](/terraform/plugin/framework/migrating/attributes-blocks/blocks)                                                                                                                                    |
| Required              | [listvalidator.IsRequired](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-framework-validators/listvalidator#IsRequired), [setvalidator.IsRequired](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-framework-validators/setvalidator#IsRequired)                                                                          |
| Optional              | N/A - no implementation required                                                                                                                                                                                                                                                                                                              |
| Computed              | [Blocks with Computed Fields](/terraform/plugin/framework/migrating/attributes-blocks/blocks-computed)                                                                                                                                                                                                                                        |
| ForceNew              | [RequiresReplace](/terraform/plugin/framework/migrating/attributes-blocks/force-new) on `PlanModifiers` field on attribute within block or implementation of [ResourceWithModifyPlan](/terraform/plugin/framework/migrating/resources/plan-modification#framework) interface                                                                  |
| DiffSuppressFunc      | [PlanModifiers](/terraform/plugin/framework/migrating/resources/plan-modification#framework) field on attribute within block or implementation of [ResourceWithModifyPlan](/terraform/plugin/framework/migrating/resources/plan-modification#framework) interface                                                                             |
| DiffSuppressOnRefresh | [Read](/terraform/plugin/framework/migrating/resources/crud) method on resource                                                                                                                                                                                                                                                               |
| Description           | `Description` field on block                                                                                                                                                                                                                                                                                                                  |
| InputDefault          | N/A - no longer valid                                                                                                                                                                                                                                                                                                                         |
| StateFunc             | Requires implementation of bespoke logic before storing state, for instance in resource [Create method](/terraform/plugin/framework/migrating/resources/crud#framework-1)                                                                                                                                                                     |
| Elem                  | `NestedObject` within block                                                                                                                                                                                                                                                                                                                   |
| MaxItems              | Use [listValidator.SizeAtMost](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-framework-validators/listvalidator#SizeAtMost) or [setvalidator.SizeAtMost](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-framework-validators/setvalidator#SizeAtMost) on `Validators` field on `ListNestedBlock` or `SetNestedBlock`     |
| MinItems              | Use [listValidator.SizeAtLeast](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-framework-validators/listvalidator#SizeAtLeast) or [setvalidator.SizeAtLeast](https://pkg.go.dev/github.com/hashicorp/terraform-plugin-framework-validators/setvalidator#SizeAtLeast) on `Validators` field on `ListNestedBlock` or `SetNestedBlock` |
| Set                   | N/A - no implementation required                                                                                                                                                                                                                                                                                                              |                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| ComputedWhen          | N/A - no longer valid                                                                                                                                                                                                                                                                                                                         |
| ConflictsWith         | [Predefined Validators](/terraform/plugin/framework/migrating/attributes-blocks/validators-predefined)                                                                                                                                                                                                                                        |
| ExactlyOneOf          | [Predefined Validators](/terraform/plugin/framework/migrating/attributes-blocks/validators-predefined)                                                                                                                                                                                                                                        |
| AtLeastOneOf          | [Predefined Validators](/terraform/plugin/framework/migrating/attributes-blocks/validators-predefined)                                                                                                                                                                                                                                        |
| RequiredWith          | [Predefined Validators](/terraform/plugin/framework/migrating/attributes-blocks/validators-predefined)                                                                                                                                                                                                                                        |
| Deprecated            | `DeprecationMessage` field on attribute within block                                                                                                                                                                                                                                                                                          |
| ValidateFunc          | [Predefined Validators](/terraform/plugin/framework/migrating/attributes-blocks/validators-predefined) and [Custom Validators](/terraform/plugin/framework/migrating/attributes-blocks/validators-custom)                                                                                                                                     |
| ValidateDiagFunc      | [Predefined Validators](/terraform/plugin/framework/migrating/attributes-blocks/validators-predefined) and [Custom Validators](/terraform/plugin/framework/migrating/attributes-blocks/validators-custom)                                                                                                                                     |
| Sensitive             | N/A - only supported on attributes                                                                                                                                                                                                                                                                                                            |


## Nested Block Example

The following example shows a nested block in Terraform resource configuration. The `subject` nested
block within the `tls_cert_request` resource configures the subject of a certificate request with the `common_name` and
`organization` attributes.

```hcl
resource "tls_cert_request" "example" {
  private_key_pem = file("private_key.pem")

  subject {
    common_name  = "example.com"
    organization = "ACME Examples, Inc"
  }
}
```


## SDKv2

In SDKv2, blocks are defined by an attribute whose type is `TypeList` or `TypeSet` and whose `Elem` field is set to a
`schema.Resource` that contains a map of the block's attribute names to corresponding `schemaSchema` structs.

```go
func resourceExample() *schema.Resource {
    return &schema.Resource{
         /* ... */
        map[string]*schema.Schema{
            "example" = &schema.Schema{
                Type:     schema.TypeList,
                Optional: bool,
                MaxItems: int,
                Elem: &schema.Resource{
                    Schema: map[string]*schema.Schema{
                        "nested_example": {
                            Type:        schema.TypeString,
                            Optional:    bool,
                            /* ... */
```

## Framework

In the Framework, you implement nested blocks with the `Blocks` field of your provider, resource, or data source's
schema, as returned by the `Schema` method. The `Blocks` field maps the name of each block to a
`schema.Block` definition.

```go
func (r *ThingResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) {
    resp.Schema = schema.Schema{
        /* ... */
        Blocks: map[string]schema.Block{
            "example": schema.ListNestedBlock{
                NestedObject: schema.NestedBlockObject{
                    Attributes: map[string]schema.Attribute{
                        "nested_example": schema.StringAttribute{
                            Optional: bool
                            /* ... */
```

##  Example

### SDKv2

The following example shows the implementation of the `example_nested_block` nested block with SDKv2.

```go
map[string]*schema.Schema{
    "example_attribute": &schema.Schema{
        Type:      schema.TypeString,
        /* ... */

    "example_nested_block" = &schema.Schema{
        Type:     schema.TypeList,
        MaxItems: 1,
        Elem: &schema.Resource{
            Schema: map[string]*schema.Schema{
                "example_block_attribute_one": {
                    Type:        schema.TypeString,
                    /* ... */
                },
                "example_block_attribute_two": {
                    Type:        schema.TypeString,
                    /* ... */
                },
                /* ... */
```

### Framework

The following example shows how the nested `example_nested_block` block
is defined with the Framework after the migration.

```go
schema.Schema{
        Attributes: map[string]schema.Attribute{
            "example_attribute": schema.StringAttribute{
            /* ... */

        Blocks: map[string]schema.Block{
            "example_nested_block": schema.ListNestedBlock{
                NestedObject: schema.NestedBlockObject{
                    Attributes: map[string]schema.Attribute{
                        "example_block_attribute_one": schema.StringAttribute{
                            /* ... */
                        },
                        "example_block_attribute_two": schema.StringAttribute{
                            /* ... */
                        },
                Validators: []validator.List{
                    listvalidator.SizeAtMost(1),
                },
```
