diff --git a/command/format/diff.go b/command/format/diff.go index f72f7be6d..0f5ecab24 100644 --- a/command/format/diff.go +++ b/command/format/diff.go @@ -496,7 +496,9 @@ func (p *blockBodyDiffPrinter) writeValue(val cty.Value, action plans.Action, in // Special behavior for JSON strings containing array or object src := []byte(val.AsString()) ty, err := ctyjson.ImpliedType(src) - if err == nil && !ty.IsPrimitiveType() { + // check for the special case of "null", which decodes to nil, + // and just allow it to be printed out directly + if err == nil && !ty.IsPrimitiveType() && val.AsString() != "null" { jv, err := ctyjson.Unmarshal(src, ty) if err == nil { p.buf.WriteString("jsonencode(") diff --git a/command/format/diff_test.go b/command/format/diff_test.go index 93d9b8cb0..7b86bdd21 100644 --- a/command/format/diff_test.go +++ b/command/format/diff_test.go @@ -30,6 +30,26 @@ func TestResourceChange_primitiveTypes(t *testing.T) { + resource "test_instance" "example" { + id = (known after apply) } +`, + }, + "creation (null string)": { + Action: plans.Create, + Mode: addrs.ManagedResourceMode, + Before: cty.NullVal(cty.EmptyObject), + After: cty.ObjectVal(map[string]cty.Value{ + "string": cty.StringVal("null"), + }), + Schema: &configschema.Block{ + Attributes: map[string]*configschema.Attribute{ + "string": {Type: cty.String, Optional: true}, + }, + }, + RequiredReplace: cty.NewPathSet(), + Tainted: false, + ExpectedOutput: ` # test_instance.example will be created + + resource "test_instance" "example" { + + string = "null" + } `, }, "deletion": {