diff --git a/plans/objchange/compatible.go b/plans/objchange/compatible.go index 8b3aeedbf..4f944775a 100644 --- a/plans/objchange/compatible.go +++ b/plans/objchange/compatible.go @@ -168,12 +168,6 @@ func assertObjectCompatible(schema *configschema.Block, planned, actual cty.Valu continue } - setErrs := assertSetValuesCompatible(plannedV, actualV, path, func(plannedEV, actualEV cty.Value) bool { - errs := assertObjectCompatible(&blockS.Block, plannedEV, actualEV, append(path, cty.IndexStep{Key: actualEV})) - return len(errs) == 0 - }) - errs = append(errs, setErrs...) - if maybeUnknownBlocks { // When unknown blocks are present the final number of blocks // may be different, either because the unknown set values @@ -184,6 +178,12 @@ func assertObjectCompatible(schema *configschema.Block, planned, actual cty.Valu continue } + setErrs := assertSetValuesCompatible(plannedV, actualV, path, func(plannedEV, actualEV cty.Value) bool { + errs := assertObjectCompatible(&blockS.Block, plannedEV, actualEV, append(path, cty.IndexStep{Key: actualEV})) + return len(errs) == 0 + }) + errs = append(errs, setErrs...) + // There can be fewer elements in a set after its elements are all // known (values that turn out to be equal will coalesce) but the // number of elements must never get larger. diff --git a/plans/objchange/compatible_test.go b/plans/objchange/compatible_test.go index 473ee5119..4c67e610d 100644 --- a/plans/objchange/compatible_test.go +++ b/plans/objchange/compatible_test.go @@ -1163,6 +1163,59 @@ func TestAssertObjectCompatible(t *testing.T) { }), nil, }, + // test a set with an unknown dynamic count going to 0 values + { + &configschema.Block{ + BlockTypes: map[string]*configschema.NestedBlock{ + "block2": { + Nesting: configschema.NestingSet, + Block: schemaWithFoo, + }, + }, + }, + cty.ObjectVal(map[string]cty.Value{ + "block2": cty.SetVal([]cty.Value{ + cty.ObjectVal(map[string]cty.Value{ + "foo": cty.UnknownVal(cty.String), + }), + }), + }), + cty.ObjectVal(map[string]cty.Value{ + "block2": cty.SetValEmpty(cty.Object(map[string]cty.Type{ + "foo": cty.String, + })), + }), + nil, + }, + // test a set with a patially known dynamic count reducing it's values + { + &configschema.Block{ + BlockTypes: map[string]*configschema.NestedBlock{ + "block3": { + Nesting: configschema.NestingSet, + Block: schemaWithFoo, + }, + }, + }, + cty.ObjectVal(map[string]cty.Value{ + "block3": cty.SetVal([]cty.Value{ + cty.ObjectVal(map[string]cty.Value{ + "foo": cty.StringVal("a"), + }), + cty.ObjectVal(map[string]cty.Value{ + "foo": cty.UnknownVal(cty.String), + }), + }), + }), + cty.ObjectVal(map[string]cty.Value{ + "block3": cty.SetVal([]cty.Value{ + cty.ObjectVal(map[string]cty.Value{ + "foo": cty.StringVal("a"), + }), + }), + }), + nil, + }, { &configschema.Block{ BlockTypes: map[string]*configschema.NestedBlock{