Skip to content

Latest commit

 

History

History
147 lines (114 loc) · 5.17 KB

File metadata and controls

147 lines (114 loc) · 5.17 KB
page_title description
Attribute default values: Migrating from SDKv2 to the Framework
Specify a default when the Terraform configuration does not supply a value for attributes. Migrate attribute defaults in SDKv2 to AttributePlanModifier in the Framework.

Default Values

-> Note: The Plugin Framework is in beta.

Default values set a value for an attribute when the Terraform configuration does not provide one. In SDKv2, default values are set via fields on an attribute's schema. In the Framework, you set default values via plan modification. Refer to Plan Modification - Attribute Plan Modification in the Framework documentation for details.

This page explains how to migrate attribute defaults in SDKv2 to AttributePlanModifier in the Framework.

SDKv2

In SDKv2, default values are defined for a primitive attribute type (i.e., TypeBool, TypeFloat, TypeInt, TypeString) by the Default field on the attribute's schema. Alternatively, the DefaultFunc function is used to compute a default value for an attribute.

The following code shows a basic implementation of a default value for a primitive attribute type in SDKv2.

func resourceExample() *schema.Resource {
    return &schema.Resource{
         /* ... */
        Schema: map[string]*schema.Schema{
            "attribute_example": {
                Default:     2048,
                /* ... */
            },
        /* ... */

Framework

In the Framework, you set default values with the PlanModifiers field on your attribute's definition.

func (r *resourceExample) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) {
    resp.Schema = schema.Schema{
        /* ... */
        Attributes: map[string]schema.Attribute{
            "attribute_example": schema.BoolAttribute{
                PlanModifiers: []planmodifier.Bool{
                    defaultValue(types.BoolValue(true)),
                    /* ... */

Migration Notes

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

  • In SDKv2, default values are set with the Default or DefaultFunc fields on an attribute's schema.Schema struct. In the Framework, you must implement an attribute plan modifier to set default values.

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 resource_private_key.go file in v3.4.0 with the file after the migration.

SDKv2

The following example from the resource_private_key.go file shows the implementation of the Default field for the rsa_bits attribute on the tls_private_key resource with SDKv2.

func resourcePrivateKey() *schema.Resource {
    return &schema.Resource{
        Schema: map[string]*schema.Schema{
            "rsa_bits": {
                Default:     2048,
                /* ... */
            },
            /* ... */

Framework

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

This code implements the PlanModifiers field for the rsa_bits attribute with the Framework.

func (r *privateKeyResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) {
    resp.Schema = schema.Schema{
        Attributes: map[string]schema.Attribute{
            "rsa_bits": schema.Int64Attribute{
                PlanModifiers: []planmodifier.Int64{
                    attribute_plan_modifier.Int64DefaultValue(types.Int64Value(2048)),
                    /* ... */
                },
                /* ... */
            },
            /* ... */
        },
    }, nil
}

The following example from the attribute_plan_modifiers.go file implements the DefaultValue attribute plan modifier that the rsa_bits attribute uses.

func Int64DefaultValue(v types.Int64) planmodifier.Int64 {
    return &int64DefaultValuePlanModifier{v}
}

type int64DefaultValuePlanModifier struct {
    DefaultValue types.Int64
}

var _ planmodifier.Int64 = (*int64DefaultValuePlanModifier)(nil)

func (apm *int64DefaultValuePlanModifier) Description(ctx context.Context) string {
    /* ... */
}

func (apm *int64DefaultValuePlanModifier) MarkdownDescription(ctx context.Context) string {
    /* ... */
}

func (apm *int64DefaultValuePlanModifier) PlanModifyInt64(ctx context.Context, req planmodifier.Int64Request, res *planmodifier.Int64Response) {
    // If the attribute configuration is not null, we are done here
    if !req.ConfigValue.IsNull() {
        return
    }

    // If the attribute plan is "known" and "not null", then a previous plan modifier in the sequence
    // has already been applied, and we don't want to interfere.
    if !req.PlanValue.IsUnknown() && !req.PlanValue.IsNull() {
        return
    }

    res.PlanValue = apm.DefaultValue
}