Skip to content

Commit 24d01e3

Browse files
stacks: follow component progress cycle for empty destroys
We expect a component instances to report its plan/apply starting and ending as well as reporting the progress / result. This should also be the case for no-ops like an empty component instance.
1 parent f912f6b commit 24d01e3

File tree

2 files changed

+42
-3
lines changed

2 files changed

+42
-3
lines changed

internal/stacks/stackruntime/apply_destroy_test.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1718,6 +1718,18 @@ func TestApplyDestroy(t *testing.T) {
17181718
InstanceAddrs: []stackaddrs.AbsComponentInstance{mustAbsComponentInstance("component.self")},
17191719
},
17201720
},
1721+
PendingComponentInstancePlan: collections.NewSet[stackaddrs.AbsComponentInstance](
1722+
mustAbsComponentInstance("component.self"),
1723+
),
1724+
BeginComponentInstancePlan: collections.NewSet[stackaddrs.AbsComponentInstance](
1725+
mustAbsComponentInstance("component.self"),
1726+
),
1727+
EndComponentInstancePlan: collections.NewSet[stackaddrs.AbsComponentInstance](
1728+
mustAbsComponentInstance("component.self"),
1729+
),
1730+
ReportComponentInstancePlanned: []*hooks.ComponentInstanceChange{{
1731+
Addr: mustAbsComponentInstance("component.self"),
1732+
}},
17211733
},
17221734
wantAppliedHooks: &ExpectedHooks{
17231735
ComponentExpanded: []*hooks.ComponentInstances{
@@ -1726,6 +1738,18 @@ func TestApplyDestroy(t *testing.T) {
17261738
InstanceAddrs: []stackaddrs.AbsComponentInstance{mustAbsComponentInstance("component.self")},
17271739
},
17281740
},
1741+
PendingComponentInstanceApply: collections.NewSet[stackaddrs.AbsComponentInstance](
1742+
mustAbsComponentInstance("component.self"),
1743+
),
1744+
BeginComponentInstanceApply: collections.NewSet[stackaddrs.AbsComponentInstance](
1745+
mustAbsComponentInstance("component.self"),
1746+
),
1747+
EndComponentInstanceApply: collections.NewSet[stackaddrs.AbsComponentInstance](
1748+
mustAbsComponentInstance("component.self"),
1749+
),
1750+
ReportComponentInstanceApplied: []*hooks.ComponentInstanceChange{{
1751+
Addr: mustAbsComponentInstance("component.self"),
1752+
}},
17291753
},
17301754
},
17311755
},

internal/stacks/stackruntime/internal/stackeval/component_instance.go

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import (
2222
"github.com/hashicorp/terraform/internal/providers"
2323
"github.com/hashicorp/terraform/internal/stacks/stackaddrs"
2424
"github.com/hashicorp/terraform/internal/stacks/stackplan"
25+
"github.com/hashicorp/terraform/internal/stacks/stackruntime/hooks"
2526
"github.com/hashicorp/terraform/internal/stacks/stackstate"
2627
"github.com/hashicorp/terraform/internal/states"
2728
"github.com/hashicorp/terraform/internal/terraform"
@@ -192,6 +193,7 @@ func (c *ComponentInstance) CheckModuleTreePlan(ctx context.Context) (*plans.Pla
192193
ctx, c.tracingName()+" modules", &c.moduleTreePlan,
193194
func(ctx context.Context) (*plans.Plan, tfdiags.Diagnostics) {
194195
var diags tfdiags.Diagnostics
196+
h := hooksFromContext(ctx)
195197

196198
if c.mode == plans.DestroyMode {
197199

@@ -203,7 +205,13 @@ func (c *ComponentInstance) CheckModuleTreePlan(ctx context.Context) (*plans.Pla
203205
// and never applied, or that it was previously destroyed
204206
// via an earlier destroy operation.
205207
//
206-
// Return a dummy plan:
208+
// Return a dummy plan and send dummy events:
209+
hookSingle(ctx, h.PendingComponentInstancePlan, c.Addr())
210+
seq, ctx := hookBegin(ctx, h.BeginComponentInstancePlan, h.ContextAttach, c.Addr())
211+
hookMore(ctx, seq, h.ReportComponentInstancePlanned, &hooks.ComponentInstanceChange{
212+
Addr: c.Addr(),
213+
})
214+
hookMore(ctx, seq, h.EndComponentInstancePlan, c.Addr())
207215
return &plans.Plan{
208216
UIMode: plans.DestroyMode,
209217
Complete: true,
@@ -220,7 +228,6 @@ func (c *ComponentInstance) CheckModuleTreePlan(ctx context.Context) (*plans.Pla
220228
// outputs from this component can read from the refresh result
221229
// without causing a cycle.
222230

223-
h := hooksFromContext(ctx)
224231
hookSingle(ctx, h.PendingComponentInstancePlan, c.Addr())
225232
seq, planCtx := hookBegin(ctx, h.BeginComponentInstancePlan, h.ContextAttach, c.Addr())
226233

@@ -336,7 +343,6 @@ func (c *ComponentInstance) CheckModuleTreePlan(ctx context.Context) (*plans.Pla
336343
}
337344
}
338345

339-
h := hooksFromContext(ctx)
340346
hookSingle(ctx, h.PendingComponentInstancePlan, c.Addr())
341347
seq, ctx := hookBegin(ctx, h.BeginComponentInstancePlan, h.ContextAttach, c.Addr())
342348
plan, moreDiags := PlanComponentInstance(ctx, c.main, c.PlanPrevState(), opts, []terraform.Hook{
@@ -384,6 +390,15 @@ func (c *ComponentInstance) ApplyModuleTreePlan(ctx context.Context, plan *plans
384390

385391
// If we're destroying and there's nothing to destroy, then we can
386392
// consider this a no-op.
393+
// We still need to report through the hooks that this component instance has been handled.
394+
h := hooksFromContext(ctx)
395+
hookSingle(ctx, hooksFromContext(ctx).PendingComponentInstanceApply, c.Addr())
396+
seq, ctx := hookBegin(ctx, h.BeginComponentInstanceApply, h.ContextAttach, c.Addr())
397+
hookMore(ctx, seq, h.ReportComponentInstanceApplied, &hooks.ComponentInstanceChange{
398+
Addr: c.Addr(),
399+
})
400+
hookMore(ctx, seq, h.EndComponentInstanceApply, c.Addr())
401+
387402
return &ComponentInstanceApplyResult{
388403
FinalState: plan.PriorState, // after refresh
389404
AffectedResourceInstanceObjects: resourceInstanceObjectsAffectedByStackPlan(stackPlan),

0 commit comments

Comments
 (0)