@@ -18,6 +18,7 @@ import { ITerraformIterator } from "./terraform-iterator";
18
18
import { Precondition , Postcondition } from "./terraform-conditions" ;
19
19
import { TerraformCount } from "./terraform-count" ;
20
20
import {
21
+ RemovedBlockLocalExecProvisioner ,
21
22
SSHProvisionerConnection ,
22
23
WinrmProvisionerConnection ,
23
24
} from "./terraform-provisioner" ;
@@ -31,6 +32,10 @@ import {
31
32
import { ValidateTerraformVersion } from "./validations/validate-terraform-version" ;
32
33
import { TerraformStack } from "./terraform-stack" ;
33
34
import {
35
+ cannotImportRemovedResource ,
36
+ cannotMoveRemovedResource ,
37
+ cannotRemoveImportedResource ,
38
+ cannotRemoveMovedResource ,
34
39
movedToResourceOfDifferentType ,
35
40
resourceGivenTwoMoveOperationsById ,
36
41
resourceGivenTwoMoveOperationsByTarget ,
@@ -128,6 +133,19 @@ export interface TerraformResourceImport {
128
133
readonly provider ?: TerraformProvider ;
129
134
}
130
135
136
+ export interface TerraformResourceRemoveLifecycle {
137
+ readonly destroy : boolean ;
138
+ }
139
+
140
+ export type TerraformResourceRemoveProvisioner =
141
+ RemovedBlockLocalExecProvisioner ;
142
+
143
+ export interface TerraformResourceRemove {
144
+ readonly from : string ;
145
+ readonly lifecycle ?: TerraformResourceRemoveLifecycle ;
146
+ readonly provisioners ?: Array < TerraformResourceRemoveProvisioner > ;
147
+ }
148
+
131
149
// eslint-disable-next-line jsdoc/require-jsdoc
132
150
export class TerraformResource
133
151
extends TerraformElement
@@ -148,6 +166,7 @@ export class TerraformResource
148
166
FileProvisioner | LocalExecProvisioner | RemoteExecProvisioner
149
167
> ;
150
168
private _imported ?: TerraformResourceImport ;
169
+ private _removed ?: TerraformResourceRemove ;
151
170
private _movedByTarget ?: TerraformResourceMoveByTarget ;
152
171
private _movedById ?: TerraformResourceMoveById ;
153
172
private _hasMoved = false ;
@@ -271,6 +290,22 @@ export class TerraformResource
271
290
...this . constructNodeMetadata ,
272
291
} ;
273
292
293
+ // If we are removing a resource imports and moved blocks are not supported
294
+ if ( this . _removed ) {
295
+ const { provisioners, ...props } = this . _removed ;
296
+ return {
297
+ resource : undefined ,
298
+ removed : [
299
+ {
300
+ ...props ,
301
+ provisioner : provisioners ?. map ( ( { type, ...props } ) => ( {
302
+ [ type ] : keysToSnakeCase ( props ) ,
303
+ } ) ) ,
304
+ } ,
305
+ ] ,
306
+ } ;
307
+ }
308
+
274
309
const movedBlock = this . _buildMovedBlock ( ) ;
275
310
return {
276
311
resource : this . _hasMoved
@@ -322,6 +357,24 @@ export class TerraformResource
322
357
...this . constructNodeMetadata ,
323
358
} ;
324
359
360
+ // If we are removing a resource imports and moved blocks are not supported
361
+ if ( this . _removed ) {
362
+ const { provisioners, ...props } = this . _removed ;
363
+ return {
364
+ resource : undefined ,
365
+ removed : [
366
+ {
367
+ ...props ,
368
+ provisioner : provisioners ?. map ( ( { type, ...props } ) => ( {
369
+ [ type ] : {
370
+ value : keysToSnakeCase ( props ) ,
371
+ } ,
372
+ } ) ) ,
373
+ } ,
374
+ ] ,
375
+ } ;
376
+ }
377
+
325
378
const movedBlock = this . _buildMovedBlock ( ) ;
326
379
return {
327
380
resource : this . _hasMoved
@@ -393,6 +446,11 @@ export class TerraformResource
393
446
[ this . terraformResourceType ] : [ this . friendlyUniqueId ] ,
394
447
}
395
448
: undefined ,
449
+ removed : this . _removed
450
+ ? {
451
+ [ this . terraformResourceType ] : [ this . friendlyUniqueId ] ,
452
+ }
453
+ : undefined ,
396
454
} ;
397
455
}
398
456
@@ -406,6 +464,9 @@ export class TerraformResource
406
464
}
407
465
408
466
public importFrom ( id : string , provider ?: TerraformProvider ) {
467
+ if ( this . _removed ) {
468
+ throw cannotImportRemovedResource ( this . node . id ) ;
469
+ }
409
470
this . _imported = { id, provider } ;
410
471
this . node . addValidation (
411
472
new ValidateTerraformVersion (
@@ -415,6 +476,42 @@ export class TerraformResource
415
476
) ;
416
477
}
417
478
479
+ /**
480
+ * Remove this resource, this will destroy the resource and place it within the removed block
481
+ * @param lifecycle The lifecycle block to be used for the removed resource
482
+ * @param provisioners Optional The provisioners to be used for the removed resource
483
+ */
484
+ public remove (
485
+ lifecycle : TerraformResourceRemoveLifecycle ,
486
+ provisioners ?: Array < TerraformResourceRemoveProvisioner > ,
487
+ ) {
488
+ if ( this . _movedByTarget ) {
489
+ throw cannotRemoveMovedResource ( this . node . id ) ;
490
+ }
491
+ if ( this . _imported ) {
492
+ throw cannotRemoveImportedResource ( this . node . id ) ;
493
+ }
494
+ this . node . addValidation (
495
+ new ValidateTerraformVersion (
496
+ ">=1.7" ,
497
+ `Removed blocks are only supported for Terraform >=1.7. Please upgrade your Terraform version.` ,
498
+ ) ,
499
+ ) ;
500
+ if ( provisioners ) {
501
+ this . node . addValidation (
502
+ new ValidateTerraformVersion (
503
+ ">=1.9" ,
504
+ `A Removed block provisioner is only supported for Terraform >=1.9. Please upgrade your Terraform version.` ,
505
+ ) ,
506
+ ) ;
507
+ }
508
+ this . _removed = {
509
+ from : `${ this . terraformResourceType } .${ this . friendlyUniqueId } ` ,
510
+ lifecycle,
511
+ provisioners,
512
+ } ;
513
+ }
514
+
418
515
private _getResourceTarget ( moveTarget : string ) {
419
516
return TerraformStack . of ( this ) . moveTargets . getResourceByTarget ( moveTarget ) ;
420
517
}
@@ -472,6 +569,9 @@ export class TerraformResource
472
569
* @param index Optional The index corresponding to the key the resource is to appear in the foreach of a resource to move to
473
570
*/
474
571
public moveTo ( moveTarget : string , index ?: string | number ) {
572
+ if ( this . _removed ) {
573
+ throw cannotMoveRemovedResource ( this . node . id ) ;
574
+ }
475
575
if ( this . _movedByTarget ) {
476
576
throw resourceGivenTwoMoveOperationsByTarget (
477
577
this . friendlyUniqueId ,
@@ -496,6 +596,9 @@ export class TerraformResource
496
596
* @param id Full id of resource to move to, e.g. "aws_s3_bucket.example"
497
597
*/
498
598
public moveToId ( id : string ) {
599
+ if ( this . _removed ) {
600
+ throw cannotMoveRemovedResource ( this . node . id ) ;
601
+ }
499
602
if ( this . _movedById ) {
500
603
throw resourceGivenTwoMoveOperationsById (
501
604
this . node . id ,
@@ -519,6 +622,9 @@ export class TerraformResource
519
622
* @param id Full id of resource being moved from, e.g. "aws_s3_bucket.example"
520
623
*/
521
624
public moveFromId ( id : string ) {
625
+ if ( this . _removed ) {
626
+ throw cannotMoveRemovedResource ( this . node . id ) ;
627
+ }
522
628
if ( this . _movedById ) {
523
629
throw resourceGivenTwoMoveOperationsById (
524
630
this . node . id ,
0 commit comments