@@ -300,10 +300,14 @@ func (e *executor) plan(ctx, killCtx context.Context, env, vars []string, logr l
300
300
graphTimings := newTimingAggregator (database .ProvisionerJobTimingStageGraph )
301
301
graphTimings .ingest (createGraphTimingsEvent (timingGraphStart ))
302
302
303
- state ,plan ,replacements , err := e .planResources (ctx ,killCtx ,planfilePath )
303
+ state ,plan ,err := e .planResources (ctx ,killCtx ,planfilePath )
304
304
if err != nil {
305
305
graphTimings .ingest (createGraphTimingsEvent (timingGraphErrored ))
306
- return nil ,err
306
+ return nil ,xerrors .Errorf ("plan resources: %w" ,err )
307
+ }
308
+ planJSON ,err := json .Marshal (plan )
309
+ if err != nil {
310
+ return nil ,xerrors .Errorf ("marshal plan: %w" ,err )
307
311
}
308
312
309
313
graphTimings .ingest (createGraphTimingsEvent (timingGraphComplete ))
@@ -312,17 +316,22 @@ func (e *executor) plan(ctx, killCtx context.Context, env, vars []string, logr l
312
316
// the point of prebuilding if the expensive resource is replaced once claimed!
313
317
var (
314
318
isPrebuildClaimAttempt = ! destroy && metadata .GetPrebuildClaimForUserId ()!= ""
315
- reps []* proto.ResourceReplacement
319
+ resReps []* proto.ResourceReplacement
316
320
)
317
- if count := len (replacements );count > 0 && isPrebuildClaimAttempt {
318
- // TODO(dannyk): we should log drift always (not just during prebuild claim attempts); we're validating that this output
319
- // will not be overwhelming for end-users, but it'll certainly be super valuable for template admins
320
- // to diagnose this resource replacement issue, at least.
321
- e .logDrift (ctx ,killCtx ,planfilePath ,logr )
322
-
323
- reps = make ([]* proto.ResourceReplacement ,0 ,len (replacements ))
324
- for n ,p := range replacements {
325
- reps = append (reps ,& proto.ResourceReplacement {
321
+ if repsFromPlan := findResourceReplacements (plan );len (repsFromPlan )> 0 {
322
+ if isPrebuildClaimAttempt {
323
+ // TODO(dannyk): we should log drift always (not just during prebuild claim attempts); we're validating that this output
324
+ // will not be overwhelming for end-users, but it'll certainly be super valuable for template admins
325
+ // to diagnose this resource replacement issue, at least.
326
+ // Once prebuilds moves out of beta, consider deleting this condition.
327
+
328
+ // Lock held before calling (see top of method).
329
+ e .logDrift (ctx ,killCtx ,planfilePath ,logr )
330
+ }
331
+
332
+ resReps = make ([]* proto.ResourceReplacement ,0 ,len (repsFromPlan ))
333
+ for n ,p := range repsFromPlan {
334
+ resReps = append (resReps ,& proto.ResourceReplacement {
326
335
Resource :n ,
327
336
Paths :p ,
328
337
})
@@ -335,8 +344,8 @@ func (e *executor) plan(ctx, killCtx context.Context, env, vars []string, logr l
335
344
ExternalAuthProviders :state .ExternalAuthProviders ,
336
345
Timings :append (e .timings .aggregate (),graphTimings .aggregate ()... ),
337
346
Presets :state .Presets ,
338
- Plan :plan ,
339
- ResourceReplacements :reps ,
347
+ Plan :planJSON ,
348
+ ResourceReplacements :resReps ,
340
349
},nil
341
350
}
342
351
@@ -358,18 +367,18 @@ func onlyDataResources(sm tfjson.StateModule) tfjson.StateModule {
358
367
}
359
368
360
369
// planResources must only be called while the lock is held.
361
- func (e * executor )planResources (ctx ,killCtx context.Context ,planfilePath string ) (* State ,json. RawMessage , resourceReplacements ,error ) {
370
+ func (e * executor )planResources (ctx ,killCtx context.Context ,planfilePath string ) (* State ,* tfjson. Plan ,error ) {
362
371
ctx ,span := e .server .startTrace (ctx ,tracing .FuncName ())
363
372
defer span .End ()
364
373
365
374
plan ,err := e .parsePlan (ctx ,killCtx ,planfilePath )
366
375
if err != nil {
367
- return nil ,nil ,nil , xerrors .Errorf ("show terraform plan file: %w" ,err )
376
+ return nil ,nil ,xerrors .Errorf ("show terraform plan file: %w" ,err )
368
377
}
369
378
370
379
rawGraph ,err := e .graph (ctx ,killCtx )
371
380
if err != nil {
372
- return nil ,nil ,nil , xerrors .Errorf ("graph: %w" ,err )
381
+ return nil ,nil ,xerrors .Errorf ("graph: %w" ,err )
373
382
}
374
383
modules := []* tfjson.StateModule {}
375
384
if plan .PriorState != nil {
@@ -387,15 +396,10 @@ func (e *executor) planResources(ctx, killCtx context.Context, planfilePath stri
387
396
388
397
state ,err := ConvertState (ctx ,modules ,rawGraph ,e .server .logger )
389
398
if err != nil {
390
- return nil ,nil ,nil ,err
391
- }
392
-
393
- planJSON ,err := json .Marshal (plan )
394
- if err != nil {
395
- return nil ,nil ,nil ,err
399
+ return nil ,nil ,err
396
400
}
397
401
398
- return state ,planJSON , findResourceReplacements ( plan ) ,nil
402
+ return state ,plan ,nil
399
403
}
400
404
401
405
// parsePlan must only be called while the lock is held.