hashicorp / hashicorp/terraform-plugin-framework

Read-only computed attribute appears in every plan when adjacent to an optional+computed SetNestedAttribute or ListNestedAttribute with no default

Open
#898 9 comments 6 reactions 0 assignees View on GitHub
bug
Dominant language
Go
Stars
384
Forks
107
Avg merge
3m
Merged PRs (30d)
1

Description

### Module version
```
1.4.2
```

### Relevant provider source code
```go
func (r *unexpectedPlanExampleResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) {
resp.Schema = schema.Schema{
Attributes: map[string]schema.Attribute{
"readonly": schema.StringAttribute{
Optional: false,
Computed: true,
},
"set": schema.SetNestedAttribute{
Optional: true,
Computed: true,
// no default set in schema
PlanModifiers: []planmodifier.Set{
setplanmodifier.UseStateForUnknown(),
},
NestedObject: schema.NestedAttributeObject{
Attributes: map[string]schema.Attribute{
"name": schema.StringAttribute{
Required: true,
},
},
},
},
},
}
}

func (r *unexpectedPlanExampleResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
var model unexpectedPlanExampleResourceModel
req.Plan.Get(ctx, &model)

// Set the same value every time for the string
model.Readonly = types.StringValue("examplereadonly")

// Set the same value every time for the set. {{"name": "examplename"}}
setResult := []attr.Value{}
setVal, _ := types.ObjectValue(map[string]attr.Type{
"name": types.StringType,
},
map[string]attr.Value{
"name": types.StringValue("examplename"),
})
setResult = append(setResult, setVal)
model.Set, _ = types.SetValue(types.ObjectType{AttrTypes: map[string]attr.Type{
"name": types.StringType,
}}, setResult)

resp.State.Set(ctx, model)
}

func (r *unexpectedPlanExampleResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) {
resp.State.Raw = req.State.Raw
}
```

### Terraform Configuration Files
```hcl
resource "example_unexpected_plan_example" "myExamplePlan" {
// both attributes are computed
}
```

### Expected Behavior
Read-only computed attribute should not result in a plan if no other attributes are changed.

### Actual Behavior
The following plan is always produced on a plan after the initial create.
```
Terraform will perform the following actions:

# example_unexpected_plan_example.myExamplePlan will be updated in-place
~ resource "example_unexpected_plan_example" "myExamplePlan" {
~ readonly = "examplereadonly" -> (known after apply)
# (1 unchanged attribute hidden)
}

Plan: 0 to add, 1 to change, 0 to destroy.
```

When I instead change the "set" attribute to be a SetAttribute of strings rather than a SetNestedAttribute, it works as expected, with no plan being produced after the create. I also tried a simple StringAttribute rather than a set and that worked as expected as well. Only SetNestedAttribute and ListNestedAttribute seems to cause this.

I also found that if a default is set in the schema for the set/list, then it stops generating this plan.

### Steps to Reproduce
1. terraform apply to create the resource
2. terraform plan to see the generated plan

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.