@go-to-k/cdkd 0.57.1 → 0.59.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -487,6 +487,68 @@ Two `orphan` variants at different granularities:
487
487
  Both `cdkd destroy` (synth-driven) and `cdkd state destroy`
488
488
  (state-driven, no synth) delete AWS resources + state.
489
489
 
490
+ ## Stack termination protection
491
+
492
+ CDK's `new Stack(app, 'X', { terminationProtection: true })` is
493
+ honored by `cdkd destroy` and `cdkd destroy --all`. A protected
494
+ stack is refused before the lock is acquired and before any
495
+ per-resource delete runs; in `--all` runs sibling unprotected
496
+ stacks still destroy and the protected ones contribute to the
497
+ partial-failure exit code 2.
498
+
499
+ Bypass workflow:
500
+
501
+ 1. Edit the CDK code to set `terminationProtection: false`.
502
+ 2. Redeploy: `cdkd deploy MyStack`.
503
+ 3. Retry: `cdkd destroy MyStack`.
504
+
505
+ `cdkd state destroy` (state-only, no synth) does **not** honor
506
+ `terminationProtection` — the flag is a CDK property surfaced via
507
+ synth and is not stored in cdkd's state.json. Use `cdkd destroy`
508
+ when synth is available, or accept that `state destroy` is the
509
+ explicit "I know what I'm doing, ignore CDK guards" escape hatch.
510
+
511
+ ### `--remove-protection`: one-shot bypass for protected resources
512
+
513
+ `cdkd destroy --remove-protection` and `cdkd state destroy
514
+ --remove-protection` flip every protection flag off in-place
515
+ before each provider's delete API call so the destroy proceeds
516
+ without an intermediate edit / redeploy. The flag covers both
517
+ stack-level `terminationProtection` (the bypass logs a WARN line
518
+ naming the stack) and resource-level protection on the following
519
+ types:
520
+
521
+ | Resource type | Protection field |
522
+ | --- | --- |
523
+ | `AWS::Logs::LogGroup` | `DeletionProtectionEnabled` |
524
+ | `AWS::RDS::DBInstance` | `DeletionProtection` |
525
+ | `AWS::RDS::DBCluster` | `DeletionProtection` |
526
+ | `AWS::DynamoDB::Table` | `DeletionProtectionEnabled` |
527
+ | `AWS::EC2::Instance` | `DisableApiTermination` |
528
+ | `AWS::ElasticLoadBalancingV2::LoadBalancer` | attribute `deletion_protection.enabled` |
529
+ | `AWS::Cognito::UserPool` | `DeletionProtection` (`ACTIVE` / `INACTIVE`) |
530
+ | `AWS::AutoScaling::AutoScalingGroup` | `DeletionProtection` (`none` / `prevent-force-deletion` / `prevent-all-deletion`) — flag also sets `ForceDelete: true` so AWS terminates running instances as part of the delete |
531
+
532
+ The flip-off call is idempotent — providers always issue it when
533
+ the flag is set, regardless of whether the resource currently has
534
+ protection on. This is per-PR-level: a single `--remove-protection`
535
+ covers every protection-bearing type listed above; there is no
536
+ per-type variant.
537
+
538
+ The interactive confirmation prompt is updated when the flag is
539
+ set: `About to destroy N resources from stack "X", REMOVING
540
+ DELETION PROTECTION on K of them. Continue? (y/N)`. The default
541
+ flips from `Y/n` to `y/N` so the destructive bypass requires an
542
+ explicit `y` / `yes`. `--yes` / `-y` / `-f` skips the prompt.
543
+
544
+ Other protected resource types (CloudFront Distributions, Lambda
545
+ function reserved concurrency, S3 bucket retention, etc.) are
546
+ out of scope — the flag list is curated to the cases where AWS
547
+ exposes a synchronous "flip protection off" API call.
548
+
549
+ `cdkd diff` (read-only) and `cdkd deploy` (forward-only) are
550
+ unaffected — only destroy is gated.
551
+
490
552
  ## `publish-assets`: synth + build + publish, no deploy
491
553
 
492
554
  `cdkd publish-assets` runs the asset half of the deploy pipeline