@go-to-k/cdkd 0.158.0 → 0.158.1

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
@@ -1,14 +1,14 @@
1
1
  # cdkd (CDK Direct)
2
2
 
3
- Drop-in CDK CLI for existing CDK apps — faster deploys via AWS SDK instead of CloudFormation, with local emulation for Lambda, API Gateway, and ECS.
3
+ Drop-in CDK CLI for existing CDK apps — faster deploys via AWS SDK instead of CloudFormation, plus local emulation for Lambda, API Gateway, and ECS.
4
4
 
5
5
  - **Drop-in CDK compatible** — your existing CDK app code runs as-is.
6
6
  - **Up to 15x faster deploys than the AWS CDK CLI (CloudFormation)**
7
- - **Local dev for CDK apps** — invoke Lambdas, serve API Gateway routes, and run ECS tasks and services directly from your CDK code, no `cdk synth → sam local` round-trip.
7
+ - **Local dev for any CDK app** — invoke Lambdas, serve API Gateway routes, run ECS tasks/services directly from your CDK code. Works against both `cdkd deploy`-managed AND `cdk deploy`-managed (CloudFormation) stacks via `--from-state` / `--from-cfn-stack` — no migration, no `cdk synth → sam local` round-trip.
8
8
 
9
9
  ![cdk deploy vs cdkd deploy — side-by-side, 35s recording, real AWS deploy. cdkd finishes while cdk is still creating its CloudFormation changeset.](assets/cdk-vs-cdkd.gif)
10
10
 
11
- **cdkd complements the AWS CDK CLI rather than replacing it.** Use cdkd in dev/test for rapid iteration and SAM-style local execution; use the AWS CDK CLI in production for full CloudFormation tooling. Bidirectional migration is supported — [import an existing CloudFormation stack](#importing-existing-resources) into cdkd for iteration, or [export back to CloudFormation](#exporting-a-stack-back-to-cloudformation) when ready for production.
11
+ **cdkd complements the AWS CDK CLI rather than replacing it.** Use cdkd in dev/test for rapid iteration and SAM-style local execution; use the AWS CDK CLI in production for full CloudFormation tooling. Install cdkd alongside an existing `cdk deploy` workflow — no migration needed, `cdkd local *` reads deployed state directly via `--from-cfn-stack`. Bidirectional migration is also supported — [import](#importing-existing-resources) into cdkd or [export](#exporting-a-stack-back-to-cloudformation) back to CloudFormation when ready.
12
12
 
13
13
  > [!IMPORTANT]
14
14
  > cdkd is for dev/test workflows only — early in development, not yet production-ready.
@@ -25,10 +25,10 @@ Drop-in CDK CLI for existing CDK apps — faster deploys via AWS SDK instead of
25
25
  - **Rollback on failure**: When a deploy errors mid-stack, cdkd rolls back the resources it just created so the stack state stays consistent (CloudFormation parity — but cdkd does this without round-tripping through CFn). Pass `cdkd deploy --no-rollback` to skip rollback and keep the partial state for Terraform-style inspection / repair. See [Rollback behavior](#rollback-behavior).
26
26
  - **`--no-wait` for async resources**: Skip the multi-minute wait on CloudFront / RDS / ElastiCache / NAT Gateway and return as soon as the create call returns (CloudFormation always blocks)
27
27
  - **VPC route DependsOn relaxation (on by default)**: Drop CDK-injected defensive `DependsOn` edges from VPC Lambdas onto private-subnet routes so `CloudFront::Distribution` and `Lambda::Url` start their ~3-min propagation in parallel with NAT Gateway stabilization (~50% faster on VPC + Lambda + CloudFront stacks). Pass `--no-aggressive-vpc-parallel` to opt out.
28
- - **Local execution without deploying** (`cdkd local invoke` / `cdkd local start-api` / `cdkd local run-task` / `cdkd local start-service`): run any Lambda — stand up every API Gateway route as a local HTTP server — start every container in an `AWS::ECS::TaskDefinition` on a per-task docker network with the AWS-published metadata-endpoints sidecar — or boot an `AWS::ECS::Service` long-running with `DesiredCount` replicas + restart-on-exit + cross-service Service Connect / Cloud Map DNS discovery (boot multiple services in one invocation, peer containers reach each other by `<discoveryName>.<namespace>` / bare alias via docker `--add-host` overlay from an in-process Cloud Map registry). SAM-compatible mental model but reuses cdkd's synthesis / asset / route-discovery (no `template.yaml` round-trip). All AWS Lambda runtimes (Node.js / Python / Ruby / Java / .NET / `provided.*`) and one server per discovered API (HTTP API v2 / REST v1 / Function URL) with their own port / authorizers / CORS configs. `local start-service` covers the long-running counterpart of `run-task` (ECS Services with DesiredCount replicas); local load-balancer emulation and `--watch` hot-reload are tracked as follow-ups. `cdkd local run-task --from-state` (also honored by `local start-service`) substitutes intrinsic-valued container `Environment[].Value` (`Ref` / `Fn::GetAtt` / `Fn::Sub` / `Fn::Join` / `Fn::ImportValue` / `Fn::GetStackOutput`) and `Secrets[].ValueFrom` against the deployed cdkd state — `table.tableName` / `ecs.Secret.fromSecretsManager(secret)` / `ecs.Secret.fromSsmParameter(param)` / cross-stack output refs Just Work locally instead of silently dropping.
29
- - **Bidirectional CloudFormation migration**: `cdkd import` adopts AWS-deployed resources (including `cdk deploy`-managed CloudFormation stacks via `--migrate-from-cloudformation`) into cdkd state without re-creating them; `cdkd export` hands a cdkd-managed stack back to CloudFormation when you're ready to move to production. See [Importing existing resources](#importing-existing-resources) and [Exporting a stack back to CloudFormation](#exporting-a-stack-back-to-cloudformation).
28
+ - **Local execution** (`cdkd local invoke` / `start-api` / `run-task` / `start-service`): run Lambdas, API Gateway routes, ECS tasks and long-running ECS services from your CDK code via Docker. All AWS Lambda runtimes, container Lambdas, REST v1 / HTTP v2 / Function URL routes, Service Connect / Cloud Map. Works for both `cdkd deploy`-managed (`--from-state`) AND `cdk deploy`-managed (`--from-cfn-stack`) stacks. See [Local execution](#local-execution).
29
+ - **Bidirectional CloudFormation migration**: `cdkd import --migrate-from-cloudformation` adopts existing CFn stacks (including `cdk deploy`-managed) into cdkd state without re-creating resources; `cdkd export` hands a cdkd stack back to CloudFormation when production-ready. See [Importing](#importing-existing-resources) / [Exporting](#exporting-a-stack-back-to-cloudformation).
30
30
 
31
- > **Note**: Resource types not covered by either SDK Providers or Cloud Control API cannot be deployed with cdkd. If you encounter an unsupported resource type, deployment will fail with a clear error message.
31
+ > **Note**: Resource types not covered by either SDK Providers or Cloud Control API cannot be deployed with cdkd. Deployment fails with a clear error message naming the type + a 1-click issue link.
32
32
 
33
33
  ## Benchmark
34
34
 
@@ -360,34 +360,7 @@ full reference. For per-resource-type provisioning support (SDK Providers
360
360
  vs Cloud Control API fallback), see
361
361
  **[docs/supported-resources.md](docs/supported-resources.md)**.
362
362
 
363
- ### Cross-stack references strong vs weak
364
-
365
- `Fn::ImportValue` is a **strong reference**: `cdkd destroy <producer>`
366
- refuses to delete a stack while any other stack still imports one of
367
- its exports via `Fn::ImportValue`. Matches CloudFormation's behavior.
368
- The error message names every offending consumer and points at the
369
- two valid resolution paths (destroy the consumer first, or remove
370
- the `Fn::ImportValue` from the consumer's template and redeploy).
371
-
372
- `Fn::GetStackOutput` (cdkd-specific) is a **weak reference**: the
373
- producer stays deletable independently of consumers. Use it when you
374
- intentionally want decoupled lifecycles (cross-region / cross-stage /
375
- staging environments).
376
-
377
- A persistent per-region exports index at
378
- `s3://{state-bucket}/cdkd/_index/{region}/exports.json` makes
379
- `Fn::ImportValue` resolution O(1) at scale (200-stack environments
380
- resolve in ~100ms vs minutes with the pre-#343 per-resolve scan).
381
- The index is a derived view rebuilt from `state.json` on demand —
382
- state.json remains the canonical source of truth, and strong-reference
383
- safety checks scan it directly rather than trusting the index.
384
-
385
- See **[docs/cross-stack-references.md](docs/cross-stack-references.md)**
386
- for the full design (`Fn::ImportValue` strong-reference rules added in
387
- state schema v4, lifecycle, locking, failure modes). State schema is at
388
- v5 since v0.100.0; `DeletionPolicy` / `UpdateReplacePolicy` changes
389
- between deploys are now detected and surfaced (see
390
- [docs/state-management.md](docs/state-management.md)).
363
+ **Property-level coverage is incremental.** SDK Providers wire most but not every CFn property of a supported type. cdkd fails fast at pre-flight when a template uses a not-yet-implemented property, with the property name + a 1-click issue link. `--allow-unsupported-properties <Type>:<Prop>,...` is the safety valve when this is too strict (e.g. mid-life update on an existing resource); avoid it on security-meaningful properties (encryption / IAM / TLS). See [docs/cli-reference.md](docs/cli-reference.md#--allow-unsupported-properties-deploy).
391
364
 
392
365
  ## Rollback behavior
393
366
 
@@ -453,96 +426,63 @@ maintain, no `cdk synth | sam ...` round-trip.
453
426
  | `cdkd local run-task <target>` | ECS RunTask — every container in a task definition started on a per-task docker network |
454
427
  | `cdkd local start-service <target>` | Long-running ECS Service emulator — `DesiredCount` replicas with restart-on-exit (no local load balancer in v1) |
455
428
 
456
- Requires Docker. Pass `--from-state` to substitute deployed physical
457
- IDs into intrinsic-valued properties (`Ref` / `Fn::GetAtt` / `Fn::Sub` /
458
- `Fn::Join` against the same stack's state plus AWS pseudo parameters
459
- via STS, AND `Fn::ImportValue` / `Fn::GetStackOutput` against the
460
- persistent exports index for cross-stack references same-account /
461
- same-region); without it, intrinsic values are dropped with a per-key
462
- warning (matches `sam local *` semantics). For CDK apps deployed via
463
- the upstream CDK CLI (`cdk deploy` → CloudFormation), pass
464
- `--from-cfn-stack [<cfn-stack-name>]` instead: cdkd reads the deployed
465
- CFn stack via `DescribeStackResources` + `ListExports` and substitutes
466
- `Ref` / `Fn::ImportValue` against the same code path (`Fn::GetAtt` is
467
- warn-and-dropped in v1). Mutually exclusive with `--from-state`.
429
+ Requires Docker. Pass `--from-state` (cdkd-deployed) or
430
+ `--from-cfn-stack` (cdk-deployed / CFn-managed) to substitute deployed
431
+ physical IDs into intrinsic-valued env vars / secrets / image URIs;
432
+ without either, intrinsic values are dropped with a per-key warning
433
+ (matches `sam local *`). The two flags are mutually exclusive.
468
434
 
469
435
  ### `local invoke`
470
436
 
471
437
  ```bash
472
- cdkd local invoke MyStack/MyApi/Handler # one-shot invoke
438
+ cdkd local invoke MyStack/Handler # one-shot invoke
473
439
  cdkd local invoke MyStack/Handler --event events/get.json
474
- cdkd local invoke MyStack/Handler --from-state # cdkd-deployed: recover deployed env vars
475
- cdkd local invoke MyStack/Handler --from-cfn-stack # cdk-deployed (CFn): same flow via DescribeStackResources
440
+ cdkd local invoke MyStack/Handler --from-state # OR --from-cfn-stack
476
441
  ```
477
442
 
478
- Supports every current AWS Lambda runtime (Node.js / Python / Ruby /
479
- Java / .NET / `provided.al2023`), container Lambdas
480
- (`DockerImageFunction` / `Code.ImageUri`) via local-build or ECR pull,
481
- and same-stack Lambda Layers bind-mounted at `/opt`.
443
+ All AWS Lambda runtimes (Node.js / Python / Ruby / Java / .NET /
444
+ `provided.al2023`), ZIP and container Lambdas, same-stack Lambda Layers
445
+ bind-mounted at `/opt`.
482
446
 
483
447
  ### `local start-api`
484
448
 
485
449
  ```bash
486
- cdkd local start-api # one HTTP server per discovered API
487
- cdkd local start-api --port 3000 # pin the first server's port
488
- cdkd local start-api MyHttpApi # filter to one API (logical id, single-stack apps)
489
- cdkd local start-api MyStack/MyHttpApi # OR: CDK Construct path
490
- cdkd local start-api --warm --watch # pre-start + hot reload
491
- cdkd local start-api --from-state # substitute deployed env vars in Lambda Environment
450
+ cdkd local start-api # one HTTP server per discovered API
451
+ cdkd local start-api MyStack/MyHttpApi --watch # filter + hot reload
452
+ cdkd local start-api --from-state # OR --from-cfn-stack
492
453
  ```
493
454
 
494
- One server per discovered API authorizers, CORS configs, and stage
495
- variables stay scoped to the owning API. Supports REST v1 + HTTP API +
496
- Function URL with **AWS_PROXY** integrations AND every REST v1
497
- non-AWS_PROXY integration kind: **MOCK** (status-code selection via
498
- request template + response-template VTL), **HTTP_PROXY** (verbatim
499
- upstream forward with `RequestParameters` mappings), **HTTP**
500
- (HTTP_PROXY + bidirectional VTL), and **AWS** Lambda non-proxy
501
- (request + response VTL via the hand-rolled engine at
502
- `src/local/vtl-engine.ts`).
503
- Direct AWS-service integrations (S3 / SQS / SNS / DynamoDB / etc.) are
504
- NOT emulated — deploy to AWS or use HTTP_PROXY to a local mock instead.
505
- Authorizers: Lambda TOKEN / REQUEST, Cognito User Pool, HTTP v2 JWT
506
- (JWKS-verified), and REST v1 `AuthorizationType: 'AWS_IAM'` (SigV4
507
- signature verification only — IAM policy evaluation is not emulated;
508
- see `docs/local-emulation.md`). CORS preflight (HTTP API v2
509
- `CorsConfiguration` + REST v1 OPTIONS MOCK preflight from
510
- `defaultCorsPreflightOptions`); hot reload via `--watch`;
511
- deploy-state-backed env var substitution via `--from-state`.
512
-
513
- Function URL `InvokeMode: RESPONSE_STREAM` is supported (issue #467):
514
- streaming Lambdas are invoked via the RIE streaming protocol and the
515
- response is piped to the HTTP client with `Transfer-Encoding: chunked`.
516
- Note that AWS's local RIE buffers the response — incremental chunk
517
- delivery only manifests against the deployed Lambda runtime; locally
518
- the response shape is correct but arrives in one block.
519
-
520
- Routes whose integration cdkd cannot emulate (REST v1 AWS integration
521
- to a non-Lambda service, HTTP_PROXY / HTTP with non-literal `Uri`, HTTP
522
- API v2 service integrations, WebSocket APIs, Function URLs with IAM
523
- auth, cross-stack Lambda Arn references) **do not block boot** — the
524
- server starts with a per-route `[warn]` summary and returns HTTP 501 +
525
- the reason in the JSON body if and when the route is hit. This lets
526
- you run the rest of your API surface locally while the unsupported
527
- routes stay on the deployed API.
455
+ REST v1 + HTTP API v2 + Function URL with all integration kinds
456
+ (AWS_PROXY / MOCK / HTTP_PROXY / HTTP / AWS Lambda non-proxy via
457
+ hand-rolled VTL), authorizers (Lambda / Cognito / HTTP v2 JWT /
458
+ REST v1 AWS_IAM SigV4), CORS, stage variables, `--watch` hot reload.
528
459
 
529
460
  ### `local run-task`
530
461
 
531
462
  ```bash
532
463
  cdkd local run-task MyStack/MyService/TaskDef
533
- cdkd local run-task MyTaskDef --from-state # resolve deployed secrets / env intrinsics
464
+ cdkd local run-task MyTaskDef --from-state # OR --from-cfn-stack
534
465
  ```
535
466
 
536
- Starts every container in the task definition on a per-task docker
537
- network with the AWS-published ECS metadata sidecar
538
- (`amazon/amazon-ecs-local-container-endpoints`). `DependsOn` /
539
- `Secrets` / `Volumes` (Host / Docker) are honored; `Secrets[].ValueFrom`
540
- is resolved from SecretsManager / SSM at startup.
467
+ Every container in the task definition on a per-task docker network
468
+ with the AWS-published ECS metadata sidecar.
541
469
 
542
- See [docs/local-emulation.md](docs/local-emulation.md) for the full
543
- reference — supported runtimes, target resolution, every flag, exit
544
- codes, route precedence, container-pool semantics, networking model,
545
- v1 scope notes.
470
+ ### `local start-service`
471
+
472
+ ```bash
473
+ cdkd local start-service MyStack/Orders MyStack/Web # multiple services in one invocation
474
+ cdkd local start-service MyStack/Orders --from-state # OR --from-cfn-stack
475
+ ```
476
+
477
+ Long-running ECS Service emulator: `DesiredCount` replicas with
478
+ restart-on-exit, cross-service Service Connect / Cloud Map DNS
479
+ discovery (peer containers reach each other by `<discoveryName>.<namespace>`).
480
+ No local load-balancer in v1.
481
+
482
+ See **[docs/local-emulation.md](docs/local-emulation.md)** for the
483
+ full reference — runtimes, target resolution, every flag, integration
484
+ and authorizer detail, route precedence, container pool, networking,
485
+ `--from-cfn-stack` semantics, v1 scope.
546
486
 
547
487
  ## Importing existing resources
548
488
 
@@ -579,63 +519,31 @@ parity matrix vs upstream `cdk import`.
579
519
  ## Exporting a stack back to CloudFormation
580
520
 
581
521
  `cdkd export` is the mirror of `cdkd import`: it hands a cdkd-managed
582
- stack over to CloudFormation via a CFn `ChangeSetType=IMPORT` changeset.
522
+ stack back to CloudFormation via a CFn `ChangeSetType=IMPORT` changeset.
583
523
  AWS resources are unchanged across the migration; cdkd state for the
584
524
  exported stack is deleted on success. From then on the stack is managed
585
- by `cdk deploy` / `aws cloudformation`.
586
-
587
- Lambda-backed Custom Resources (`Custom::*` and
588
- `AWS::CloudFormation::CustomResource`) are NOT directly CFn-importable.
589
- `cdkd export --include-non-importable` opts into a 2-phase migration
590
- to handle them: phase 1 IMPORT changeset adopts every importable
591
- resource, then phase 2 UPDATE changeset re-CREATEs the Custom Resources
592
- through CFn — which re-invokes each backing Lambda's onCreate handler.
593
- The Custom Resource Lambda must be idempotent AND must POST to
594
- `event.ResponseURL` per the cfn-response protocol. Without the flag,
595
- the command refuses to proceed and the user is expected to destroy
596
- the offending resources (or accept abandoning them) first. Nested
597
- `AWS::CloudFormation::Stack` rows are fully supported as of
598
- [#464](https://github.com/go-to-k/cdkd/issues/464) PR B2: `cdkd export`
599
- recursively walks the cdkd state tree, validates every parent → child
600
- link, and submits **IMPORT changesets per cdkd-managed stack** in
601
- leaf-first order — leaf stacks via one CREATE-via-IMPORT changeset, non-leaf
602
- parents via two changesets (Phase 1A CREATE-via-IMPORT for the parent's
603
- leaf resources only, then Phase 1B UPDATE-via-IMPORT for the just-imported
604
- child adoption per AWS's
605
- ["Nest an existing stack"](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/resource-import-nested-stacks.html)
606
- pattern with `DeletionPolicy: Retain` plus
607
- `ResourceIdentifier: { StackId: <child arn> }` plus AWS-validated
608
- child-Tag forwarding). Between phases cdkd flips each
609
- stack's status from `IMPORT_COMPLETE` to `UPDATE_COMPLETE` via a no-op
610
- tag-only `UpdateStack` (AWS rejects `IMPORT_COMPLETE` as a non-importable
611
- status for nested adoption). The original "one atomic
612
- `--include-nested-stacks` IMPORT changeset" design was found infeasible
613
- by the 2026-05-24 AWS spike — AWS rejects that flag combination with
614
- `ValidationError: IncludeNestedStacks is not supported for changeSet type: IMPORT`;
615
- see [docs/design/464-nested-stacks-export-import.md](docs/design/464-nested-stacks-export-import.md)
616
- §4.0 / §4.3 for the per-stack-loop algorithm. Each child cdkd stack
617
- (`<parent>~<childLogicalId>`) becomes its own CFn stack named
618
- `<parent>-<childLogicalId>` by default (`~` is illegal in CFn stack
619
- names); override per child with `--cfn-child-stack-name '<cdkd>=<cfn>'`
620
- (repeatable). Fresh `cdkd deploy` of nested stacks works via
621
- [#459](https://github.com/go-to-k/cdkd/issues/459).
525
+ by `cdk deploy` / `aws cloudformation`. Accepts JSON and YAML templates
526
+ (shorthand intrinsics round-trip).
622
527
 
623
528
  ```bash
624
529
  cdkd export MyStack # confirmation prompt; CFn stack name = cdkd stack name
625
530
  cdkd export MyStack --cfn-stack-name MyStack-CFn
626
531
  cdkd export MyStack --dry-run # print the import plan, do not call CFn
627
- cdkd export MyStack --template path.json # skip synth, use a pre-rendered template (JSON or YAML — format auto-detected)
628
532
  cdkd export MyStack --include-non-importable # 2-phase: IMPORT importable + CFn-CREATE Custom Resources
629
-
630
- # Nested-stack tree (parent + children). Default child CFn names: '<parent>-<childLogicalId>'.
631
- cdkd export MyApp # leaf-first per-stack IMPORT loop
632
- cdkd export MyApp --cfn-child-stack-name 'MyApp~Database=my-app-db' # per-child name override
533
+ cdkd export MyApp # nested-stack tree: leaf-first per-stack IMPORT loop
633
534
  ```
634
535
 
635
- Accepts JSON and YAML templates. YAML round-trips through a CFn-aware codec
636
- (`src/cli/yaml-cfn.ts`) that preserves every shorthand intrinsic (`!Ref` /
637
- `!GetAtt` / `!Sub` / `!Join` / etc.), so a YAML-authored CFn stack stays YAML
638
- on the phase-1 IMPORT and phase-2 UPDATE changesets.
536
+ **Lambda-backed Custom Resources** (`Custom::*` /
537
+ `AWS::CloudFormation::CustomResource`) are NOT directly CFn-importable.
538
+ `--include-non-importable` opts into a 2-phase migration that re-CREATEs
539
+ them through CFn — the Custom Resource Lambda must be idempotent.
540
+ **Nested stacks** are supported via a leaf-first per-stack IMPORT loop
541
+ (AWS rejects `--include-nested-stacks` for IMPORT changesets).
542
+
543
+ See **[docs/import.md](docs/import.md)** for the full guide — Custom Resource
544
+ 2-phase flow, nested-stack adoption mechanics (`--cfn-child-stack-name`
545
+ per-child overrides, AWS's "Nest an existing stack" pattern), and the
546
+ design rationale at [docs/design/464-nested-stacks-export-import.md](docs/design/464-nested-stacks-export-import.md).
639
547
 
640
548
  ## Drift detection
641
549
 
@@ -677,22 +585,11 @@ Both `cdkd destroy` (synth-driven) and `cdkd state destroy`
677
585
 
678
586
  ## `--remove-protection`: one-shot bypass for protected resources
679
587
 
680
- CDK's `new Stack(app, 'X', { terminationProtection: true })` is honored
681
- by `cdkd destroy` (refused before any per-resource delete). The
682
- state-only path `cdkd state destroy` does NOT honor it that's the
683
- explicit "I know what I'm doing, ignore CDK guards" escape hatch.
684
-
685
- For resource-level protection (`DeletionProtection` etc.), the standard
686
- workflow is edit CDK → redeploy → destroy. `--remove-protection` is the
687
- one-shot bypass:
688
-
689
- `cdkd destroy --remove-protection` and `cdkd state destroy
690
- --remove-protection` flip every protection flag off in-place
691
- before each provider's delete API call so the destroy proceeds
692
- without an intermediate edit / redeploy. The flag covers both
693
- stack-level `terminationProtection` (the bypass logs a WARN line
694
- naming the stack) and resource-level protection on the following
695
- types:
588
+ `cdkd destroy --remove-protection` (and `cdkd state destroy --remove-protection`)
589
+ flips every protection flag off in-place before each provider's delete
590
+ API call, so a destroy proceeds without an intermediate edit / redeploy.
591
+ Covers stack-level `terminationProtection` (logged as a WARN) AND
592
+ resource-level protection on these types:
696
593
 
697
594
  | Resource type | Protection field |
698
595
  | --- | --- |