From 4d30924de858d3f32a5763f819a92e612614f8dc Mon Sep 17 00:00:00 2001 From: Daniel Schmidt Date: Fri, 5 Apr 2024 23:44:17 +0200 Subject: [PATCH] stacks: check if resource instance is deferred before marking it as deferred --- internal/plans/deferring/deferred.go | 19 ++++++++++++++++++- .../terraform/node_resource_plan_instance.go | 9 +++++++-- 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/internal/plans/deferring/deferred.go b/internal/plans/deferring/deferred.go index 5fa0153cda7c..76ec14e2b574 100644 --- a/internal/plans/deferring/deferred.go +++ b/internal/plans/deferring/deferred.go @@ -177,6 +177,22 @@ func (d *Deferred) HaveAnyDeferrals() bool { len(d.partialExpandedModulesDeferred) != 0) } +// IsResourceInstanceDeferred returns true if the receiver knows some reason +// why the resource instance with the given address should have its planned +// action deferred for a future plan/apply round. +func (d *Deferred) IsResourceInstanceDeferred(addr addrs.AbsResourceInstance) bool { + if d.externalDependencyDeferred { + return true + } + + // Our resource graph describes relationships between the static resource + // configuration blocks, not their dynamic instances, so we need to start + // with the config address that the given instance belongs to. + configAddr := addr.ConfigResource() + + return d.resourceInstancesDeferred.Get(configAddr).Has(addr) +} + // ShouldDeferResourceInstanceChanges returns true if the receiver knows some // reason why the resource instance with the given address should have its // planned action deferred for a future plan/apply round. @@ -196,7 +212,8 @@ func (d *Deferred) HaveAnyDeferrals() bool { // It's invalid to call this method for an address that was already reported // as deferred using [Deferred.ReportResourceInstanceDeferred], and so this // method will panic in that case. Callers should always test whether a resource -// instance action should be deferred _before_ reporting that it has been. +// instance action should be deferred _before_ reporting that it has been by calling +// [Deferred.IsResourceInstanceDeferred]. func (d *Deferred) ShouldDeferResourceInstanceChanges(addr addrs.AbsResourceInstance) bool { if d.externalDependencyDeferred { // This is an easy case: _all_ actions must be deferred. diff --git a/internal/terraform/node_resource_plan_instance.go b/internal/terraform/node_resource_plan_instance.go index 2bc635da9aa0..ded687f2630b 100644 --- a/internal/terraform/node_resource_plan_instance.go +++ b/internal/terraform/node_resource_plan_instance.go @@ -298,7 +298,12 @@ func (n *NodePlannableResourceInstance) managedResourceExecute(ctx EvalContext) } deferrals := ctx.Deferrals() - if !deferrals.ShouldDeferResourceInstanceChanges(n.Addr) { + + if deferrals.IsResourceInstanceDeferred(n.Addr) { + // This resource instance is already deferred, so we don't need to + // do anything else with it here. + fmt.Println("SKIPID") + } else if !deferrals.ShouldDeferResourceInstanceChanges(n.Addr) { // 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 @@ -614,7 +619,7 @@ func (n *NodePlannableResourceInstance) importState(ctx EvalContext, addr addrs. } // verify the existence of the imported resource - if instanceRefreshState.Value.IsNull() { + if instanceRefreshState.Value.IsNull() && deferred == nil { var diags tfdiags.Diagnostics diags = diags.Append(tfdiags.Sourceless( tfdiags.Error,