diff --git a/lang/blocktoattr/fixup_test.go b/lang/blocktoattr/fixup_test.go index 20f71069e..ae650ee67 100644 --- a/lang/blocktoattr/fixup_test.go +++ b/lang/blocktoattr/fixup_test.go @@ -196,6 +196,20 @@ dynamic "foo" { }), }), }, + "dynamic block with empty iterator": { + src: ` +dynamic "foo" { + for_each = [] + content { + bar = foo.value + } +} +`, + schema: fooSchema, + want: cty.ObjectVal(map[string]cty.Value{ + "foo": cty.NullVal(fooSchema.Attributes["foo"].Type), + }), + }, "both attribute and block syntax": { src: ` foo = [] diff --git a/lang/blocktoattr/schema.go b/lang/blocktoattr/schema.go index 2f2463a5c..47a025659 100644 --- a/lang/blocktoattr/schema.go +++ b/lang/blocktoattr/schema.go @@ -55,10 +55,11 @@ func effectiveSchema(given *hcl.BodySchema, body hcl.Body, ambiguousNames map[st }, } content, _, _ = body.PartialContent(&probeSchema) - if len(content.Blocks) > 0 { - // No attribute present and at least one block present, so - // we'll need to rewrite this one as a block for a successful - // result. + if len(content.Blocks) > 0 || dynamicExpanded { + // A dynamic block with an empty iterator returns nothing. + // If there's no attribute and we have either a block or a + // dynamic expansion, we need to rewrite this one as a + // block for a successful result. appearsAsBlock[name] = struct{}{} } }