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
- 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
Assessment
This issue has not been assessed yet.