Skip to content

Commit 39a6c8c

Browse files
committed
core: do not refresh when forgetting instances
When destroying a resource instance, we always refresh first, to give the provider a chance to tell us that the instance no longer exists. This prevents issues with providers that cannot handle delete requests for already deleted resources. When forgetting, however, this is unnecessary, since no further requests to the provider will be made for this instance. Indeed, since a main use case for the forget functionality is removing instances from state for which there is no longer a configurable provider, attempting to refresh is both unnecessary and often problematic.
1 parent 7520f46 commit 39a6c8c

File tree

3 files changed

+59
-46
lines changed

3 files changed

+59
-46
lines changed

internal/terraform/context_apply2_test.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2743,6 +2743,11 @@ removed {
27432743
t.Fatalf("diags: %s", diags.Err())
27442744
}
27452745

2746+
// check that the provider was not asked to refresh the resource
2747+
if p.ReadResourceCalled {
2748+
t.Fatalf("Expected ReadResource not to be called, but it was called")
2749+
}
2750+
27462751
// check that the provider was not asked to destroy the resource
27472752
if p.ApplyResourceChangeCalled {
27482753
t.Fatalf("Expected ApplyResourceChange not to be called, but it was called")
@@ -2789,6 +2794,11 @@ removed {
27892794
t.Fatalf("diags: %s", diags.Err())
27902795
}
27912796

2797+
// check that the provider was not asked to refresh the resource
2798+
if p.ReadResourceCalled {
2799+
t.Fatalf("Expected ReadResource not to be called, but it was called")
2800+
}
2801+
27922802
// check that the provider was not asked to destroy the resource
27932803
if p.ApplyResourceChangeCalled {
27942804
t.Fatalf("Expected ApplyResourceChange not to be called, but it was called")

internal/terraform/node_resource_destroy_deposed.go

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -108,12 +108,26 @@ func (n *NodePlanDeposedResourceInstanceObject) Execute(ctx EvalContext, op walk
108108
return diags
109109
}
110110

111+
var forget bool
112+
for _, ft := range n.forgetResources {
113+
if ft.Equal(n.ResourceAddr()) {
114+
forget = true
115+
}
116+
}
117+
for _, fm := range n.forgetModules {
118+
if fm.TargetContains(n.Addr) {
119+
forget = true
120+
}
121+
}
122+
111123
// We don't refresh during the planDestroy walk, since that is only adding
112124
// the destroy changes to the plan and the provider will not be configured
113125
// at this point. The other nodes use separate types for plan and destroy,
114126
// while deposed instances are always a destroy or forget operation, so the
115127
// logic here is a bit overloaded.
116-
if !n.skipRefresh && op != walkPlanDestroy {
128+
//
129+
// We also don't refresh when forgetting instances, as it is unnecessary.
130+
if !n.skipRefresh && op != walkPlanDestroy && !forget {
117131
// Refresh this object even though it may be destroyed, in
118132
// case it's already been deleted outside of Terraform. If this is a
119133
// normal plan, providers expect a Read request to remove missing
@@ -149,17 +163,6 @@ func (n *NodePlanDeposedResourceInstanceObject) Execute(ctx EvalContext, op walk
149163
}
150164

151165
if !n.skipPlanChanges {
152-
var forget bool
153-
for _, ft := range n.forgetResources {
154-
if ft.Equal(n.ResourceAddr()) {
155-
forget = true
156-
}
157-
}
158-
for _, fm := range n.forgetModules {
159-
if fm.TargetContains(n.Addr) {
160-
forget = true
161-
}
162-
}
163166
var change *plans.ResourceInstanceChange
164167
var pDiags tfdiags.Diagnostics
165168
var deferred *providers.Deferred

internal/terraform/node_resource_plan_orphan.go

Lines changed: 34 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,40 @@ func (n *NodePlannableResourceInstanceOrphan) managedResourceExecute(ctx EvalCon
110110
return diags
111111
}
112112

113-
if !n.skipRefresh {
113+
var forget bool
114+
for _, ft := range n.forgetResources {
115+
if ft.Equal(n.ResourceAddr()) {
116+
forget = true
117+
}
118+
}
119+
for _, fm := range n.forgetModules {
120+
if fm.TargetContains(n.Addr) {
121+
forget = true
122+
}
123+
}
124+
var change *plans.ResourceInstanceChange
125+
var pDiags tfdiags.Diagnostics
126+
var deferred *providers.Deferred
127+
if forget {
128+
change, pDiags = n.planForget(ctx, oldState, "")
129+
diags = diags.Append(pDiags)
130+
} else {
131+
change, deferred, pDiags = n.planDestroy(ctx, oldState, "")
132+
diags = diags.Append(pDiags)
133+
134+
if deferred != nil {
135+
ctx.Deferrals().ReportResourceInstanceDeferred(n.Addr, deferred.Reason, &plans.ResourceInstanceChange{
136+
Addr: n.Addr,
137+
Change: change.Change,
138+
})
139+
return diags
140+
}
141+
}
142+
if diags.HasErrors() {
143+
return diags
144+
}
145+
146+
if !n.skipRefresh && !forget {
114147
// Refresh this instance even though it is going to be destroyed, in
115148
// order to catch missing resources. If this is a normal plan,
116149
// providers expect a Read request to remove missing resources from the
@@ -152,39 +185,6 @@ func (n *NodePlannableResourceInstanceOrphan) managedResourceExecute(ctx EvalCon
152185
return diags.Append(n.writeResourceInstanceState(ctx, oldState, workingState))
153186
}
154187

155-
var forget bool
156-
for _, ft := range n.forgetResources {
157-
if ft.Equal(n.ResourceAddr()) {
158-
forget = true
159-
}
160-
}
161-
for _, fm := range n.forgetModules {
162-
if fm.TargetContains(n.Addr) {
163-
forget = true
164-
}
165-
}
166-
var change *plans.ResourceInstanceChange
167-
var pDiags tfdiags.Diagnostics
168-
var deferred *providers.Deferred
169-
if forget {
170-
change, pDiags = n.planForget(ctx, oldState, "")
171-
diags = diags.Append(pDiags)
172-
} else {
173-
change, deferred, pDiags = n.planDestroy(ctx, oldState, "")
174-
diags = diags.Append(pDiags)
175-
176-
if deferred != nil {
177-
ctx.Deferrals().ReportResourceInstanceDeferred(n.Addr, deferred.Reason, &plans.ResourceInstanceChange{
178-
Addr: n.Addr,
179-
Change: change.Change,
180-
})
181-
return diags
182-
}
183-
}
184-
if diags.HasErrors() {
185-
return diags
186-
}
187-
188188
// We might be able to offer an approximate reason for why we are
189189
// planning to delete this object. (This is best-effort; we might
190190
// sometimes not have a reason.)

0 commit comments

Comments
 (0)