diff --git a/builtin/providers/test/resource_nested_set_test.go b/builtin/providers/test/resource_nested_set_test.go index fac38ef6d..fd05f6c12 100644 --- a/builtin/providers/test/resource_nested_set_test.go +++ b/builtin/providers/test/resource_nested_set_test.go @@ -620,3 +620,39 @@ resource "test_resource_nested_set" "bar" { }, }) } + +func TestResourceNestedSet_dynamicSetBlock(t *testing.T) { + resource.UnitTest(t, resource.TestCase{ + Providers: testAccProviders, + CheckDestroy: testAccCheckResourceDestroy, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: strings.TrimSpace(` +resource "test_resource" "a" { + required = "ok" + required_map = { + a = "b" + } +} + +resource "test_resource_nested_set" "foo" { + dynamic "with_list" { + iterator = thing + for_each = test_resource.a.computed_list + content { + required = thing.value + list = [thing.key] + } + } +} + `), + Check: resource.ComposeTestCheckFunc( + func(s *terraform.State) error { + fmt.Println(s) + return nil + }, + ), + }, + }, + }) +} diff --git a/plans/objchange/compatible.go b/plans/objchange/compatible.go index 8a74c07fe..d85086c97 100644 --- a/plans/objchange/compatible.go +++ b/plans/objchange/compatible.go @@ -169,6 +169,16 @@ func assertObjectCompatible(schema *configschema.Block, planned, actual cty.Valu }) 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 + // become equal and are collapsed, or the count is unknown due + // a dynamic block. Unfortunately this means we can't do our + // usual checks in this case without generating false + // negatives. + continue + } + // 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 2841ec26b..473ee5119 100644 --- a/plans/objchange/compatible_test.go +++ b/plans/objchange/compatible_test.go @@ -1068,9 +1068,9 @@ func TestAssertObjectCompatible(t *testing.T) { }), }), }), - []string{ - `.block: block set length changed from 2 to 3`, - }, + // there is no error here, because the presence of unknowns + // indicates this may be a dynamic block, and the length is unknown + nil, }, { &configschema.Block{ @@ -1135,6 +1135,34 @@ func TestAssertObjectCompatible(t *testing.T) { }), nil, }, + { + &configschema.Block{ + BlockTypes: map[string]*configschema.NestedBlock{ + "block": { + Nesting: configschema.NestingSet, + Block: schemaWithFoo, + }, + }, + }, + cty.ObjectVal(map[string]cty.Value{ + "block": cty.SetVal([]cty.Value{ + cty.ObjectVal(map[string]cty.Value{ + "foo": cty.UnknownVal(cty.String), + }), + }), + }), + cty.ObjectVal(map[string]cty.Value{ + "block": cty.SetVal([]cty.Value{ + cty.ObjectVal(map[string]cty.Value{ + "foo": cty.StringVal("a"), + }), + cty.ObjectVal(map[string]cty.Value{ + "foo": cty.StringVal("b"), + }), + }), + }), + nil, + }, { &configschema.Block{ BlockTypes: map[string]*configschema.NestedBlock{