Skip to content

Commit

Permalink
do not create delete change for nonexistent output
Browse files Browse the repository at this point in the history
If there are outputs in configuration, a destroy plan will always contain a "delete" change for each of these outputs.

This leads to meaningless delete changes being present for outputs which were not present in state and therefore cannot be deleted. Since there is a change in the plan, this plan will then be considered applyable, and the user will be presented with text instructing them to apply a plan in which there are no actual changes.

This commit stops the above from happening in the case of root module outputs.
  • Loading branch information
kmoe committed Jul 19, 2022
1 parent 7b4a551 commit 3081083
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 8 deletions.
17 changes: 10 additions & 7 deletions internal/terraform/node_output.go
Expand Up @@ -5,6 +5,8 @@ import (
"log"

"github.com/hashicorp/hcl/v2"
"github.com/zclconf/go-cty/cty"

"github.com/hashicorp/terraform/internal/addrs"
"github.com/hashicorp/terraform/internal/configs"
"github.com/hashicorp/terraform/internal/dag"
Expand All @@ -13,7 +15,6 @@ import (
"github.com/hashicorp/terraform/internal/plans"
"github.com/hashicorp/terraform/internal/states"
"github.com/hashicorp/terraform/internal/tfdiags"
"github.com/zclconf/go-cty/cty"
)

// nodeExpandOutput is the placeholder for a non-root module output that has
Expand Down Expand Up @@ -413,12 +414,14 @@ func (n *NodeDestroyableOutput) Execute(ctx EvalContext, op walkOperation) tfdia
before := cty.NullVal(cty.DynamicPseudoType)
mod := state.Module(n.Addr.Module)
if n.Addr.Module.IsRoot() && mod != nil {
for name, o := range mod.OutputValues {
if name == n.Addr.OutputValue.Name {
sensitiveBefore = o.Sensitive
before = o.Value
break
}
if o, ok := mod.OutputValues[n.Addr.OutputValue.Name]; ok {
sensitiveBefore = o.Sensitive
before = o.Value
} else {
// If the output was not in state, a delete change would
// be meaningless, so exit early.
return nil

}
}

Expand Down
22 changes: 21 additions & 1 deletion internal/terraform/node_output_test.go
Expand Up @@ -5,11 +5,12 @@ import (
"testing"

"github.com/hashicorp/hcl/v2"
"github.com/zclconf/go-cty/cty"

"github.com/hashicorp/terraform/internal/addrs"
"github.com/hashicorp/terraform/internal/configs"
"github.com/hashicorp/terraform/internal/lang/marks"
"github.com/hashicorp/terraform/internal/states"
"github.com/zclconf/go-cty/cty"
)

func TestNodeApplyableOutputExecute_knownValue(t *testing.T) {
Expand Down Expand Up @@ -160,3 +161,22 @@ func TestNodeDestroyableOutputExecute(t *testing.T) {
t.Fatal("Unexpected outputs in state after removal")
}
}

func TestNodeDestroyableOutputExecute_notInState(t *testing.T) {
outputAddr := addrs.OutputValue{Name: "foo"}.Absolute(addrs.RootModuleInstance)

state := states.NewState()

ctx := &MockEvalContext{
StateState: state.SyncWrapper(),
}
node := NodeDestroyableOutput{Addr: outputAddr}

diags := node.Execute(ctx, walkApply)
if diags.HasErrors() {
t.Fatalf("Unexpected error: %s", diags.Err())
}
if state.OutputValue(outputAddr) != nil {
t.Fatal("Unexpected outputs in state after removal")
}
}

0 comments on commit 3081083

Please sign in to comment.