Skip to content

Commit 1f65100

Browse files
all types of action deferrals should lead to deferred triggering resources
1 parent 0174a2f commit 1f65100

File tree

2 files changed

+37
-8
lines changed

2 files changed

+37
-8
lines changed

internal/terraform/context_plan_actions_test.go

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2824,6 +2824,14 @@ resource "test_object" "a" {
28242824
if ai.Addr.String() != `action.test_unlinked.hello["a"]` {
28252825
t.Fatalf(`expected action invocation for action.test_unlinked.hello["a"], got %s`, ai.Addr.String())
28262826
}
2827+
2828+
if len(p.DeferredResources) != 1 {
2829+
t.Fatalf("expected 1 deferred resource, got %d", len(p.DeferredResources))
2830+
}
2831+
2832+
if p.DeferredResources[0].ChangeSrc.Addr.String() != "test_object.a" {
2833+
t.Fatalf("expected test_object.a, got %s", p.DeferredResources[0].ChangeSrc.Addr.String())
2834+
}
28272835
},
28282836
},
28292837
"action with unknown module expansion": {
@@ -3020,11 +3028,27 @@ resource "test_object" "a" {
30203028
t.Errorf("Expected 1 deferred action invocation, got %d", len(p.DeferredActionInvocations))
30213029
}
30223030
if p.DeferredActionInvocations[0].ActionInvocationInstanceSrc.Addr.String() != "action.test_unlinked.hello" {
3023-
t.Errorf("Expected action.test_unlinked.hello, got %s", p.DeferredActionInvocations[0].ActionInvocationInstanceSrc.Addr.String())
3031+
t.Errorf("Expected action. test_unlinked.hello, got %s", p.DeferredActionInvocations[0].ActionInvocationInstanceSrc.Addr.String())
30243032
}
30253033
if p.DeferredActionInvocations[0].DeferredReason != providers.DeferredReasonDeferredPrereq {
30263034
t.Errorf("Expected DeferredReasonDeferredPrereq, got %s", p.DeferredActionInvocations[0].DeferredReason)
30273035
}
3036+
3037+
if len(p.DeferredResources) != 2 {
3038+
t.Fatalf("Expected 2 deferred resources, got %d", len(p.DeferredResources))
3039+
}
3040+
if p.DeferredResources[0].ChangeSrc.Addr.String() != "test_object.origin" {
3041+
t.Errorf("Expected test_object.origin, got %s", p.DeferredResources[0].ChangeSrc.Addr.String())
3042+
}
3043+
if p.DeferredResources[0].DeferredReason != providers.DeferredReasonAbsentPrereq {
3044+
t.Errorf("Expected DeferredReasonAbsentPrereq, got %s", p.DeferredResources[0].DeferredReason)
3045+
}
3046+
if p.DeferredResources[1].ChangeSrc.Addr.String() != "test_object.a" {
3047+
t.Errorf("Expected test_object.a, got %s", p.DeferredResources[1].ChangeSrc.Addr.String())
3048+
}
3049+
if p.DeferredResources[1].DeferredReason != providers.DeferredReasonDeferredPrereq {
3050+
t.Errorf("Expected DeferredReasonDeferredPrereq, got %s", p.DeferredResources[1].DeferredReason)
3051+
}
30283052
},
30293053
},
30303054
} {

internal/terraform/node_action_trigger_instance_plan.go

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -76,12 +76,23 @@ func (n *nodeActionTriggerPlanInstance) Execute(ctx EvalContext, operation walkO
7676

7777
ActionTrigger: n.lifecycleActionTrigger.ActionTrigger(configs.Unknown),
7878
}
79+
change := ctx.Changes().GetResourceInstanceChange(n.lifecycleActionTrigger.resourceAddress, n.lifecycleActionTrigger.resourceAddress.CurrentObject().DeposedKey)
7980

81+
// If we should defer the action invocation, we need to report it and if the resource instance
82+
// was not deferred (and therefore was planned) we need to retroactively remove the change
8083
if deferrals.ShouldDeferActionInvocation(ai) {
8184
deferrals.ReportActionInvocationDeferred(ai, providers.DeferredReasonDeferredPrereq)
85+
if change != nil {
86+
ctx.Changes().RemoveResourceInstanceChange(change.Addr, change.Addr.CurrentObject().DeposedKey)
87+
deferrals.ReportResourceInstanceDeferred(change.Addr, providers.DeferredReasonDeferredPrereq, change)
88+
}
8289
return nil
8390
}
8491

92+
if change == nil {
93+
panic("change cannot be nil")
94+
}
95+
8596
if n.lifecycleActionTrigger == nil {
8697
panic("Only actions triggered by plan and apply are supported")
8798
}
@@ -102,10 +113,6 @@ func (n *nodeActionTriggerPlanInstance) Execute(ctx EvalContext, operation walkO
102113
// provider so we'll do that ourselves now.
103114
ai.ConfigValue = ephemeral.RemoveEphemeralValues(actionInstance.ConfigValue)
104115

105-
change := ctx.Changes().GetResourceInstanceChange(n.lifecycleActionTrigger.resourceAddress, n.lifecycleActionTrigger.resourceAddress.CurrentObject().DeposedKey)
106-
if change == nil {
107-
panic("change cannot be nil")
108-
}
109116
triggeringEvent, isTriggered := actionIsTriggeredByEvent(n.lifecycleActionTrigger.events, change.Action)
110117
if !isTriggered {
111118
return diags
@@ -180,11 +187,9 @@ func (n *nodeActionTriggerPlanInstance) Execute(ctx EvalContext, operation walkO
180187
return diags
181188
}
182189

190+
// If the action is deferred, we need to also defer the resource instance
183191
if resp.Deferred != nil {
184192
deferrals.ReportActionInvocationDeferred(ai, resp.Deferred.Reason)
185-
186-
// If we run as part of a before action we need to retrospectively defer the triggering resource
187-
// For this we remove the change and report the deferral
188193
ctx.Changes().RemoveResourceInstanceChange(change.Addr, change.Addr.CurrentObject().DeposedKey)
189194
deferrals.ReportResourceInstanceDeferred(change.Addr, providers.DeferredReasonDeferredPrereq, change)
190195
return diags

0 commit comments

Comments
 (0)