apply the stored plan CreateThenDelete action

When applying a plan, a forced CreateBeforeDestroy may not be set during
the apply walk when downstream resources are no longer present in the
graph. We still need to stick to that plan, and both the
NodeApplyableResourceInstance EvalTree and the individual Eval nodes
need to operate on that planned value.

Ensure that we always check for an existing plan when determining
CreateBeforeDestroy status. This must happen in 2 different code paths
due to the eval node pattern currently in-use. Future refactoring may be
able to unify these code-paths to make this less fragile.
This commit is contained in:
James Bardin 2020-09-09 17:02:28 -04:00
parent 7695d1cefe
commit ec231c7616
2 changed files with 13 additions and 2 deletions

View File

@ -130,6 +130,12 @@ func (n *EvalDiff) Eval(ctx EvalContext) (interface{}, error) {
provider := *n.Provider
providerSchema := *n.ProviderSchema
createBeforeDestroy := n.CreateBeforeDestroy
if n.PreviousDiff != nil {
// If we already planned the action, we stick to that plan
createBeforeDestroy = (*n.PreviousDiff).Action == plans.CreateThenDelete
}
if providerSchema == nil {
return nil, fmt.Errorf("provider schema is unavailable for %s", n.Addr)
}
@ -384,7 +390,7 @@ func (n *EvalDiff) Eval(ctx EvalContext) (interface{}, error) {
case !reqRep.Empty():
// If there are any "requires replace" paths left _after our filtering
// above_ then this is a replace action.
if n.CreateBeforeDestroy {
if createBeforeDestroy {
action = plans.CreateThenDelete
} else {
action = plans.DeleteThenCreate
@ -450,7 +456,7 @@ func (n *EvalDiff) Eval(ctx EvalContext) (interface{}, error) {
// as a replace change, even though so far we've been treating it as a
// create.
if action == plans.Create && priorValTainted != cty.NilVal {
if n.CreateBeforeDestroy {
if createBeforeDestroy {
action = plans.CreateThenDelete
} else {
action = plans.DeleteThenCreate

View File

@ -263,10 +263,15 @@ func (n *NodeApplyableResourceInstance) evalTreeManagedResource(addr addrs.AbsRe
destroy := false
if diffApply != nil {
destroy = (diffApply.Action == plans.Delete || diffApply.Action.IsReplace())
// Get the stored action for CBD if we have a plan already
createBeforeDestroyEnabled = diffApply.Change.Action == plans.CreateThenDelete
}
if destroy && n.CreateBeforeDestroy() {
createBeforeDestroyEnabled = true
}
return createBeforeDestroyEnabled, nil
},
Then: &EvalDeposeState{