@@ -261,17 +261,6 @@ func (e *executor) plan(ctx, killCtx context.Context, env, vars []string, logr l
261
261
e .mut .Lock ()
262
262
defer e .mut .Unlock ()
263
263
264
- // TODO: defunct?
265
- // var isPrebuild bool
266
- // for _, v := range env {
267
- // if envName(v) == provider.IsPrebuildEnvironmentVariable() && envVar(v) == "true" {
268
- // isPrebuild = true
269
- // break
270
- // }
271
- // }
272
-
273
- // _ = isPrebuild
274
-
275
264
planfilePath := getPlanFilePath (e .workdir )
276
265
args := []string {
277
266
"plan" ,
@@ -341,6 +330,68 @@ func onlyDataResources(sm tfjson.StateModule) tfjson.StateModule {
341
330
return filtered
342
331
}
343
332
333
+ func (e * executor ) logResourceReplacements (ctx context.Context , plan * tfjson.Plan ) {
334
+ if plan == nil {
335
+ return
336
+ }
337
+
338
+ if len (plan .ResourceChanges ) == 0 {
339
+ return
340
+ }
341
+ var (
342
+ count int
343
+ replacements = make (map [string ][]string , len (plan .ResourceChanges ))
344
+ )
345
+
346
+ for _ , ch := range plan .ResourceChanges {
347
+ // No change, no problem!
348
+ if ch .Change == nil {
349
+ continue
350
+ }
351
+
352
+ // No-op change, no problem!
353
+ if ch .Change .Actions .NoOp () {
354
+ continue
355
+ }
356
+
357
+ // No replacements, no problem!
358
+ if len (ch .Change .ReplacePaths ) == 0 {
359
+ continue
360
+ }
361
+
362
+ // Replacing our resources, no problem!
363
+ if strings .Index (ch .Type , "coder_" ) == 0 {
364
+ continue
365
+ }
366
+
367
+ for _ , p := range ch .Change .ReplacePaths {
368
+ var path string
369
+ switch p := p .(type ) {
370
+ case []interface {}:
371
+ segs := p
372
+ list := make ([]string , 0 , len (segs ))
373
+ for _ , s := range segs {
374
+ list = append (list , fmt .Sprintf ("%v" , s ))
375
+ }
376
+ path = strings .Join (list , "." )
377
+ default :
378
+ path = fmt .Sprintf ("%v" , p )
379
+ }
380
+
381
+ replacements [ch .Address ] = append (replacements [ch .Address ], path )
382
+ }
383
+
384
+ count ++
385
+ }
386
+
387
+ if count > 0 {
388
+ e .server .logger .Warn (ctx , "plan introduces resource changes" , slog .F ("count" , count ))
389
+ for n , p := range replacements {
390
+ e .server .logger .Warn (ctx , "resource will be replaced!" , slog .F ("name" , n ), slog .F ("replacement_paths" , strings .Join (p , "," )))
391
+ }
392
+ }
393
+ }
394
+
344
395
// planResources must only be called while the lock is held.
345
396
func (e * executor ) planResources (ctx , killCtx context.Context , planfilePath string ) (* State , json.RawMessage , error ) {
346
397
ctx , span := e .server .startTrace (ctx , tracing .FuncName ())
@@ -351,6 +402,8 @@ func (e *executor) planResources(ctx, killCtx context.Context, planfilePath stri
351
402
return nil , nil , xerrors .Errorf ("show terraform plan file: %w" , err )
352
403
}
353
404
405
+ e .logResourceReplacements (ctx , plan )
406
+
354
407
rawGraph , err := e .graph (ctx , killCtx )
355
408
if err != nil {
356
409
return nil , nil , xerrors .Errorf ("graph: %w" , err )
0 commit comments