account for noop deposed instances in json plan

When rendering a json plan, we need to account for deposed instances
that have become a noop rather than a destroy.
This commit is contained in:
James Bardin 2021-06-09 17:57:14 -04:00
parent ce638c9231
commit 09c33fa449
2 changed files with 52 additions and 3 deletions

View File

@ -11,6 +11,7 @@ import (
"github.com/hashicorp/terraform/internal/addrs"
"github.com/hashicorp/terraform/internal/configs/configschema"
"github.com/hashicorp/terraform/internal/plans"
"github.com/hashicorp/terraform/internal/states"
"github.com/hashicorp/terraform/internal/terraform"
)
@ -93,8 +94,10 @@ func marshalPlannedValues(changes *plans.Changes, schemas *terraform.Schemas) (m
seenModules := make(map[string]bool)
for _, resource := range changes.Resources {
// if the resource is being deleted, skip over it.
if resource.Action != plans.Delete {
// If the resource is being deleted, skip over it.
// Deposed instances are always conceptually a destroy, but if they
// were gone during refresh then the change becomes a noop.
if resource.Action != plans.Delete && resource.DeposedKey == states.NotDeposed {
containingModule := resource.Addr.Module.String()
moduleResourceMap[containingModule] = append(moduleResourceMap[containingModule], resource.Addr)

View File

@ -204,13 +204,26 @@ func TestMarshalPlanResources(t *testing.T) {
}},
Err: false,
},
"delete": {
"delete with null and nil": {
Action: plans.Delete,
Before: cty.NullVal(cty.EmptyObject),
After: cty.NilVal,
Want: nil,
Err: false,
},
"delete": {
Action: plans.Delete,
Before: cty.ObjectVal(map[string]cty.Value{
"woozles": cty.StringVal("foo"),
"foozles": cty.StringVal("bar"),
}),
After: cty.NullVal(cty.Object(map[string]cty.Type{
"woozles": cty.String,
"foozles": cty.String,
})),
Want: nil,
Err: false,
},
"update without unknowns": {
Action: plans.Update,
Before: cty.ObjectVal(map[string]cty.Value{
@ -291,6 +304,39 @@ func TestMarshalPlanResources(t *testing.T) {
}
}
func TestMarshalPlanValuesNoopDeposed(t *testing.T) {
dynamicNull, err := plans.NewDynamicValue(cty.NullVal(cty.DynamicPseudoType), cty.DynamicPseudoType)
if err != nil {
t.Fatal(err)
}
testChange := &plans.Changes{
Resources: []*plans.ResourceInstanceChangeSrc{
{
Addr: addrs.Resource{
Mode: addrs.ManagedResourceMode,
Type: "test_thing",
Name: "example",
}.Instance(addrs.NoKey).Absolute(addrs.RootModuleInstance),
DeposedKey: "12345678",
ProviderAddr: addrs.AbsProviderConfig{
Provider: addrs.NewDefaultProvider("test"),
Module: addrs.RootModule,
},
ChangeSrc: plans.ChangeSrc{
Action: plans.NoOp,
Before: dynamicNull,
After: dynamicNull,
},
},
},
}
_, err = marshalPlannedValues(testChange, testSchemas())
if err != nil {
t.Fatal(err)
}
}
func testSchemas() *terraform.Schemas {
return &terraform.Schemas{
Providers: map[addrs.Provider]*terraform.ProviderSchema{