mirror of
https://github.com/opentofu/opentofu.git
synced 2025-02-25 18:45:20 -06:00
core: EvalDiff must handle Create/Replace as a special case
When we re-run EvalDiff during apply, we may have already completed the destroy leg of a replace operation, leaving us in a different situation than we were when we made the original planned change. Therefore as a special case we will allow a create to turn back into a replace if there was an earlier diff that requested that.
This commit is contained in:
parent
dea74f9048
commit
e9e11955a8
@ -331,6 +331,21 @@ func (n *EvalDiff) Eval(ctx EvalContext) (interface{}, error) {
|
||||
priorVal = priorValTainted
|
||||
}
|
||||
|
||||
// As a special case, if we have a previous diff (presumably from the plan
|
||||
// phases, whereas we're now in the apply phase) and it was for a replace,
|
||||
// we've already deleted the original object from state by the time we
|
||||
// get here and so we would've ended up with a _create_ action this time,
|
||||
// which we now need to paper over to get a result consistent with what
|
||||
// we originally intended.
|
||||
if n.PreviousDiff != nil {
|
||||
prevChange := *n.PreviousDiff
|
||||
if prevChange.Action == plans.Replace && action == plans.Create {
|
||||
log.Printf("[TRACE] EvalDiff: %s treating Create change as Replace change to match with earlier plan", absAddr)
|
||||
action = plans.Replace
|
||||
priorVal = prevChange.Before
|
||||
}
|
||||
}
|
||||
|
||||
// Call post-refresh hook
|
||||
if !n.Stub {
|
||||
err := ctx.Hook(func(h Hook) (HookAction, error) {
|
||||
|
@ -260,6 +260,13 @@ func (n *NodeApplyableResourceInstance) evalTreeManagedResource(addr addrs.AbsRe
|
||||
Output: &state,
|
||||
},
|
||||
|
||||
// Get the saved diff
|
||||
&EvalReadDiff{
|
||||
Addr: addr.Resource,
|
||||
ProviderSchema: &providerSchema,
|
||||
Change: &diff,
|
||||
},
|
||||
|
||||
// Make a new diff, in case we've learned new values in the state
|
||||
// during apply which we can now incorporate.
|
||||
&EvalDiff{
|
||||
@ -269,18 +276,12 @@ func (n *NodeApplyableResourceInstance) evalTreeManagedResource(addr addrs.AbsRe
|
||||
ProviderAddr: n.ResolvedProvider,
|
||||
ProviderSchema: &providerSchema,
|
||||
State: &state,
|
||||
PreviousDiff: &diff,
|
||||
OutputChange: &diffApply,
|
||||
OutputValue: &configVal,
|
||||
OutputState: &state,
|
||||
},
|
||||
|
||||
// Get the saved diff
|
||||
&EvalReadDiff{
|
||||
Addr: addr.Resource,
|
||||
ProviderSchema: &providerSchema,
|
||||
Change: &diff,
|
||||
},
|
||||
|
||||
// Compare the diffs
|
||||
&EvalCheckPlannedChange{
|
||||
Addr: addr.Resource,
|
||||
@ -389,10 +390,21 @@ func (n *NodeApplyableResourceInstance) evalTreeManagedResource(addr addrs.AbsRe
|
||||
// We clear the diff out here so that future nodes
|
||||
// don't see a diff that is already complete. There
|
||||
// is no longer a diff!
|
||||
&EvalWriteDiff{
|
||||
Addr: addr.Resource,
|
||||
ProviderSchema: &providerSchema,
|
||||
Change: nil,
|
||||
&EvalIf{
|
||||
If: func(ctx EvalContext) (bool, error) {
|
||||
if diff.Action != plans.Replace {
|
||||
return true, nil
|
||||
}
|
||||
if !n.createBeforeDestroy() {
|
||||
return true, nil
|
||||
}
|
||||
return false, nil
|
||||
},
|
||||
Then: &EvalWriteDiff{
|
||||
Addr: addr.Resource,
|
||||
ProviderSchema: &providerSchema,
|
||||
Change: nil,
|
||||
},
|
||||
},
|
||||
|
||||
&EvalApplyPost{
|
||||
|
Loading…
Reference in New Issue
Block a user