Terraform
- Plugin Framework
- v1.16.x (latest)
- No versions of this document exist before v1.15.x. Click below to redirect to the version homepage.
- v1.15.x
- v1.14.x
- v1.13.x
- v1.12.x
- v1.11.x
- v1.10.x
- v1.9.x
- v1.8.x
- v1.7.x
- v1.6.x
- v1.5.x
- v1.4.x
- v1.3.x
- v1.2.x
- v1.1.x
- v1.0.x
- v0.16.x
- v0.15.x
- v0.14.x
- v0.13.x
- v0.12.x
- v0.11.x
- v0.10.x
- v0.9.x
- v0.8.x
- v0.7.x
Blocks with Computed Fields
Note: The Plugin Framework is in beta.
Some providers, resources, and data sources include repeatable nested blocks in their attributes. Some blocks contain
fields  with Computed: true, which means that the provider code can define the value or that it could come from the
output of terraform apply (e.g., the ID of an EC2 instance).
This page explains how to migrate computed-only blocks from SDKv2 to the Framework. Refer to Blocks if you are looking for information about migrating blocks that are practitioner configurable.
SDKv2
In SDKv2, blocks are defined by an attribute whose type is either 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.
map[string]*schema.Schema{
    "example": {
        Type:     schema.TypeList,
        Computed: true,
        Elem: &schema.Resource{
            Schema: map[string]*schema.Schema{
                "nested_example": {
                        Type:        schema.TypeString,
                        Computed:    true,
                        /* ... */
Framework
In the Framework, when working with protocol version 5, computed blocks are implemented using a ListAttribute which has an ElementType of types.ObjectType.
map[string]schema.Attribute{
"example": schema.ListAttribute{
    Computed: true,
    ElementType: types.ObjectType{
        AttrTypes: map[string]attr.Type{
            "nested_example":  types.StringType,
            /* ... */
In the Framework, when working with protocol version 6, we recommend that you define computed blocks using nested
attributes. This example shows usage of ListNestedAttribute as this provides configuration references with list index
syntax as is the case when using schema.TypeList in SDKv2. SingleNestedAttribute is a good choice for single
underlying objects which results in a breaking change but also allows dropping [0] in configuration references.
map[string]schema.Attribute{
"example": schema.ListNestedAttribute{
    Computed: true,
    NestedObject: schema.NestedAttributeObject{
        Attributes: map[string]schema.Attribute{
            "nested_example": schema.StringAttribute{
                Computed: true,
                /* ... */
Migration Notes
- When using protocol version 5 specify ElementTypeastypes.ObjectTypewhen migrating blocks that are computed from SDKv2 to Framework.
- When using protocol version 6, use nested attributes when migrating blocks that are computed from SDKv2 to Framework.
Example
The following examples show how to migrate portions of the tls provider.
For a complete example, clone the
terraform-provider-tls repository and compare the data_source_certificate.go file in
v3.4.0
with
v4.0.1.
SDKv2
The following example from the data_source_certificate.go file shows the implementation of the certificates nested
block on the certificate data source's schema.
Schema: map[string]*schema.Schema{
"certificates": {
        Type:     schema.TypeList,
        Computed: true,
        Elem: &schema.Resource{
            Schema: map[string]*schema.Schema{
                "signature_algorithm": {
                    Type:        schema.TypeString,
                    Computed:    true,
                    /* ... */
                },
Framework
The following shows the same section of provider code after the migration.
This code defines the certificates block as an attribute on the certificate data source's schema, where the
types.ObjectType is being used to define the nested block.
map[string]schema.Attribute{
    "certificates": schema.ListAttribute{
        ElementType: types.ObjectType{
            AttrTypes: map[string]attr.Type{
                "signature_algorithm":  types.StringType,
            },
        },
        Computed:            true,
        /* ... */