Default Values
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
orDefaultFunc
fields on an attribute'sschema.Schema
struct. In the Framework, you must implement an attribute plan modifier to set default values.
Example
SDKv2
The following example shows the implementation of the Default
field for the
example_attribute
attribute on the exampleResource
resource with SDKv2.
func exampleResource() *schema.Resource {
return &schema.Resource{
Schema: map[string]*schema.Schema{
"example_attribute": {
Default: 2048,
/* ... */
},
/* ... */
Framework
The following shows the same section of code after the migration.
This code implements the PlanModifiers
field for the example_attribute
attribute with the Framework.
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.Int64Attribute{
PlanModifiers: []planmodifier.Int64{
attribute_plan_modifier.Int64DefaultValue(types.Int64Value(2048)),
/* ... */
},
/* ... */
},
/* ... */
},
}, nil
}
The following example implements the Int64DefaultValue
attribute plan modifier
that the example_attribute
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
}