diff --git a/internal/plans/objchange/objchange.go b/internal/plans/objchange/objchange.go index 281b9dd13..739d66648 100644 --- a/internal/plans/objchange/objchange.go +++ b/internal/plans/objchange/objchange.go @@ -308,7 +308,9 @@ func proposedNewAttributes(attrs map[string]*configschema.Attribute, prior, conf } func proposedNewNestedType(schema *configschema.Object, prior, config cty.Value) cty.Value { - var newV cty.Value + // If the config is null or empty, we will be using this default value. + newV := config + switch schema.Nesting { case configschema.NestingSingle: if !config.IsNull() { @@ -323,6 +325,7 @@ func proposedNewNestedType(schema *configschema.Object, prior, config cty.Value) if config.IsKnown() && !config.IsNull() { configVLen = config.LengthInt() } + if configVLen > 0 { newVals := make([]cty.Value, 0, configVLen) for it := config.ElementIterator(); it.Next(); { @@ -345,8 +348,6 @@ func proposedNewNestedType(schema *configschema.Object, prior, config cty.Value) } else { newV = cty.ListVal(newVals) } - } else { - newV = cty.NullVal(schema.ImpliedType()) } case configschema.NestingMap: @@ -378,8 +379,6 @@ func proposedNewNestedType(schema *configschema.Object, prior, config cty.Value) // object values so that elements might have different types // in case of dynamically-typed attributes. newV = cty.ObjectVal(newVals) - } else { - newV = cty.NullVal(schema.ImpliedType()) } } else { configVLen := 0 @@ -403,8 +402,6 @@ func proposedNewNestedType(schema *configschema.Object, prior, config cty.Value) newVals[k] = cty.ObjectVal(newEV) } newV = cty.MapVal(newVals) - } else { - newV = cty.NullVal(schema.ImpliedType()) } } @@ -446,8 +443,6 @@ func proposedNewNestedType(schema *configschema.Object, prior, config cty.Value) } } newV = cty.SetVal(newVals) - } else { - newV = cty.NullVal(schema.ImpliedType()) } } diff --git a/internal/plans/objchange/objchange_test.go b/internal/plans/objchange/objchange_test.go index 77147989b..b0021fb14 100644 --- a/internal/plans/objchange/objchange_test.go +++ b/internal/plans/objchange/objchange_test.go @@ -1461,6 +1461,81 @@ func TestProposedNew(t *testing.T) { }))), }), }, + "expected empty NestedTypes": { + &configschema.Block{ + Attributes: map[string]*configschema.Attribute{ + "set": { + NestedType: &configschema.Object{ + Nesting: configschema.NestingSet, + Attributes: map[string]*configschema.Attribute{ + "bar": {Type: cty.String}, + }, + }, + Optional: true, + }, + "map": { + NestedType: &configschema.Object{ + Nesting: configschema.NestingMap, + Attributes: map[string]*configschema.Attribute{ + "bar": {Type: cty.String}, + }, + }, + Optional: true, + }, + }, + }, + cty.ObjectVal(map[string]cty.Value{ + "map": cty.MapValEmpty(cty.Object(map[string]cty.Type{"bar": cty.String})), + "set": cty.SetValEmpty(cty.Object(map[string]cty.Type{"bar": cty.String})), + }), + cty.ObjectVal(map[string]cty.Value{ + "map": cty.MapValEmpty(cty.Object(map[string]cty.Type{"bar": cty.String})), + "set": cty.SetValEmpty(cty.Object(map[string]cty.Type{"bar": cty.String})), + }), + cty.ObjectVal(map[string]cty.Value{ + "map": cty.MapValEmpty(cty.Object(map[string]cty.Type{"bar": cty.String})), + "set": cty.SetValEmpty(cty.Object(map[string]cty.Type{"bar": cty.String})), + }), + }, + "optional types set replacement": { + &configschema.Block{ + Attributes: map[string]*configschema.Attribute{ + "set": { + NestedType: &configschema.Object{ + Nesting: configschema.NestingSet, + Attributes: map[string]*configschema.Attribute{ + "bar": { + Type: cty.String, + Required: true, + }, + }, + }, + Optional: true, + }, + }, + }, + cty.ObjectVal(map[string]cty.Value{ + "set": cty.SetVal([]cty.Value{ + cty.ObjectVal(map[string]cty.Value{ + "bar": cty.StringVal("old"), + }), + }), + }), + cty.ObjectVal(map[string]cty.Value{ + "set": cty.SetVal([]cty.Value{ + cty.ObjectVal(map[string]cty.Value{ + "bar": cty.StringVal("new"), + }), + }), + }), + cty.ObjectVal(map[string]cty.Value{ + "set": cty.SetVal([]cty.Value{ + cty.ObjectVal(map[string]cty.Value{ + "bar": cty.StringVal("new"), + }), + }), + }), + }, } for name, test := range tests {