stacks: move destroy deferred handling outside of destroy method

TF-13960
Daniel Schmidt 2 years ago
parent a26fd2e81f
commit c2fe241570
No known key found for this signature in database
GPG Key ID: 377C3A4D62FBBBE2

@ -368,8 +368,9 @@ func (n *NodeAbstractResourceInstance) writeResourceInstanceStateImpl(ctx EvalCo
}
// planDestroy returns a plain destroy diff.
func (n *NodeAbstractResourceInstance) planDestroy(ctx EvalContext, currentState *states.ResourceInstanceObject, deposedKey states.DeposedKey) (*plans.ResourceInstanceChange, tfdiags.Diagnostics) {
func (n *NodeAbstractResourceInstance) planDestroy(ctx EvalContext, currentState *states.ResourceInstanceObject, deposedKey states.DeposedKey) (*plans.ResourceInstanceChange, *providers.Deferred, tfdiags.Diagnostics) {
var diags tfdiags.Diagnostics
var deferred *providers.Deferred
var plan *plans.ResourceInstanceChange
absAddr := n.Addr
@ -400,7 +401,7 @@ func (n *NodeAbstractResourceInstance) planDestroy(ctx EvalContext, currentState
},
ProviderAddr: n.ResolvedProvider,
}
return noop, nil
return noop, deferred, nil
}
unmarkedPriorVal, _ := currentState.Value.UnmarkDeep()
@ -411,13 +412,13 @@ func (n *NodeAbstractResourceInstance) planDestroy(ctx EvalContext, currentState
provider, _, err := getProvider(ctx, n.ResolvedProvider)
if err != nil {
return plan, diags.Append(err)
return plan, deferred, diags.Append(err)
}
metaConfigVal, metaDiags := n.providerMetas(ctx)
diags = diags.Append(metaDiags)
if diags.HasErrors() {
return plan, diags
return plan, deferred, diags
}
var resp providers.PlanResourceChangeResponse
@ -441,6 +442,7 @@ func (n *NodeAbstractResourceInstance) planDestroy(ctx EvalContext, currentState
ProviderMeta: metaConfigVal,
DeferralAllowed: ctx.Deferrals().DeferralAllowed(),
})
deferred = resp.Deferred
// We may not have a config for all destroys, but we want to reference
// it in the diagnostics if we do.
@ -449,19 +451,11 @@ func (n *NodeAbstractResourceInstance) planDestroy(ctx EvalContext, currentState
}
diags = diags.Append(resp.Diagnostics)
if diags.HasErrors() {
return plan, diags
return plan, deferred, diags
}
if resp.Deferred != nil {
ctx.Deferrals().ReportResourceInstanceDeferred(n.Addr, resp.Deferred.Reason, &plans.ResourceInstanceChange{
Addr: n.Addr,
Change: plans.Change{
Action: plans.Delete,
Before: unmarkedPriorVal,
After: resp.PlannedState,
},
})
return plan, diags
return plan, deferred, diags
}
// Check that the provider returned a null value here, since that is the
@ -475,7 +469,7 @@ func (n *NodeAbstractResourceInstance) planDestroy(ctx EvalContext, currentState
n.ResolvedProvider.Provider, n.Addr),
),
)
return plan, diags
return plan, deferred, diags
}
}
@ -493,7 +487,7 @@ func (n *NodeAbstractResourceInstance) planDestroy(ctx EvalContext, currentState
ProviderAddr: n.ResolvedProvider,
}
return plan, diags
return plan, deferred, diags
}
// planForget returns a Forget change.

@ -11,6 +11,7 @@ import (
"github.com/hashicorp/terraform/internal/dag"
"github.com/hashicorp/terraform/internal/instances"
"github.com/hashicorp/terraform/internal/plans"
"github.com/hashicorp/terraform/internal/providers"
"github.com/hashicorp/terraform/internal/states"
"github.com/hashicorp/terraform/internal/tfdiags"
)
@ -161,15 +162,26 @@ func (n *NodePlanDeposedResourceInstanceObject) Execute(ctx EvalContext, op walk
}
var change *plans.ResourceInstanceChange
var pDiags tfdiags.Diagnostics
var deferred *providers.Deferred
if forget {
change, pDiags = n.planForget(ctx, state, n.DeposedKey)
} else {
change, pDiags = n.planDestroy(ctx, state, n.DeposedKey)
change, deferred, pDiags = n.planDestroy(ctx, state, n.DeposedKey)
}
diags = diags.Append(pDiags)
if diags.HasErrors() {
return diags
}
if deferred != nil {
ctx.Deferrals().ReportResourceInstanceDeferred(n.Addr, deferred.Reason, &plans.ResourceInstanceChange{
Addr: n.Addr,
Change: plans.Change{
Action: plans.Delete,
Before: state.Value,
},
})
return diags
}
// NOTE: We don't check prevent_destroy for deposed objects, even
// though we would do so here for a "current" object, because
@ -275,12 +287,23 @@ func (n *NodeDestroyDeposedResourceInstanceObject) Execute(ctx EvalContext, op w
return diags
}
change, destroyPlanDiags := n.planDestroy(ctx, state, n.DeposedKey)
change, deferred, destroyPlanDiags := n.planDestroy(ctx, state, n.DeposedKey)
diags = diags.Append(destroyPlanDiags)
if diags.HasErrors() {
return diags
}
if deferred != nil {
ctx.Deferrals().ReportResourceInstanceDeferred(n.Addr, deferred.Reason, &plans.ResourceInstanceChange{
Addr: n.Addr,
Change: plans.Change{
Action: plans.Delete,
Before: state.Value,
},
})
return diags
}
// Call pre-apply hook
diags = diags.Append(n.preApplyHook(ctx, change))
if diags.HasErrors() {

@ -90,12 +90,23 @@ func (n *NodePlanDestroyableResourceInstance) managedResourceExecute(ctx EvalCon
}
}
change, destroyPlanDiags := n.planDestroy(ctx, state, "")
change, deferred, destroyPlanDiags := n.planDestroy(ctx, state, "")
diags = diags.Append(destroyPlanDiags)
if diags.HasErrors() {
return diags
}
if deferred != nil {
ctx.Deferrals().ReportResourceInstanceDeferred(n.Addr, deferred.Reason, &plans.ResourceInstanceChange{
Addr: n.Addr,
Change: plans.Change{
Action: plans.Delete,
Before: state.Value,
},
})
return diags
}
// We intentionally write the change before the subsequent checks, because
// all of the checks below this point are for problems caused by the
// context surrounding the change, rather than the change itself, and

@ -9,6 +9,7 @@ import (
"github.com/hashicorp/terraform/internal/addrs"
"github.com/hashicorp/terraform/internal/plans"
"github.com/hashicorp/terraform/internal/providers"
"github.com/hashicorp/terraform/internal/states"
"github.com/hashicorp/terraform/internal/tfdiags"
)
@ -164,13 +165,22 @@ func (n *NodePlannableResourceInstanceOrphan) managedResourceExecute(ctx EvalCon
}
var change *plans.ResourceInstanceChange
var pDiags tfdiags.Diagnostics
var deferred *providers.Deferred
if forget {
change, pDiags = n.planForget(ctx, oldState, "")
diags = diags.Append(pDiags)
} else {
change, pDiags = n.planDestroy(ctx, oldState, "")
change, deferred, pDiags = n.planDestroy(ctx, oldState, "")
diags = diags.Append(pDiags)
if diags.HasErrors() {
if deferred != nil {
ctx.Deferrals().ReportResourceInstanceDeferred(n.Addr, deferred.Reason, &plans.ResourceInstanceChange{
Addr: n.Addr,
Change: plans.Change{
Action: plans.Delete,
Before: oldState.Value,
},
})
return diags
}
}
@ -181,10 +191,7 @@ func (n *NodePlannableResourceInstanceOrphan) managedResourceExecute(ctx EvalCon
// We might be able to offer an approximate reason for why we are
// planning to delete this object. (This is best-effort; we might
// sometimes not have a reason.)
// The change can be nil in case of deferred destroys.
if change != nil {
change.ActionReason = n.deleteActionReason(ctx)
}
change.ActionReason = n.deleteActionReason(ctx)
// We intentionally write the change before the subsequent checks, because
// all of the checks below this point are for problems caused by the

Loading…
Cancel
Save