diff --git a/internal/lang/blocktoattr/fixup.go b/internal/lang/blocktoattr/fixup.go index 1864e3e50..90eb260d7 100644 --- a/internal/lang/blocktoattr/fixup.go +++ b/internal/lang/blocktoattr/fixup.go @@ -12,6 +12,10 @@ import ( // type in the schema to be written with HCL block syntax as multiple nested // blocks with the attribute name as the block type. // +// The fixup is only applied in the absence of structural attribute types. The +// presence of these types indicate the use of a provider which does not +// support mapping blocks to attributes. +// // This partially restores some of the block/attribute confusion from HCL 1 // so that existing patterns that depended on that confusion can continue to // be used in the short term while we settle on a longer-term strategy. @@ -28,6 +32,10 @@ func FixUpBlockAttrs(body hcl.Body, schema *configschema.Block) hcl.Body { schema = &configschema.Block{} } + if skipFixup(schema) { + return body + } + return &fixupBody{ original: body, schema: schema, @@ -35,6 +43,25 @@ func FixUpBlockAttrs(body hcl.Body, schema *configschema.Block) hcl.Body { } } +// skipFixup detects any use of Attribute.NestedType. Because the fixup was +// only supported for the legacy SDK, there is no situation where structural +// attributes are used where the fixup is expected. +func skipFixup(schema *configschema.Block) bool { + for _, attr := range schema.Attributes { + if attr.NestedType != nil { + return true + } + } + + for _, block := range schema.BlockTypes { + if skipFixup(&block.Block) { + return true + } + } + + return false +} + type fixupBody struct { original hcl.Body schema *configschema.Block diff --git a/internal/lang/blocktoattr/fixup_test.go b/internal/lang/blocktoattr/fixup_test.go index 8c7640521..92799394f 100644 --- a/internal/lang/blocktoattr/fixup_test.go +++ b/internal/lang/blocktoattr/fixup_test.go @@ -400,6 +400,35 @@ container { }), wantErrs: true, }, + "no fixup allowed": { + src: ` + container { + foo = "one" + } + `, + schema: &configschema.Block{ + Attributes: map[string]*configschema.Attribute{ + "container": { + NestedType: &configschema.Object{ + Nesting: configschema.NestingList, + Attributes: map[string]*configschema.Attribute{ + "foo": { + Type: cty.String, + }, + }, + }, + }, + }, + }, + want: cty.ObjectVal(map[string]cty.Value{ + "container": cty.NullVal(cty.List( + cty.Object(map[string]cty.Type{ + "foo": cty.String, + }), + )), + }), + wantErrs: true, + }, } ctx := &hcl.EvalContext{