terraform/internal/terraform/node_resource_plan_destroy.go

88 lines
3.0 KiB
Go

package terraform
import (
"github.com/hashicorp/terraform/internal/addrs"
"github.com/hashicorp/terraform/internal/plans"
"github.com/hashicorp/terraform/internal/states"
"github.com/hashicorp/terraform/internal/tfdiags"
)
// NodePlanDestroyableResourceInstance represents a resource that is ready
// to be planned for destruction.
type NodePlanDestroyableResourceInstance struct {
*NodeAbstractResourceInstance
// skipRefresh indicates that we should skip refreshing
skipRefresh bool
}
var (
_ GraphNodeModuleInstance = (*NodePlanDestroyableResourceInstance)(nil)
_ GraphNodeReferenceable = (*NodePlanDestroyableResourceInstance)(nil)
_ GraphNodeReferencer = (*NodePlanDestroyableResourceInstance)(nil)
_ GraphNodeDestroyer = (*NodePlanDestroyableResourceInstance)(nil)
_ GraphNodeConfigResource = (*NodePlanDestroyableResourceInstance)(nil)
_ GraphNodeResourceInstance = (*NodePlanDestroyableResourceInstance)(nil)
_ GraphNodeAttachResourceConfig = (*NodePlanDestroyableResourceInstance)(nil)
_ GraphNodeAttachResourceState = (*NodePlanDestroyableResourceInstance)(nil)
_ GraphNodeExecutable = (*NodePlanDestroyableResourceInstance)(nil)
_ GraphNodeProviderConsumer = (*NodePlanDestroyableResourceInstance)(nil)
)
// GraphNodeDestroyer
func (n *NodePlanDestroyableResourceInstance) DestroyAddr() *addrs.AbsResourceInstance {
addr := n.ResourceInstanceAddr()
return &addr
}
// GraphNodeEvalable
func (n *NodePlanDestroyableResourceInstance) Execute(ctx EvalContext, op walkOperation) (diags tfdiags.Diagnostics) {
addr := n.ResourceInstanceAddr()
// Declare a bunch of variables that are used for state during
// evaluation. These are written to by address in the EvalNodes we
// declare below.
var change *plans.ResourceInstanceChange
var state *states.ResourceInstanceObject
state, err := n.readResourceInstanceState(ctx, addr)
diags = diags.Append(err)
if diags.HasErrors() {
return diags
}
// If we are in the "skip refresh" mode then we will have skipped over our
// usual opportunity to update the previous run state and refresh state
// with the result of any provider schema upgrades, so we'll compensate
// by doing that here.
//
// NOTE: this is coupled with logic in Context.destroyPlan which skips
// running a normal plan walk when refresh is enabled. These two
// conditionals must agree (be exactly opposite) in order to get the
// correct behavior in both cases.
if n.skipRefresh {
diags = diags.Append(n.writeResourceInstanceState(ctx, state, prevRunState))
if diags.HasErrors() {
return diags
}
diags = diags.Append(n.writeResourceInstanceState(ctx, state, refreshState))
if diags.HasErrors() {
return diags
}
}
change, destroyPlanDiags := n.planDestroy(ctx, state, "")
diags = diags.Append(destroyPlanDiags)
if diags.HasErrors() {
return diags
}
diags = diags.Append(n.checkPreventDestroy(change))
if diags.HasErrors() {
return diags
}
diags = diags.Append(n.writeChange(ctx, change, ""))
return diags
}