Skip to content

Commit 1ec74c7

Browse files
handle providers deferring action invocations
1 parent 741d7f3 commit 1ec74c7

File tree

4 files changed

+437
-27
lines changed

4 files changed

+437
-27
lines changed

internal/plans/action_invocation.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,10 @@ type ActionTrigger interface {
4040
Less(other ActionTrigger) bool
4141
}
4242

43+
var (
44+
_ ActionTrigger = (*LifecycleActionTrigger)(nil)
45+
)
46+
4347
type LifecycleActionTrigger struct {
4448
TriggeringResourceAddr addrs.AbsResourceInstance
4549
// Information about the trigger

internal/plans/deferring/deferred.go

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -658,6 +658,45 @@ func (d *Deferred) ReportActionInvocationDeferred(ai plans.ActionInvocationInsta
658658
})
659659
}
660660

661+
// ShouldDeferActionInvocation returns true if there is a reason to defer the action invocation instance
662+
// We want to defer an action invocation if
663+
// a) the resource was deferred
664+
// or
665+
// b) a previously run action was deferred
666+
func (d *Deferred) ShouldDeferActionInvocation(ai plans.ActionInvocationInstance) bool {
667+
d.mu.Lock()
668+
defer d.mu.Unlock()
669+
670+
// We only want to defer actions that are lifecycle triggered
671+
at, ok := ai.ActionTrigger.(plans.LifecycleActionTrigger)
672+
if !ok {
673+
return false
674+
}
675+
676+
// If the resource was deferred, we also need to defer any action potentially triggering from this
677+
if configResourceMap, ok := d.resourceInstancesDeferred.GetOk(at.TriggeringResourceAddr.ConfigResource()); ok {
678+
if configResourceMap.Has(at.TriggeringResourceAddr) {
679+
return true
680+
}
681+
}
682+
683+
// Since all actions plan in order we can just check if an action for this resource instance
684+
// has been deferred already
685+
for _, deferred := range d.actionInvocationDeferred {
686+
deferredAt, deferredOk := deferred.ActionInvocationInstance.ActionTrigger.(plans.LifecycleActionTrigger)
687+
if !deferredOk {
688+
continue // We only care about lifecycle triggered actions here
689+
}
690+
691+
if deferredAt.TriggeringResourceAddr.Equal(at.TriggeringResourceAddr) {
692+
return true
693+
}
694+
}
695+
696+
// We found no reason, so we return false
697+
return false
698+
}
699+
661700
// UnexpectedProviderDeferralDiagnostic is a diagnostic that indicates that a
662701
// provider was deferred although deferrals were not allowed.
663702
func UnexpectedProviderDeferralDiagnostic(addrs fmt.Stringer) tfdiags.Diagnostic {

0 commit comments

Comments
 (0)