Thanks, @bflad.
directly copying the prior state into the refreshed state … should be no “differences” between the two
This was my expectation.
My resource has a bunch of nested objects. It looks roughly like the following (many irrelevant attributes removed):
func (o *myResource) Schema(_ context.Context, _ resource.SchemaRequest, resp *resource.SchemaResponse) {
resp.Schema = schema.Schema{
Attributes: map[string]schema.Attribute{
"aaa": schema.SetNestedAttribute{
Required: true,
PlanModifiers: []planmodifier.Set{setplanmodifier.UseStateForUnknown()},
NestedObject: schema.NestedAttributeObject{
Attributes: map[string]schema.Attribute{
"bbb": schema.SingleNestedAttribute{
Computed: true,
PlanModifiers: []planmodifier.Object{objectplanmodifier.UseStateForUnknown()},
Attributes: map[string]schema.Attribute{
"ccc": schema.ListNestedAttribute{
Computed: true,
PlanModifiers: []planmodifier.List{listplanmodifier.UseStateForUnknown()},
NestedObject: schema.NestedAttributeObject{
Attributes: map[string]schema.Attribute{
"ddd_1": schema.Int64Attribute{
MarkdownDescription: "Physical vertical dimension of the panel.",
Computed: true,
PlanModifiers: []planmodifier.Int64{int64planmodifier.UseStateForUnknown()},
},
"ddd_2": schema.Int64Attribute{
Computed: true,
PlanModifiers: []planmodifier.Int64{int64planmodifier.UseStateForUnknown()},
},
"ddd_3": schema.ListNestedAttribute{
Computed: true,
PlanModifiers: []planmodifier.List{listplanmodifier.UseStateForUnknown()},
NestedObject: schema.NestedAttributeObject{
Attributes: map[string]schema.Attribute{
"eee_1": schema.Int64Attribute{
Computed: true,
PlanModifiers: []planmodifier.Int64{int64planmodifier.UseStateForUnknown()},
},
"eee_2": schema.StringAttribute{
Computed: true,
PlanModifiers: []planmodifier.String{stringplanmodifier.UseStateForUnknown()},
},
"eee_3": schema.SetAttribute{
Computed: true,
ElementType: types.StringType,
PlanModifiers: []planmodifier.Set{setplanmodifier.UseStateForUnknown()},
},
},
},
},
},
},
},
},
},
},
},
},
},
}
}
When I first terraform apply
, everything goes the way I expect: The resource is created and the Computed
attributes are learned and saved to the Terraform state.
Things go sideways on Read()
, and have continued to do so even with the short-circuit Read()
function I posted previously.
The plan output indicates that set aaa
is scheduled to be modified, replacing its only element with a new element. That new element is identical to the previous one (elements I’ve omitted here are all the same), except that its ccc
is now an empty list.
The ccc
list wasn’t empty in the object retrieved from, and then immediately re-committed to the state. I think something happened in plan generation.
The plan output looks like this:
# foo.r will be updated in-place
~ resource "foo" "r" {
id = "qnxzfxucqo-uyigprhs6zw"
~ aaa = [
- {
- bbb = {
- name = "some_string" -> null
- ccc = [
- {
- ddd_1 = 7 -> null
- ddd_2 = 1 -> null
- ddd_3 = [
- {
- eee_1 = 7 -> null
- eee_2 = "10G" -> null
- eee_3 = [
- "val1",
- "val2",
- "val3",
] -> null
},
]
},
]
}
- name = "some_other_string" -> null
- some_identifier = "yet_another_string" -> null
},
+ {
+ bbb = {
+ name = "name_bbb"
+ ccc = [ <---------- this is not expected to be empty
]
}
+ name = "some_other_string"
+ some_identifier = "yet_another_string"
},
]
name = "aaa terraform"
# (2 unchanged attributes hidden)
}
I’ve likely made some transcription errors here. I’m hoping to soon have a sanitized, simple provider which will make it easy to replicate the issue.