@go-to-k/cdkd 0.285.11 → 0.285.13
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 +27 -958
- package/dist/{asg-provider--XFrKRbw.js → asg-provider-DcFgnQQO.js} +11 -4
- package/dist/asg-provider-DcFgnQQO.js.map +1 -0
- package/dist/cli.js +2 -2
- package/dist/{deploy-engine-CJdl4I5l.js → deploy-engine-DhMm2M33.js} +105 -34
- package/dist/deploy-engine-DhMm2M33.js.map +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/{program-BeYoZQIP.js → program-DHJ4G_ZZ.js} +437 -88
- package/dist/{program-BeYoZQIP.js.map → program-DHJ4G_ZZ.js.map} +1 -1
- package/dist/{version-CHHsJMqE.js → version-FLW4rE5A.js} +2 -2
- package/dist/{version-CHHsJMqE.js.map → version-FLW4rE5A.js.map} +1 -1
- package/package.json +5 -2
- package/dist/asg-provider--XFrKRbw.js.map +0 -1
- package/dist/deploy-engine-CJdl4I5l.js.map +0 -1
package/README.md
CHANGED
|
@@ -6,16 +6,23 @@
|
|
|
6
6
|
|
|
7
7
|
Drop-in CDK CLI for existing CDK apps — up to 15x faster deploys via direct AWS SDK calls instead of CloudFormation.
|
|
8
8
|
|
|
9
|
+
**📚 Documentation: [cdkd.dev](https://cdkd.dev)**
|
|
10
|
+
|
|
11
|
+
<a href="https://cdkd.dev"><picture>
|
|
12
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/go-to-k/cdkd/main/assets/docs-site-dark.png">
|
|
13
|
+
<img alt="cdkd documentation site — cdkd.dev" src="https://raw.githubusercontent.com/go-to-k/cdkd/main/assets/docs-site-light.png" width="820">
|
|
14
|
+
</picture></a>
|
|
15
|
+
|
|
9
16
|
- **Drop-in CDK compatible**: your existing CDK app code runs as-is; just replace `cdk deploy` with `cdkd deploy`.
|
|
10
17
|
- **Up to 15x faster deploys**: direct SDK calls, aggressive parallelization, and `--no-wait` to skip slow stabilization waits; **faster than Terraform and CloudFormation Express mode** too (see [Benchmark](#benchmark)).
|
|
11
18
|
|
|
12
|
-

|
|
19
|
+

|
|
13
20
|
|
|
14
|
-
**cdkd complements the AWS CDK CLI rather than replacing it.** Use cdkd in dev/test for rapid iteration; use the AWS CDK CLI in production for full CloudFormation tooling. Install cdkd alongside an existing `cdk deploy` workflow: no migration needed. You can also [import](
|
|
21
|
+
**cdkd complements the AWS CDK CLI rather than replacing it.** Use cdkd in dev/test for rapid iteration; use the AWS CDK CLI in production for full CloudFormation tooling. Install cdkd alongside an existing `cdk deploy` workflow: no migration needed. You can also [import](https://cdkd.dev/import/) existing stacks into cdkd or [export](https://cdkd.dev/export/) back to CloudFormation anytime.
|
|
15
22
|
|
|
16
23
|
**A natural fit for AI-driven development.** AI coding agents iterate in tight spin-up / tear-down loops — and cdkd keeps each turn short, with fast deploys and an equally fast `cdkd destroy` that deletes via direct SDK calls instead of polling a CloudFormation stack-delete.
|
|
17
24
|
|
|
18
|
-
**Local execution from your deployed stack.** `cdkd local` runs your functions, APIs, and ECS tasks on your machine. It can resolve env vars, secrets, and resource references from your real deployed stack: no hand-written `.env` files, no hand-seeded test data (see [Local execution](
|
|
25
|
+
**Local execution from your deployed stack.** `cdkd local` runs your functions, APIs, and ECS tasks on your machine. It can resolve env vars, secrets, and resource references from your real deployed stack: no hand-written `.env` files, no hand-seeded test data (see [Local execution](https://cdkd.dev/local-emulation/)).
|
|
19
26
|
|
|
20
27
|
> [!IMPORTANT]
|
|
21
28
|
> cdkd is for dev/test workflows only — early in development, not yet production-ready.
|
|
@@ -33,7 +40,7 @@ The installed binary is `cdkd`.
|
|
|
33
40
|
|
|
34
41
|
> **First-time setup**: run `cdkd bootstrap` once per AWS account before any
|
|
35
42
|
> other command; it replaces `cdk bootstrap`, which cdkd does not require
|
|
36
|
-
> (details in [
|
|
43
|
+
> (details in [Getting Started](https://cdkd.dev/getting-started/)).
|
|
37
44
|
|
|
38
45
|
```bash
|
|
39
46
|
# Bootstrap (creates S3 state bucket + asset storage — one-time setup per AWS account)
|
|
@@ -57,15 +64,12 @@ cdkd destroy
|
|
|
57
64
|
|
|
58
65
|
## Use with AI Coding Agents
|
|
59
66
|
|
|
60
|
-
This repository ships a [`cdkd` skill](plugins/cdkd-skills/skills/cdkd/SKILL.md)
|
|
61
|
-
that teaches AI coding agents to use cdkd safely
|
|
62
|
-
checks, preview and deployment, wait modes, verification, CloudFormation
|
|
63
|
-
migration boundaries, and destructive-operation safety.
|
|
67
|
+
This repository ships a [`cdkd` skill](https://github.com/go-to-k/cdkd/blob/main/plugins/cdkd-skills/skills/cdkd/SKILL.md)
|
|
68
|
+
that teaches AI coding agents to use cdkd safely ([AI agents guide](https://cdkd.dev/ai-agents/)).
|
|
64
69
|
|
|
65
70
|
### Claude Code
|
|
66
71
|
|
|
67
|
-
Install it as a plugin (one-time setup
|
|
68
|
-
running these inside a Claude Code session:
|
|
72
|
+
Install it as a plugin (one-time setup) by running these inside a Claude Code session:
|
|
69
73
|
|
|
70
74
|
```text
|
|
71
75
|
/plugin marketplace add go-to-k/cdkd
|
|
@@ -98,12 +102,20 @@ linking the checkout:
|
|
|
98
102
|
claude --add-dir /path/to/cdkd
|
|
99
103
|
```
|
|
100
104
|
|
|
105
|
+
## Documentation
|
|
106
|
+
|
|
107
|
+
Full documentation lives at **[cdkd.dev](https://cdkd.dev)**:
|
|
108
|
+
|
|
109
|
+
- [Getting Started](https://cdkd.dev/getting-started/)
|
|
110
|
+
- [CLI Reference](https://cdkd.dev/cli-reference/)
|
|
111
|
+
- [Local Execution](https://cdkd.dev/local-emulation/)
|
|
112
|
+
- [Import / Export — CloudFormation migration](https://cdkd.dev/import/)
|
|
113
|
+
- [Troubleshooting](https://cdkd.dev/troubleshooting/)
|
|
114
|
+
|
|
101
115
|
## Benchmark
|
|
102
116
|
|
|
103
117
|
**cdkd deploys up to 15x faster than AWS CDK (CloudFormation)** on SDK-Provider-handled stacks; the per-stack speedup widens with size and parallelism.
|
|
104
118
|
|
|
105
|
-
Numbers below are deploy-phase only (CDK app synthesis is identical between cdkd and AWS CDK — both run the same user code through `aws-cdk-lib`'s synthesizer — so synth time is excluded from the speedup calculation).
|
|
106
|
-
|
|
107
119
|
### vs CloudFormation Express mode: up to 9x faster
|
|
108
120
|
|
|
109
121
|
CloudFormation's [Express mode](https://aws.amazon.com/about-aws/whats-new/2026/06/aws-cloudformation-cdk/) is a fast-deploy option that skips resource stabilization waits, similar in spirit to cdkd's `--no-wait`. Even so, cdkd is faster than Express on nearly every stack, and with `--no-wait` it pulls dramatically ahead on stacks dominated by async resources.
|
|
@@ -119,11 +131,7 @@ CloudFormation's [Express mode](https://aws.amazon.com/about-aws/whats-new/2026/
|
|
|
119
131
|
| SQS | 83 | 22 | **9** | 9 |
|
|
120
132
|
| SQS + CloudWatch | 87 | 44 | 30 | 31 |
|
|
121
133
|
|
|
122
|
-
Best of 3 runs, deploy-phase only, seconds, `us-west-2`.
|
|
123
|
-
|
|
124
|
-
- **~1.5–2x faster than Express on most stacks** — e.g. SQS finishes in 9s vs Express's 22s (~2.4x).
|
|
125
|
-
- **Async-heavy stacks are where the gap explodes.** On the VPC + CloudFront stack the cdkd default finishes in 96s vs Express's 366s (~3.8x) — since #1282 the default already leaves CloudFront propagation to complete in the background — and `--no-wait` (40s, ~9x) additionally skips the NAT stabilization wait.
|
|
126
|
-
- **S3 is the one case where Express edges cdkd's default** (22s vs 23s). On a near-instant single-resource stack there is little left to parallelize, and `--no-wait` makes no difference there.
|
|
134
|
+
Best of 3 runs, deploy-phase only, seconds, `us-west-2`.
|
|
127
135
|
|
|
128
136
|
### vs Terraform: cdkd deploys faster
|
|
129
137
|
|
|
@@ -139,948 +147,9 @@ We also raced cdkd against Terraform: the same logical stacks expressed both as
|
|
|
139
147
|
| cloudfront — created (fire and forget) | S3 origin + CloudFront + OAC | 11.1 | 10.3 (`wait_for_deployment = false`) | no such mode | 10.4 |
|
|
140
148
|
| cloudfront — `Deployed` | S3 origin + CloudFront + OAC | 174.0 (`--full-wait`) | 166.4 | 232.3 | n/a |
|
|
141
149
|
|
|
142
|
-
Cold end-to-end wall clock including synth / plan, median of 7 runs, seconds, `us-east-1
|
|
143
|
-
|
|
144
|
-
- **The lead tracks how much of the wall clock is orchestration.** wide and serverless are almost pure orchestration and run ~2.2x faster; cloudfront is almost pure CDN propagation under the `Deployed` definition and pure API accept under fire-and-forget — a tie in both rows.
|
|
145
|
-
- **A win is claimed only where no cdkd run overlaps any Terraform run** — true of the four bolded rows. The ties disclose which way their medians lean, and the rule cuts both ways: webapp leans cdkd (by 17.6s), both cloudfront rows lean Terraform (by 0.8s and 7.6s) — in all three the run distributions overlap fully, so n=7 cannot separate them and neither side gets the row.
|
|
146
|
-
- **This is not cdkd waiting for less.** Held to the same completion definition — ECS `--full-wait` vs Terraform's `wait_for_steady_state=true` is 227.7 vs 282.7 (1.24x), and both cloudfront rows above are same-definition pairs by construction.
|
|
147
|
-
|
|
148
|
-
Distribution analysis, wait-skipping comparability (Terraform has no global `--no-wait` equivalent), and per-run data: [docs/benchmarks.md](docs/benchmarks.md) and [cdkd-bench-terraform](https://github.com/go-to-k/cdkd-bench-terraform).
|
|
149
|
-
|
|
150
|
-
### More benchmarks
|
|
151
|
-
|
|
152
|
-
The full benchmark suite lives in [docs/benchmarks.md](docs/benchmarks.md): the SDK Provider path (**5.5x**, 17.0s vs 94.4s), the VPC + CloudFront + Lambda stack behind the headline **15x** (40s vs 599s with `--no-wait`), the Cloud Control API fallback path (**1.6x**), and the Terraform comparison in full detail. Reproduction scripts: [tests/benchmark](tests/benchmark/README.md).
|
|
153
|
-
|
|
154
|
-
## Features
|
|
155
|
-
|
|
156
|
-
- **Synthesis orchestration**: CDK app subprocess execution, Cloud Assembly parsing, context provider loop
|
|
157
|
-
- **Asset handling**: Self-implemented asset publisher for S3 file assets (ZIP packaging) and Docker images (ECR)
|
|
158
|
-
- **Context resolution**: Self-implemented context provider loop for Vpc.fromLookup(), AZ, SSM, HostedZone, etc.
|
|
159
|
-
- **Hybrid provisioning**: SDK Providers for fast direct API calls, Cloud Control API fallback for broad resource coverage
|
|
160
|
-
- **Diff calculation**: Self-implemented resource/property-level diff between desired template and current state
|
|
161
|
-
- **S3-based state management**: No DynamoDB required, uses S3 conditional writes for locking
|
|
162
|
-
- **DAG-based parallelization**: Analyze `Ref`/`Fn::GetAtt` dependencies and execute in parallel
|
|
163
|
-
- **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 — then either fix forward with another `cdkd deploy`, revert with the standalone `cdkd rollback`, or `cdkd destroy` to clean up. See [Rollback behavior](#rollback-behavior).
|
|
164
|
-
- **`--no-wait` / `--full-wait` for async resources**: `--no-wait` skips the multi-minute wait on RDS / ElastiCache / NAT Gateway / EC2 Instance / ELBv2 LoadBalancer / Lambda MicroVM Image and returns as soon as the create call returns (CloudFormation always blocks); `--full-wait` goes the other way and waits where cdkd's default does not (ECS Service steady state; CloudFront Distribution `Deployed` — the default returns as soon as `CreateDistribution` is accepted, since nothing in-deploy needs the 3–15 min edge propagation)
|
|
165
|
-
- **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.
|
|
166
|
-
- **Local execution** (`cdkd local invoke` / `start-api` / `run-task` / `start-service` / `start-alb` / `start-cloudfront` / `invoke-agentcore` / `start-agentcore`): run Lambdas, API Gateway routes, ECS tasks, long-running ECS services, CloudFront distributions, and Bedrock AgentCore Runtimes from your CDK code. All AWS Lambda runtimes, container Lambdas, REST v1 / HTTP v2 / Function URL routes, Service Connect / Cloud Map, AgentCore HTTP / MCP / A2A / AGUI / WebSocket protocols (one-shot `invoke-agentcore` and long-running warm serve via `start-agentcore`, which serves the native contract — `POST /invocations` + `GET /ping`, MCP `/mcp`, A2A `/` — plus the `/ws` bridge for HTTP / AGUI). The Docker-backed commands work for both `cdkd deploy`-managed (`--from-state`) AND `cdk deploy`-managed (`--from-cfn-stack`) stacks; `start-cloudfront` serves the viewer-request -> S3 / Lambda Function URL origin -> viewer-response pipeline (CloudFront-Functions + S3-only distributions run in-process with no Docker). See [Local execution](#local-execution).
|
|
167
|
-
- **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).
|
|
168
|
-
- **Mixed cdkd / CloudFormation estates**: a cdkd-deployed stack can reference a producer stack still managed by `cdk deploy` — `Fn::ImportValue` / `Fn::GetStackOutput` fall back to CloudFormation (`ListExports` / stack outputs) when the reference is not in cdkd state, so shared infrastructure stays on the CDK CLI while app stacks iterate on cdkd. See [Reference CloudFormation-managed stacks](#reference-cloudformation-managed-stacks-mixed-estates).
|
|
169
|
-
|
|
170
|
-
> **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.
|
|
171
|
-
|
|
172
|
-
## How it works
|
|
173
|
-
|
|
174
|
-
```
|
|
175
|
-
┌─────────────────┐
|
|
176
|
-
│ Your CDK App │ (aws-cdk-lib)
|
|
177
|
-
└────────┬────────┘
|
|
178
|
-
│
|
|
179
|
-
▼
|
|
180
|
-
┌─────────────────┐
|
|
181
|
-
│ cdkd Synthesis │ Subprocess + Cloud Assembly parser
|
|
182
|
-
└────────┬────────┘
|
|
183
|
-
│
|
|
184
|
-
▼
|
|
185
|
-
┌─────────────────┐
|
|
186
|
-
│ CloudFormation │
|
|
187
|
-
│ Template │
|
|
188
|
-
└────────┬────────┘
|
|
189
|
-
│
|
|
190
|
-
▼
|
|
191
|
-
┌─────────────────┐
|
|
192
|
-
│ Asset Build & │ S3 ZIP upload / ECR image build & push
|
|
193
|
-
│ Publish │
|
|
194
|
-
└────────┬────────┘
|
|
195
|
-
│
|
|
196
|
-
▼
|
|
197
|
-
┌─────────────────┐
|
|
198
|
-
│ cdkd Engine │
|
|
199
|
-
│ - DAG Analysis │ Dependency graph construction
|
|
200
|
-
│ - Diff Calc │ Compare with existing resources
|
|
201
|
-
│ - Parallel Exec │ Dispatch on deps complete (no level barrier)
|
|
202
|
-
└────────┬────────┘
|
|
203
|
-
│
|
|
204
|
-
┌────┴────┐
|
|
205
|
-
▼ ▼
|
|
206
|
-
┌────────┐ ┌────────┐
|
|
207
|
-
│ SDK │ │ Cloud │
|
|
208
|
-
│Provider│ │Control │ Fallback for many
|
|
209
|
-
│ │ │ API │ additional types
|
|
210
|
-
└────────┘ └────────┘
|
|
211
|
-
```
|
|
212
|
-
|
|
213
|
-
For a step-by-step walkthrough of the full `cdkd deploy` pipeline (CLI
|
|
214
|
-
parsing → synthesis → asset publishing → per-stack deploy), see
|
|
215
|
-
[docs/architecture.md](docs/architecture.md#5-end-to-end-pipeline-walkthrough-cdkd-deploy).
|
|
216
|
-
|
|
217
|
-
## Prerequisites
|
|
218
|
-
|
|
219
|
-
- **Node.js** >= 20.0.0
|
|
220
|
-
- **AWS credentials with admin-equivalent permissions** for the resources being deployed. cdkd does NOT route through CloudFormation, so CDK CLI's `cdk-hnb659fds-deploy-role-*` is NOT sufficient — see [`--role-arn`](docs/cli-reference.md).
|
|
221
|
-
|
|
222
|
-
AWS CDK's `cdk bootstrap` is not required. Instead, run `cdkd bootstrap` once per
|
|
223
|
-
account: it creates the S3 state bucket (`cdkd-state-{accountId}`) that cdkd uses
|
|
224
|
-
to track deployed resources, plus cdkd-owned asset storage (by default a
|
|
225
|
-
`cdkd-assets-{accountId}-{region}` bucket + a
|
|
226
|
-
`cdkd-container-assets-{accountId}-{region}` ECR repo; custom names via
|
|
227
|
-
`--asset-bucket` / `--container-repo`, skip with `--no-assets`; see
|
|
228
|
-
[`cdkd bootstrap`](docs/cli-reference.md#cdkd-bootstrap)). Per-region asset
|
|
229
|
-
storage is added automatically on the first `cdkd deploy` into each region.
|
|
230
|
-
Existing setups, legacy-mode opt-outs, and how this relates to `cdk bootstrap`: see
|
|
231
|
-
[Upgrading from an earlier cdkd version](#upgrading-from-an-earlier-cdkd-version).
|
|
232
|
-
|
|
233
|
-
### Upgrading from an earlier cdkd version
|
|
234
|
-
|
|
235
|
-
**No breaking change, no manual step: just deploy.** The first `cdkd deploy` into
|
|
236
|
-
each region auto-creates the cdkd-owned asset storage (interactive runs are asked
|
|
237
|
-
once per region, `--yes` / CI runs create it automatically) and shows a one-time
|
|
238
|
-
in-place UPDATE repointing asset references — content identical, no replacement.
|
|
239
|
-
Downgrading is safe too (older binaries ignore the marker). If you bootstrapped
|
|
240
|
-
under a previous cdkd version, the legacy region-suffixed state bucket name
|
|
241
|
-
(`cdkd-state-{accountId}-{region}`) is still picked up automatically with a
|
|
242
|
-
deprecation warning. Explicit pre-provisioning
|
|
243
|
-
(`cdkd bootstrap --region <r>`), legacy-mode opt-outs, and how this relates to
|
|
244
|
-
`cdk bootstrap`: see [`cdkd bootstrap`](docs/cli-reference.md#cdkd-bootstrap).
|
|
245
|
-
|
|
246
|
-
## Usage
|
|
247
|
-
|
|
248
|
-
cdkd has three command families:
|
|
249
|
-
|
|
250
|
-
- **Top-level commands** (`cdkd deploy` / `destroy` / `diff` / `synth` /
|
|
251
|
-
`list` / `import` / `orphan` / `publish-assets`) require a CDK app —
|
|
252
|
-
they synthesize a template to learn what they're operating on.
|
|
253
|
-
- **`cdkd state ...` subcommands** (`state info` / `list` / `resources`
|
|
254
|
-
/ `show` / `orphan` / `destroy` / `migrate` / `refresh-observed`)
|
|
255
|
-
operate on the S3 state bucket only and do NOT need the CDK app —
|
|
256
|
-
use them to inspect / clean up state when the source is gone or
|
|
257
|
-
you don't want to synth. `cdkd state destroy` is the CDK-app-free
|
|
258
|
-
counterpart of `cdkd destroy`.
|
|
259
|
-
- **`cdkd local ...` subcommands** (`local invoke` / `start-api` /
|
|
260
|
-
`run-task` / `start-service`) run synthesized workloads locally
|
|
261
|
-
inside Docker containers — no AWS deploy needed. Modeled on
|
|
262
|
-
`sam local *` but reads CDK state directly via `--from-state`
|
|
263
|
-
(cdkd-managed) or `--from-cfn-stack` (CFn-managed). See
|
|
264
|
-
[Local execution](#local-execution).
|
|
265
|
-
|
|
266
|
-
Options like `--app`, `--state-bucket`, and `--context` can be omitted if configured via `cdk.json` or environment variables (`CDKD_APP`, `CDKD_STATE_BUCKET`).
|
|
267
|
-
|
|
268
|
-
```bash
|
|
269
|
-
# Synth + deploy
|
|
270
|
-
cdkd synth
|
|
271
|
-
cdkd deploy # single-stack auto-detected
|
|
272
|
-
cdkd deploy MyStack # by name (or 'MyStage/Api' display path)
|
|
273
|
-
cdkd deploy --all
|
|
274
|
-
cdkd deploy --dry-run # plan only, no changes
|
|
275
|
-
cdkd deploy --no-rollback # Terraform-style: keep partial state on failure
|
|
276
|
-
cdkd rollback MyStack # revert a failed --no-rollback / interrupted deploy
|
|
277
|
-
cdkd deploy --no-wait # skip multi-minute waits (RDS / ElastiCache / NAT)
|
|
278
|
-
cdkd deploy --full-wait # also wait where cdkd's default does not (ECS steady state, CloudFront Deployed)
|
|
279
|
-
|
|
280
|
-
# Inspect what would change
|
|
281
|
-
cdkd diff MyStack
|
|
282
|
-
cdkd diff MyStack --fail # exit 1 on any change (CI gate)
|
|
283
|
-
|
|
284
|
-
# Drift detection — compare state vs AWS reality (no synth)
|
|
285
|
-
cdkd drift MyStack # exit 1 if drift
|
|
286
|
-
cdkd drift MyStack --accept --yes # state ← AWS
|
|
287
|
-
cdkd drift MyStack --revert --yes # AWS ← state
|
|
288
|
-
|
|
289
|
-
# State secret hygiene — clean + audit. Keeps cdkd state free of sensitive
|
|
290
|
-
# plaintext: a resolved secret dynamic reference is stored as its
|
|
291
|
-
# {{resolve:...}} expression. No deploy, no AWS mutation.
|
|
292
|
-
cdkd scrub MyStack # clean existing state in place
|
|
293
|
-
cdkd scrub MyStack --dry-run # audit only, report what would change
|
|
294
|
-
cdkd scrub MyStack --dry-run --fail # standing CI gate: exit 1 if plaintext remains
|
|
295
|
-
|
|
296
|
-
# Asset / destroy / unlock
|
|
297
|
-
cdkd publish-assets # synth + upload only (typical CI split)
|
|
298
|
-
cdkd destroy MyStack
|
|
299
|
-
cdkd orphan MyStack/MyBucket # drop one resource from state (AWS resource stays)
|
|
300
|
-
cdkd force-unlock MyStack # clear stale lock from an interrupted deploy / cancelled CI job
|
|
301
|
-
cdkd gc --dry-run # reclaim unreferenced cdkd-owned assets (S3 + ECR)
|
|
302
|
-
|
|
303
|
-
# Migrate between cdkd and CloudFormation
|
|
304
|
-
cdkd import MyStack --yes # adopt existing AWS resources into cdkd state
|
|
305
|
-
cdkd export MyStack # hand a cdkd-managed stack back to CloudFormation
|
|
306
|
-
|
|
307
|
-
# State-bucket-only commands (no CDK app needed)
|
|
308
|
-
cdkd state info # bucket name, region, schema version
|
|
309
|
-
cdkd state list # one row per (stackName, region)
|
|
310
|
-
cdkd state list --tree # parent → child nested-stack tree
|
|
311
|
-
cdkd state show MyStack # full state record
|
|
312
|
-
cdkd state resources MyStack # logical id / type / physical id
|
|
313
|
-
cdkd state destroy MyStack # delete AWS resources + state, no CDK app
|
|
314
|
-
cdkd state orphan MyStack # remove state record only (AWS resources stay)
|
|
315
|
-
```
|
|
316
|
-
|
|
317
|
-
See **[docs/cli-reference.md](docs/cli-reference.md)** for the full flag
|
|
318
|
-
matrix (`--concurrency`, `--no-aggressive-vpc-parallel`,
|
|
319
|
-
`--allow-unsupported-properties`, `--role-arn`, etc.), per-command details
|
|
320
|
-
including the synth-driven per-resource `cdkd orphan <constructPath>`
|
|
321
|
-
variant, and stage / wildcard pattern matching.
|
|
322
|
-
|
|
323
|
-
## `--no-wait` / `--full-wait`: choose what "done" means
|
|
324
|
-
|
|
325
|
-
CloudFront / RDS / ElastiCache / NAT Gateway / EC2 Instance / ELBv2
|
|
326
|
-
LoadBalancer typically take 1–15 minutes to fully provision. Three
|
|
327
|
-
modes, least to most waiting:
|
|
328
|
-
|
|
329
|
-
- **`--no-wait`** returns as soon as the create call returns and lets
|
|
330
|
-
AWS finish in the background.
|
|
331
|
-
- **default** waits where the wait is load-bearing (something the same
|
|
332
|
-
deploy resolves or verifies needs the settled state, or the wait can
|
|
333
|
-
surface a failure) — in practice, where CloudFormation and Terraform
|
|
334
|
-
agree, with one measured exception: CloudFront Distribution returns
|
|
335
|
-
as soon as `CreateDistribution` is accepted (nothing in-deploy needs
|
|
336
|
-
the 3–15 min edge propagation, and the wait cannot detect a failure).
|
|
337
|
-
- **`--full-wait`** additionally waits everywhere CloudFormation does
|
|
338
|
-
(today: ECS Service steady state, CloudFront Distribution
|
|
339
|
-
`Deployed`).
|
|
340
|
-
|
|
341
|
-
Pick by whether anything downstream needs the resource to actually be
|
|
342
|
-
serving, not by where the deploy runs — cutting billed CI minutes is a
|
|
343
|
-
perfectly good reason to use `--no-wait` in CI, and a local smoke test
|
|
344
|
-
(or a pipeline that wants CloudFormation-parity completion as a standing
|
|
345
|
-
setting) is a good reason to use `--full-wait`. The two flags are
|
|
346
|
-
opposite ends of one axis and cannot be combined.
|
|
347
|
-
|
|
348
|
-
**Deploy-only**: `cdkd destroy` always waits (NAT in `deleting` state
|
|
349
|
-
holds ENIs and would `DependencyViolation` sibling deletes).
|
|
350
|
-
|
|
351
|
-
See [docs/cli-reference.md](docs/cli-reference.md#wait-semantics) for
|
|
352
|
-
the per-resource table (what each mode does, next to what
|
|
353
|
-
CloudFormation and Terraform do) and caveats (NAT egress, RDS
|
|
354
|
-
final-snapshot timing, etc.).
|
|
355
|
-
|
|
356
|
-
## Use in CI: per-PR environments
|
|
357
|
-
|
|
358
|
-
Deploy time is CI job time, and a PR environment redeploys on every
|
|
359
|
-
push — so cdkd's speedup compounds across a PR's lifetime. Because
|
|
360
|
-
cdkd needs **zero CDK code changes**, you can swap only the PR-environment
|
|
361
|
-
workflow to cdkd and keep production / staging on the CDK CLI; switching
|
|
362
|
-
back is a one-line workflow revert.
|
|
363
|
-
|
|
364
|
-
Run `cdkd bootstrap` once per AWS account beforehand (creates the state
|
|
365
|
-
bucket + asset storage; `cdk bootstrap` is not required).
|
|
366
|
-
|
|
367
|
-
**One stack per PR** — pass the PR number as CDK context and suffix the
|
|
368
|
-
stack name; cdkd state is keyed by (stack name, region) and locks are
|
|
369
|
-
per-stack, so PR environments deploy concurrently without contention:
|
|
370
|
-
|
|
371
|
-
```ts
|
|
372
|
-
const prNumber = app.node.tryGetContext('prNumber');
|
|
373
|
-
new WebAppStack(app, `WebApp${prNumber ? `-pr-${prNumber}` : ''}`);
|
|
374
|
-
```
|
|
375
|
-
|
|
376
|
-
**Credentials** — cdkd calls AWS APIs directly, so the deploying
|
|
377
|
-
identity needs permissions for every deployed resource (CDK's
|
|
378
|
-
`cdk-hnb659fds-*` roles do not work: they are designed for
|
|
379
|
-
CloudFormation delegation, and cdkd uses its own bootstrap storage).
|
|
380
|
-
Create a dedicated deploy role and switch into it with
|
|
381
|
-
[`--role-arn`](docs/cli-reference.md#--role-arn) (or the
|
|
382
|
-
`CDKD_ROLE_ARN` env var): the workflow's OIDC base role needs only
|
|
383
|
-
`sts:AssumeRole` on the deploy role, and the deploy role's trust policy
|
|
384
|
-
allows only that base role — the strong permissions live in exactly one
|
|
385
|
-
place, reachable through one path, and never sit on the CI runner
|
|
386
|
-
itself.
|
|
387
|
-
|
|
388
|
-
**Minimal GitHub Actions shape** (deploy on open/sync/reopen, destroy
|
|
389
|
-
on close):
|
|
390
|
-
|
|
391
|
-
```yaml
|
|
392
|
-
on:
|
|
393
|
-
pull_request:
|
|
394
|
-
types: [opened, synchronize, reopened, closed]
|
|
395
|
-
permissions: { id-token: write, contents: read }
|
|
396
|
-
env:
|
|
397
|
-
CDKD_ROLE_ARN: arn:aws:iam::123456789012:role/cdkd-deploy-role
|
|
398
|
-
jobs:
|
|
399
|
-
deploy:
|
|
400
|
-
if: github.event.action != 'closed'
|
|
401
|
-
runs-on: ubuntu-latest
|
|
402
|
-
steps:
|
|
403
|
-
- uses: actions/checkout@v7
|
|
404
|
-
- uses: actions/setup-node@v7
|
|
405
|
-
with: { node-version: 24, cache: npm }
|
|
406
|
-
- run: npm ci
|
|
407
|
-
- uses: aws-actions/configure-aws-credentials@v6
|
|
408
|
-
with:
|
|
409
|
-
role-to-assume: arn:aws:iam::123456789012:role/github-actions-base
|
|
410
|
-
aws-region: us-east-1
|
|
411
|
-
- run: npx cdkd deploy --yes -c prNumber=${{ github.event.pull_request.number }}
|
|
412
|
-
destroy:
|
|
413
|
-
if: github.event.action == 'closed'
|
|
414
|
-
runs-on: ubuntu-latest
|
|
415
|
-
steps:
|
|
416
|
-
- uses: aws-actions/configure-aws-credentials@v6
|
|
417
|
-
with:
|
|
418
|
-
role-to-assume: arn:aws:iam::123456789012:role/github-actions-base
|
|
419
|
-
aws-region: us-east-1
|
|
420
|
-
- run: npx @go-to-k/cdkd state destroy WebApp-pr-${{ github.event.pull_request.number }} --yes
|
|
421
|
-
```
|
|
422
|
-
|
|
423
|
-
The destroy job has no checkout, `npm ci`, or synth —
|
|
424
|
-
[`cdkd state destroy`](#orphan-vs-destroy) deletes from the state
|
|
425
|
-
record alone, so it works even after the branch is gone.
|
|
426
|
-
|
|
427
|
-
If the environment contains protection-enabled resources (RDS /
|
|
428
|
-
DynamoDB deletion protection, EC2 termination protection, and more),
|
|
429
|
-
add [`--remove-protection`](#--remove-protection-one-shot-bypass-for-protected-resources)
|
|
430
|
-
to the destroy so the teardown completes in one pass — an ephemeral PR
|
|
431
|
-
environment has nothing worth protecting, and without the flag those
|
|
432
|
-
resources survive the job and linger until the next sweep.
|
|
433
|
-
|
|
434
|
-
Two more teardown-completeness flags matter for disposable
|
|
435
|
-
environments: resources with `DeletionPolicy: Snapshot` leave a final
|
|
436
|
-
snapshot behind on every PR close by default — add
|
|
437
|
-
[`--skip-final-snapshot`](#deletionpolicy-snapshot-final-snapshots-on-delete)
|
|
438
|
-
when the environment's data is disposable, so snapshots don't
|
|
439
|
-
accumulate per closed PR. And `cdkd destroy --purge-events` also
|
|
440
|
-
removes the stack's deployment-event history so the state bucket
|
|
441
|
-
returns fully empty (after a `state destroy`, the equivalent is
|
|
442
|
-
`cdkd events prune <stack> --all`).
|
|
443
|
-
|
|
444
|
-
**Housekeeping**:
|
|
445
|
-
|
|
446
|
-
- Pick the wait mode from what runs next (see the section above):
|
|
447
|
-
review-only environments can use `--no-wait`; E2E tests after the
|
|
448
|
-
deploy should keep the default, or `--full-wait` when they need ECS
|
|
449
|
-
steady state / CloudFront propagation.
|
|
450
|
-
- A job cancelled mid-deploy (e.g. `concurrency.cancel-in-progress`)
|
|
451
|
-
can leave a stack lock; it expires on its own TTL (30 minutes), or
|
|
452
|
-
run `cdkd force-unlock <stack>` to clear it immediately.
|
|
453
|
-
- Sweep forgotten environments with `cdkd state list --json` on a
|
|
454
|
-
schedule, and reclaim unreferenced assets with
|
|
455
|
-
`cdkd gc --older-than 30d --dry-run` — `gc` aborts if any stack is
|
|
456
|
-
locked, so schedule it outside deploy hours.
|
|
457
|
-
- To comment the environment URL on the PR, read stack outputs with
|
|
458
|
-
`cdkd state show <stack> --json`.
|
|
459
|
-
- To gate a PR without deploying, `cdkd diff --fail` exits `1` when any
|
|
460
|
-
change is detected (and `cdkd drift --json` machine-checks live
|
|
461
|
-
divergence). See [Exit codes](#exit-codes) for per-command semantics.
|
|
462
|
-
|
|
463
|
-
## Rollback behavior
|
|
464
|
-
|
|
465
|
-
When a deploy fails mid-stack (e.g. a resource hits a validation error
|
|
466
|
-
or AWS rejects the request), cdkd by default **rolls back the
|
|
467
|
-
already-completed resources in the same deploy** so the stack state
|
|
468
|
-
stays consistent — every resource cdkd just created in this run is
|
|
469
|
-
deleted in reverse dependency order, the state record is updated to
|
|
470
|
-
match, and the CLI exits non-zero. Resources that existed before this
|
|
471
|
-
deploy are NOT touched.
|
|
472
|
-
|
|
473
|
-
Pass `cdkd deploy --no-rollback` to skip the rollback (Terraform-style:
|
|
474
|
-
the partial state is preserved so you can `cdkd state show <stack>`,
|
|
475
|
-
inspect what landed, fix the underlying issue, and re-run `cdkd deploy`
|
|
476
|
-
to continue from the half-deployed state). Recommended only when you
|
|
477
|
-
plan to manually inspect / repair; the default is safer for CI.
|
|
478
|
-
|
|
479
|
-
Mid-deploy state is also saved per-resource as work completes, so even
|
|
480
|
-
if cdkd itself crashes between the failure and the rollback, the state
|
|
481
|
-
file accurately reflects what's on AWS and a follow-up `cdkd destroy`
|
|
482
|
-
won't orphan anything.
|
|
483
|
-
|
|
484
|
-
### `cdkd rollback` — revert a failed deploy
|
|
485
|
-
|
|
486
|
-
After a `--no-rollback` failure (or a Ctrl+C-interrupted deploy, or an
|
|
487
|
-
automatic rollback that itself died partway), you have three options:
|
|
488
|
-
fix forward (`cdkd deploy` again), revert (`cdkd rollback`), or clean up
|
|
489
|
-
(`cdkd destroy`). The standalone `cdkd rollback` command is the "revert"
|
|
490
|
-
option — the cdkd equivalent of `cdk rollback` / CloudFormation
|
|
491
|
-
`RollbackStack`:
|
|
492
|
-
|
|
493
|
-
```bash
|
|
494
|
-
cdkd rollback MyStack # revert MyStack to its pre-deploy state
|
|
495
|
-
cdkd rollback # single journaled stack (no arg)
|
|
496
|
-
cdkd rollback MyStack --force # skip the confirmation prompt
|
|
497
|
-
```
|
|
498
|
-
|
|
499
|
-
It works from a **rollback journal** cdkd writes to
|
|
500
|
-
`s3://bucket/cdkd/{stack}/{region}/rollback-journal.json` (a sibling of
|
|
501
|
-
`state.json`) whenever a deploy ends without a completed rollback — the
|
|
502
|
-
journal records the exact operations that completed, so `cdkd rollback`
|
|
503
|
-
replays them in reverse (deleting created resources, restoring updated
|
|
504
|
-
ones) with no synth and no CDK app needed. It is **synth-free** on
|
|
505
|
-
purpose: a broken app is a common reason you want to roll back. The
|
|
506
|
-
journal is deleted automatically on the next successful deploy and by
|
|
507
|
-
`cdkd destroy`; after a clean automatic rollback it keeps only the
|
|
508
|
-
failed resource's record so `cdkd rollback --revert-failed` still works
|
|
509
|
-
in the default deploy flow.
|
|
510
|
-
|
|
511
|
-
Flags: `--force` (skip confirm), `--orphan <logicalId>` (repeatable —
|
|
512
|
-
leave the resource alone during replay, like `cdk rollback --orphan`),
|
|
513
|
-
`--revert-failed` (also attempt to revert the resource whose operation
|
|
514
|
-
FAILED mid-deploy — off by default because its remote state is unknown; its
|
|
515
|
-
delete honors `DeletionPolicy` the same way a completed CREATE's does),
|
|
516
|
-
`--stack-region <region>` (disambiguate a same-named stack across
|
|
517
|
-
regions), `--role-arn`, `--state-bucket`. A **replacement** is reverted
|
|
518
|
-
by reversing it: the old resource is re-created from its journaled
|
|
519
|
-
pre-deploy state and the new one deleted (for a stateful type the old
|
|
520
|
-
data is unrecoverable — warned loudly). Exit codes: `0` = fully clean
|
|
521
|
-
(journal deleted), `2` = partial (some ops failed / were skipped — the
|
|
522
|
-
journal is kept so you can re-run), `1` = hard error. See
|
|
523
|
-
[docs/cli-reference.md](docs/cli-reference.md#cdkd-rollback) for the
|
|
524
|
-
full reference and known limitations (a DELETE that already happened
|
|
525
|
-
cannot be restored).
|
|
526
|
-
|
|
527
|
-
## Importing existing resources
|
|
528
|
-
|
|
529
|
-
`cdkd import` adopts AWS resources that are already deployed (via
|
|
530
|
-
`cdk deploy`, manual creation, or another tool) into cdkd state so the
|
|
531
|
-
next `cdkd deploy` updates them in-place instead of CREATEing duplicates.
|
|
532
|
-
|
|
533
|
-
`cdkd import --migrate-from-cloudformation` extends this to migrate a
|
|
534
|
-
**whole CloudFormation stack** off CFn in a single command: cdkd reads
|
|
535
|
-
the source CFn stack's `(logicalId, physicalId)` mappings, adopts every
|
|
536
|
-
resource into cdkd state, then retires the source CFn stack (injects
|
|
537
|
-
`DeletionPolicy: Retain` + `UpdateReplacePolicy: Retain` on every
|
|
538
|
-
resource → `UpdateStack` → `DeleteStack`) so the AWS resources stay
|
|
539
|
-
intact but are no longer tracked by CFn. After the command finishes,
|
|
540
|
-
the stack is managed by `cdkd deploy`. This is the reverse direction
|
|
541
|
-
of `cdkd export` (see below).
|
|
542
|
-
|
|
543
|
-
```bash
|
|
544
|
-
# Adopt a whole stack: each resource is resolved from its template name property,
|
|
545
|
-
# then from a same-named CloudFormation stack (#1128). Use
|
|
546
|
-
# --migrate-from-cloudformation below when you also want that stack retired.
|
|
547
|
-
cdkd import MyStack --yes
|
|
548
|
-
|
|
549
|
-
# Adopt only specific resources (CDK CLI parity).
|
|
550
|
-
cdkd import MyStack --resource MyBucket=my-bucket-name
|
|
551
|
-
|
|
552
|
-
# Some types use a composite, `|`-delimited physical id — quote it.
|
|
553
|
-
# Full per-type table: docs/state-management.md#composite-pipe-delimited-physicalids
|
|
554
|
-
cdkd import MyStack --resource 'MyGlueTable=my_database|my_table'
|
|
555
|
-
|
|
556
|
-
# Migrate off CloudFormation in one shot — adopt + retire the source CFn stack.
|
|
557
|
-
cdkd import MyStack --migrate-from-cloudformation --yes
|
|
558
|
-
```
|
|
559
|
-
|
|
560
|
-
See **[docs/import.md](docs/import.md)** for the full guide: three import
|
|
561
|
-
modes (auto / selective / hybrid), `--resource-mapping` CDK CLI
|
|
562
|
-
compatibility, CloudFormation migration flow, provider coverage, and the
|
|
563
|
-
parity matrix vs upstream `cdk import`.
|
|
564
|
-
|
|
565
|
-
## Exporting a stack back to CloudFormation
|
|
566
|
-
|
|
567
|
-
`cdkd export` is the mirror of `cdkd import`: it hands a cdkd-managed
|
|
568
|
-
stack back to CloudFormation via a CFn `ChangeSetType=IMPORT` changeset.
|
|
569
|
-
AWS resources are unchanged across the migration; cdkd state for the
|
|
570
|
-
exported stack is deleted on success. From then on the stack is managed
|
|
571
|
-
by `cdk deploy` / `aws cloudformation`. Accepts JSON and YAML templates
|
|
572
|
-
(shorthand intrinsics round-trip).
|
|
573
|
-
|
|
574
|
-
```bash
|
|
575
|
-
cdkd export MyStack # confirmation prompt; CFn stack name = cdkd stack name
|
|
576
|
-
cdkd export MyStack --cfn-stack-name MyStack-CFn
|
|
577
|
-
cdkd export MyStack --dry-run # print the import plan, do not call CFn
|
|
578
|
-
cdkd export MyStack --include-non-importable # 2-phase: IMPORT importable + CFn-CREATE Custom Resources
|
|
579
|
-
cdkd export MyApp # nested-stack tree: leaf-first per-stack IMPORT loop
|
|
580
|
-
```
|
|
581
|
-
|
|
582
|
-
**Lambda-backed Custom Resources** (`Custom::*` /
|
|
583
|
-
`AWS::CloudFormation::CustomResource`) are NOT directly CFn-importable.
|
|
584
|
-
`--include-non-importable` opts into a 2-phase migration that re-CREATEs
|
|
585
|
-
them through CFn — the Custom Resource Lambda must be idempotent.
|
|
586
|
-
**Nested stacks** are supported via a leaf-first per-stack IMPORT loop
|
|
587
|
-
(AWS rejects `--include-nested-stacks` for IMPORT changesets).
|
|
588
|
-
**Some resource types CloudFormation cannot import at all** (`AWS::Glue::Table`,
|
|
589
|
-
`AWS::Route53::RecordSet` / `::RecordSetGroup`, `AWS::AppSync::ApiKey`,
|
|
590
|
-
`AWS::EC2::NetworkAclEntry`, `AWS::SQS::QueuePolicy`,
|
|
591
|
-
`AWS::SNS::TopicPolicy`, …). cdkd detects those from the resource type's
|
|
592
|
-
CloudFormation registry schema and names every affected resource at once —
|
|
593
|
-
before acquiring the stack lock, and before submitting anything — so you fix
|
|
594
|
-
them in one pass instead of one per re-run.
|
|
595
|
-
`--skip-import-support-preflight` bypasses the check if AWS has since made a
|
|
596
|
-
type importable.
|
|
597
|
-
|
|
598
|
-
See **[docs/import.md](docs/import.md)** for the full guide — Custom Resource
|
|
599
|
-
2-phase flow, nested-stack adoption mechanics (`--cfn-child-stack-name`
|
|
600
|
-
per-child overrides, AWS's "Nest an existing stack" pattern), and the
|
|
601
|
-
design rationale at [docs/design/464-nested-stacks-export-import.md](docs/design/464-nested-stacks-export-import.md).
|
|
602
|
-
|
|
603
|
-
## Reference CloudFormation-managed stacks (mixed estates)
|
|
604
|
-
|
|
605
|
-
You don't have to migrate a producer stack to reference it. When an
|
|
606
|
-
`Fn::ImportValue` / `Fn::GetStackOutput` reference is not found in cdkd
|
|
607
|
-
state, cdkd falls back to CloudFormation — `ListExports` for
|
|
608
|
-
`Fn::ImportValue` (CFn's own semantic for the intrinsic), the stack's
|
|
609
|
-
outputs via `DescribeStacks` for `Fn::GetStackOutput` — so a
|
|
610
|
-
cdkd-deployed stack can consume values from a stack still managed by
|
|
611
|
-
`cdk deploy` / raw CloudFormation, with zero changes on the producer
|
|
612
|
-
side.
|
|
613
|
-
|
|
614
|
-
This makes the recommended split work out of the box: shared
|
|
615
|
-
infrastructure (VPC, domains, IAM) stays on the CDK CLI, while dev/test
|
|
616
|
-
app stacks iterate via cdkd.
|
|
617
|
-
|
|
618
|
-
```typescript
|
|
619
|
-
// Producer: deployed with `cdk deploy` (stays CloudFormation-managed).
|
|
620
|
-
new cdk.CfnOutput(this, 'SharedVpcId', {
|
|
621
|
-
value: vpc.vpcId,
|
|
622
|
-
exportName: 'SharedVpcId',
|
|
623
|
-
});
|
|
624
|
-
|
|
625
|
-
// Consumer: deployed with `cdkd deploy`. Resolution order is cdkd state
|
|
626
|
-
// first, then CloudFormation — same syntax either way.
|
|
627
|
-
const vpcId = cdk.Fn.importValue('SharedVpcId');
|
|
628
|
-
```
|
|
629
|
-
|
|
630
|
-
How it behaves:
|
|
631
|
-
|
|
632
|
-
- **cdkd-first precedence.** The fallback fires only after cdkd state
|
|
633
|
-
misses, so cdkd-to-cdkd references are untouched and a name collision
|
|
634
|
-
resolves to the cdkd export.
|
|
635
|
-
- **Weak reference.** A CFn-sourced value is not recorded into cdkd
|
|
636
|
-
state, and neither engine blocks deleting the CFn producer while cdkd
|
|
637
|
-
consumers reference it (CloudFormation's export-in-use protection
|
|
638
|
-
cannot see cdkd consumers). Check downstream consumers before deleting
|
|
639
|
-
a producer.
|
|
640
|
-
- **IAM**: the deploying credentials need `cloudformation:ListExports` /
|
|
641
|
-
`cloudformation:DescribeStacks` for the fallback. Without them, cdkd
|
|
642
|
-
warns and fails with the ordinary not-found error.
|
|
643
|
-
- **Opt-out**: `--no-cfn-fallback` (on `deploy` / `diff`) pins
|
|
644
|
-
cdkd-state-only resolution — minimal IAM, and an export-name typo
|
|
645
|
-
fails fast instead of matching an unrelated CloudFormation export.
|
|
646
|
-
- This also works mid-migration: after `cdkd export` hands a producer
|
|
647
|
-
back to CloudFormation, remaining cdkd consumers keep resolving its
|
|
648
|
-
outputs through the fallback (no leaf-first ordering requirement).
|
|
649
|
-
|
|
650
|
-
See **[docs/cross-stack-references.md](docs/cross-stack-references.md)**
|
|
651
|
-
for the full design (resolution order, weak-vs-strong reference
|
|
652
|
-
semantics, cross-region / cross-account forms).
|
|
653
|
-
|
|
654
|
-
## Drift detection
|
|
655
|
-
|
|
656
|
-
`cdkd drift` (state-driven; no synth) compares each managed resource
|
|
657
|
-
against AWS reality and reports divergence — including console-side
|
|
658
|
-
changes to keys you did NOT template (S3 public-access-block, IAM Role
|
|
659
|
-
tags, Lambda env keys, etc.).
|
|
660
|
-
|
|
661
|
-
```bash
|
|
662
|
-
cdkd drift # auto-detect single stack, exit 1 if drift
|
|
663
|
-
cdkd drift MyStack --json # machine-readable, for CI gating
|
|
664
|
-
cdkd drift MyStack --accept --yes # state ← AWS (catch up after a console edit)
|
|
665
|
-
cdkd drift MyStack --revert --yes # AWS ← state (undo a console edit)
|
|
666
|
-
cdkd state refresh-observed MyStack # populate the drift baseline without redeploying
|
|
667
|
-
```
|
|
668
|
-
|
|
669
|
-
See **[docs/cli-reference.md `cdkd drift`](docs/cli-reference.md#cdkd-drift)**
|
|
670
|
-
for the full reference: `--no-capture-observed-state` deploy opt-out
|
|
671
|
-
(per-command vs per-project, mid-flight reversibility), v2→v3 state
|
|
672
|
-
upgrade flow, exit codes, and what changes when capture is off.
|
|
673
|
-
|
|
674
|
-
## Orphan vs destroy
|
|
675
|
-
|
|
676
|
-
`destroy` deletes the AWS resources **and** the state record;
|
|
677
|
-
`orphan` deletes **only** the state record (AWS resources stay
|
|
678
|
-
intact, just no longer tracked by cdkd). Mirrors aws-cdk-cli's
|
|
679
|
-
`cdk orphan`.
|
|
680
|
-
|
|
681
|
-
Two `orphan` variants at different granularities:
|
|
682
|
-
|
|
683
|
-
- `cdkd orphan <constructPath>...` — synth-driven, **per-resource**.
|
|
684
|
-
Rewrites every sibling reference (Ref / Fn::GetAtt / Fn::Sub /
|
|
685
|
-
dependencies) so the next deploy doesn't re-create the orphan.
|
|
686
|
-
- `cdkd state orphan <stack>...` — state-driven, **whole-stack**.
|
|
687
|
-
Removes the entire state record. Works without the CDK app.
|
|
688
|
-
|
|
689
|
-
Both `cdkd destroy` (synth-driven) and `cdkd state destroy`
|
|
690
|
-
(state-driven, no synth) delete AWS resources + state.
|
|
691
|
-
|
|
692
|
-
## VPC route DependsOn relaxation (on by default)
|
|
693
|
-
|
|
694
|
-
CDK injects defensive `DependsOn` from VPC Lambdas onto private-subnet
|
|
695
|
-
routes. The dependency is real at runtime but NOT required at deploy
|
|
696
|
-
time. cdkd drops it by default so CloudFront + Lambda::Url propagation
|
|
697
|
-
runs in parallel with NAT stabilization (~50% faster on VPC+Lambda+CloudFront
|
|
698
|
-
stacks; bench-cdk-sample 398s → 181s). Pass
|
|
699
|
-
`cdkd deploy --no-aggressive-vpc-parallel` to opt out (e.g. when a
|
|
700
|
-
Custom Resource synchronously invokes a VPC Lambda outside cdkd's
|
|
701
|
-
Lambda-ServiceToken Active wait).
|
|
702
|
-
|
|
703
|
-
See [docs/cli-reference.md](docs/cli-reference.md) for the full
|
|
704
|
-
type-pair allowlist and trade-off notes.
|
|
705
|
-
|
|
706
|
-
## `DeletionPolicy: Snapshot`: final snapshots on delete
|
|
707
|
-
|
|
708
|
-
Matching CloudFormation, cdkd creates a **final snapshot before deleting**
|
|
709
|
-
a resource whose `DeletionPolicy` is `Snapshot` (the CDK RDS L2 defaults
|
|
710
|
-
`removalPolicy` to `SNAPSHOT`) — and, on replacements, one whose
|
|
711
|
-
`UpdateReplacePolicy` is `Snapshot`: RDS DBInstance / DBCluster,
|
|
712
|
-
Neptune / DocDB clusters and ElastiCache CacheCluster delete via the API's
|
|
713
|
-
atomic final-snapshot parameter; EC2 Volumes, Redshift Clusters and
|
|
714
|
-
ElastiCache ReplicationGroups get a pre-delete snapshot waited to
|
|
715
|
-
completion. The full CFn-documented Snapshot-capable type list is covered.
|
|
716
|
-
Pass `--skip-final-snapshot` (on `deploy` / `destroy` / `state destroy` /
|
|
717
|
-
`rollback`) to delete without the snapshot (explicit data-loss opt-out for
|
|
718
|
-
dev/test stacks). Rolling a CREATE back is a delete too, so the policy
|
|
719
|
-
applies there as well — for a resource whose CREATE completed and, under
|
|
720
|
-
`--revert-failed`, for one whose CREATE failed after AWS provisioned it. See the "DeletionPolicy: Snapshot" section in
|
|
721
|
-
[docs/cli-reference.md](docs/cli-reference.md).
|
|
722
|
-
|
|
723
|
-
## `--remove-protection`: one-shot bypass for protected resources
|
|
724
|
-
|
|
725
|
-
`cdkd destroy --remove-protection` (and `cdkd state destroy --remove-protection`)
|
|
726
|
-
flips every protection flag off in-place before each provider's delete
|
|
727
|
-
API call, so a destroy proceeds without an intermediate edit / redeploy.
|
|
728
|
-
Covers stack-level `terminationProtection` (logged as a WARN) AND
|
|
729
|
-
resource-level protection on these types:
|
|
730
|
-
|
|
731
|
-
| Resource type | Protection field |
|
|
732
|
-
| --- | --- |
|
|
733
|
-
| `AWS::Logs::LogGroup` | `DeletionProtectionEnabled` |
|
|
734
|
-
| `AWS::RDS::DBInstance` | `DeletionProtection` |
|
|
735
|
-
| `AWS::RDS::DBCluster` | `DeletionProtection` |
|
|
736
|
-
| `AWS::DocDB::DBCluster` | `DeletionProtection` (DocDB DBInstance has no `DeletionProtection` field, so per-instance bypass is a no-op) |
|
|
737
|
-
| `AWS::Neptune::DBCluster` | `DeletionProtection` |
|
|
738
|
-
| `AWS::Neptune::DBInstance` | `DeletionProtection` |
|
|
739
|
-
| `AWS::DynamoDB::Table` | `DeletionProtectionEnabled` |
|
|
740
|
-
| `AWS::DynamoDB::GlobalTable` | `DeletionProtectionEnabled` (CDK v2 `dynamodb.TableV2`) |
|
|
741
|
-
| `AWS::EC2::Instance` | `DisableApiTermination` |
|
|
742
|
-
| `AWS::ElasticLoadBalancingV2::LoadBalancer` | attribute `deletion_protection.enabled` |
|
|
743
|
-
| `AWS::Cognito::UserPool` | `DeletionProtection` (`ACTIVE` / `INACTIVE`) |
|
|
744
|
-
| `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 |
|
|
745
|
-
| `AWS::DSQL::Cluster` | `DeletionProtectionEnabled` (flipped via a Cloud Control `UpdateResource` patch before delete) |
|
|
746
|
-
| `AWS::NeptuneGraph::Graph` | `DeletionProtection` (same Cloud Control patch flip) |
|
|
747
|
-
| `AWS::SMSVOICE::ProtectConfiguration` | `DeletionProtectionEnabled` (same Cloud Control patch flip) |
|
|
748
|
-
| `AWS::VerifiedPermissions::PolicyStore` | `DeletionProtection` `{Mode}` (patched to `{Mode: DISABLED}`) |
|
|
749
|
-
| `AWS::EKS::Cluster` | `DeletionProtection` (same Cloud Control patch flip) |
|
|
750
|
-
| `AWS::RDS::GlobalCluster` | `DeletionProtection` (same Cloud Control patch flip) |
|
|
751
|
-
| `AWS::DocDB::GlobalCluster` | `DeletionProtection` (same Cloud Control patch flip) |
|
|
752
|
-
|
|
753
|
-
A single `--remove-protection` covers every type listed above (no
|
|
754
|
-
per-type variant). The interactive confirm prompt switches to
|
|
755
|
-
`y/N` (requiring an explicit `y` for the destructive bypass);
|
|
756
|
-
`--yes` / `-y` / `-f` skips it.
|
|
757
|
-
|
|
758
|
-
Out of scope: types where AWS doesn't expose a synchronous "flip
|
|
759
|
-
protection off" API call (CloudFront Distributions, Lambda function
|
|
760
|
-
reserved concurrency, S3 bucket retention, etc.).
|
|
761
|
-
|
|
762
|
-
## `publish-assets`: synth + build + publish, no deploy
|
|
763
|
-
|
|
764
|
-
`cdkd publish-assets` runs the asset half of the deploy pipeline
|
|
765
|
-
only — synthesize, build Docker images, upload file assets to S3,
|
|
766
|
-
push images to ECR — and stops. No state writes, no provisioning.
|
|
767
|
-
Typical CI split where one runner builds + uploads assets and a
|
|
768
|
-
separate runner deploys.
|
|
769
|
-
|
|
770
|
-
```bash
|
|
771
|
-
cdkd publish-assets # all stacks (or auto-detect single stack)
|
|
772
|
-
cdkd publish-assets MyStack # specific stack
|
|
773
|
-
cdkd publish-assets -a cdk.out # skip synth, use pre-synthesized assembly
|
|
774
|
-
```
|
|
775
|
-
|
|
776
|
-
See [docs/cli-reference.md](docs/cli-reference.md#publish-assets-synth--build--publish-no-deploy)
|
|
777
|
-
for stack-selection rules and concurrency knobs.
|
|
778
|
-
|
|
779
|
-
## Compatibility
|
|
780
|
-
|
|
781
|
-
cdkd supports the standard CloudFormation surface — intrinsic functions,
|
|
782
|
-
pseudo parameters, parameters / conditions, cross-stack / cross-region
|
|
783
|
-
references, asset publishing, custom resources, and so on. Cross-stack
|
|
784
|
-
references also work against producer stacks still managed by
|
|
785
|
-
CloudFormation (see
|
|
786
|
-
["Reference CloudFormation-managed stacks"](#reference-cloudformation-managed-stacks-mixed-estates)
|
|
787
|
-
above). See
|
|
788
|
-
**[docs/supported-features.md](docs/supported-features.md)** for the
|
|
789
|
-
full reference. For per-resource-type provisioning support (SDK Providers
|
|
790
|
-
vs Cloud Control API fallback), see
|
|
791
|
-
**[docs/supported-resources.md](docs/supported-resources.md)**.
|
|
792
|
-
|
|
793
|
-
**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).
|
|
794
|
-
|
|
795
|
-
## State Management
|
|
796
|
-
|
|
797
|
-
State is stored in S3 with optimistic locking via S3 Conditional Writes
|
|
798
|
-
(no DynamoDB required). Keys are scoped by `(stackName, region)` so the
|
|
799
|
-
same stack deployed to two regions has two independent state files.
|
|
800
|
-
|
|
801
|
-
**You do not create this bucket yourself** — `cdkd bootstrap` creates it once
|
|
802
|
-
per account (see [Prerequisites](#prerequisites)), with versioning, AES-256
|
|
803
|
-
encryption, and a deny-external-access bucket policy. The settings below are
|
|
804
|
-
only for pointing cdkd at a non-default name; pass that same name to
|
|
805
|
-
`cdkd bootstrap --state-bucket` so bootstrap creates it for you there too.
|
|
806
|
-
|
|
807
|
-
| Setting | CLI | cdk.json | Env var | Default |
|
|
808
|
-
|---------|-----|----------|---------|---------|
|
|
809
|
-
| Bucket | `--state-bucket` | `context.cdkd.stateBucket` | `CDKD_STATE_BUCKET` | `cdkd-state-{accountId}` (legacy `cdkd-state-{accountId}-{region}` is still read with a deprecation warning — run `cdkd state migrate` to consolidate) |
|
|
810
|
-
| Prefix | `--state-prefix` | - | - | `cdkd` |
|
|
811
|
-
|
|
812
|
-
The state bucket is shared across all CDK apps in the same account by
|
|
813
|
-
default. To isolate apps, pass different `--state-prefix` values.
|
|
814
|
-
`cdkd destroy --all` only targets stacks from the current CDK app
|
|
815
|
-
(determined by synthesis), not all stacks in the bucket.
|
|
816
|
-
|
|
817
|
-
See **[docs/state-management.md](docs/state-management.md)** for the full
|
|
818
|
-
spec: S3 key layout, optimistic-locking mechanism (ETag-based), state
|
|
819
|
-
schema, legacy `version: 1` migration, bucket-name migration via
|
|
820
|
-
`cdkd state migrate`, and troubleshooting.
|
|
821
|
-
|
|
822
|
-
## Deployment events (`cdkd events`)
|
|
823
|
-
|
|
824
|
-
Every `cdkd deploy` / `cdkd destroy` run records a structured event
|
|
825
|
-
stream to S3 — cdkd's local equivalent of CloudFormation's
|
|
826
|
-
`DescribeStackEvents`. Read it back with `cdkd events <stack>`:
|
|
827
|
-
|
|
828
|
-
```bash
|
|
829
|
-
cdkd events MyStack # list runs, newest first
|
|
830
|
-
cdkd events MyStack --run <runId> # one run's full event stream
|
|
831
|
-
cdkd events MyStack --format json # machine-readable (AI-agent hand-off)
|
|
832
|
-
cdkd events prune MyStack --all # purge event history (reclaim S3 space)
|
|
833
|
-
cdkd destroy MyStack --purge-events # destroy + purge events in one command
|
|
834
|
-
```
|
|
835
|
-
|
|
836
|
-
Events are persisted as JSONL under a `deployments/` key family separate
|
|
837
|
-
from `state.json` (no state schema bump), so a destroyed stack's failure
|
|
838
|
-
history stays readable. Recording is best-effort and never blocks the
|
|
839
|
-
run; events carry error + metadata only (never resource properties). The
|
|
840
|
-
store self-bounds to the last 20 runs, `cdkd events prune` purges old
|
|
841
|
-
history on demand (`--keep N` / `--older-than <dur>` / `--all`), and
|
|
842
|
-
`cdkd destroy --purge-events` deletes a stack's history right after a clean
|
|
843
|
-
destroy so the bucket returns fully empty. See
|
|
844
|
-
**[docs/deployment-events.md](docs/deployment-events.md)** for the full
|
|
845
|
-
reference.
|
|
846
|
-
|
|
847
|
-
## Stack Outputs
|
|
848
|
-
|
|
849
|
-
CDK's `CfnOutput` constructs are resolved and stored in the state file:
|
|
850
|
-
|
|
851
|
-
```typescript
|
|
852
|
-
// In your CDK code
|
|
853
|
-
new cdk.CfnOutput(this, 'BucketArn', {
|
|
854
|
-
value: bucket.bucketArn, // Uses Fn::GetAtt internally
|
|
855
|
-
description: 'ARN of the bucket',
|
|
856
|
-
});
|
|
857
|
-
```
|
|
858
|
-
|
|
859
|
-
After deployment, outputs are resolved and printed at the end of `cdkd deploy` (matching CDK CLI's format) and saved to the S3 state file:
|
|
860
|
-
|
|
861
|
-
```text
|
|
862
|
-
Deployment Summary:
|
|
863
|
-
Stack: MyStack
|
|
864
|
-
...
|
|
865
|
-
Duration: 21.25s
|
|
866
|
-
|
|
867
|
-
Outputs:
|
|
868
|
-
MyStack.BucketArn = arn:aws:s3:::actual-bucket-name-xyz
|
|
869
|
-
|
|
870
|
-
✓ Deployment completed successfully
|
|
871
|
-
```
|
|
872
|
-
|
|
873
|
-
```json
|
|
874
|
-
{
|
|
875
|
-
"outputs": {
|
|
876
|
-
"BucketArn": "arn:aws:s3:::actual-bucket-name-xyz"
|
|
877
|
-
}
|
|
878
|
-
}
|
|
879
|
-
```
|
|
880
|
-
|
|
881
|
-
**Key differences from CloudFormation**:
|
|
882
|
-
|
|
883
|
-
- CloudFormation: Outputs accessible via `aws cloudformation describe-stacks`
|
|
884
|
-
- cdkd: Outputs saved in S3 state file (e.g., `s3://bucket/cdkd/MyStack/us-east-1/state.json`)
|
|
885
|
-
- Both print outputs to stdout after a successful deploy
|
|
886
|
-
- Both resolve intrinsic functions (Ref, Fn::GetAtt, etc.) to actual values
|
|
887
|
-
|
|
888
|
-
## Exit codes
|
|
889
|
-
|
|
890
|
-
cdkd commands distinguish three outcomes via the process exit code so
|
|
891
|
-
CI / bench scripts can react without grepping log output:
|
|
892
|
-
|
|
893
|
-
| Exit | Meaning |
|
|
894
|
-
|------|---------|
|
|
895
|
-
| `0` | Success — command completed and no resources are in an error state |
|
|
896
|
-
| `1` | Command-level failure — auth error, bad arguments, synth crash, unhandled exception |
|
|
897
|
-
| `2` | **Partial failure** — work completed but one or more resources failed or was SKIPPED (state.json is preserved, re-running typically resolves it) |
|
|
898
|
-
|
|
899
|
-
Exit `2` is emitted by `cdkd destroy` and `cdkd state
|
|
900
|
-
destroy` when one or more per-resource deletes fail. The summary line
|
|
901
|
-
also switches from `✓ Stack X destroyed` to `⚠ Stack X partially
|
|
902
|
-
destroyed (...). State preserved — re-run 'cdkd destroy' / 'cdkd
|
|
903
|
-
state destroy' to clean up.` so the visual marker matches the exit
|
|
904
|
-
code.
|
|
905
|
-
|
|
906
|
-
A per-resource **skip** exits `2` as well: `⚠ MyTable (AWS::Glue::Table)
|
|
907
|
-
skipped (...)` plus `(4 deleted, 1 skipped, 0 errors)` means cdkd could not
|
|
908
|
-
address that resource, issued no AWS call, and therefore left it in place —
|
|
909
|
-
so the state record is deliberately KEPT rather than dropped. See
|
|
910
|
-
[docs/cli-reference.md](docs/cli-reference.md#skipped-resources-on-destroy-issue-1752).
|
|
911
|
-
|
|
912
|
-
One figure on that line does **not** mean exit `2`: `N unverified` (issue
|
|
913
|
-
[#2301](https://github.com/go-to-k/cdkd/issues/2301)). It counts pre-flight
|
|
914
|
-
safety guards that ran, could not reach a verdict, and were therefore not
|
|
915
|
-
enforced — cdkd proceeded, and the resource really was deleted, so
|
|
916
|
-
`(1 deleted, 1 unverified, 0 errors)` exits `0`. It is there because such a
|
|
917
|
-
guard is disabled by DENYING the permission its probe needs, and the warning
|
|
918
|
-
cdkd prints does not survive the run; the durable half is a
|
|
919
|
-
`RESOURCE_GUARD_INDETERMINATE` event
|
|
920
|
-
([docs/deployment-events.md](docs/deployment-events.md)).
|
|
921
|
-
|
|
922
|
-
`cdkd deploy` exits `2` for the same class of outcome (issue
|
|
923
|
-
[#1960](https://github.com/go-to-k/cdkd/issues/1960)) — it finished, nothing
|
|
924
|
-
failed, and yet a resource cdkd was responsible for may still be alive in AWS:
|
|
925
|
-
|
|
926
|
-
| Summary row | What survived | Recovers on its own? |
|
|
927
|
-
|---|---|---|
|
|
928
|
-
| `Skipped (not deleted): N` | a resource removed from the template whose provider could not issue the delete | **Yes** — the state record is kept, so the next `cdkd deploy` re-attempts it |
|
|
929
|
-
| `of which left an orphaned predecessor: N` | the OLD resource of a replacement (e.g. an ACM certificate a CloudFront distribution still references) | **No** — state now points at the replacement, so nothing will retry it; delete it by hand |
|
|
930
|
-
|
|
931
|
-
A run that left a resource unaddressed also stops printing
|
|
932
|
-
`✓ Deployment completed successfully` — it prints a `⚠ Stack X deployed, but N
|
|
933
|
-
resource(s) were left unaddressed` warning instead, and records
|
|
934
|
-
`result: 'FAILED'` in `cdkd events` (matching destroy). **A pipeline grepping
|
|
935
|
-
the log for the success string breaks on this independently of the exit code.**
|
|
936
|
-
|
|
937
|
-
Pass `--allow-unaddressed` to exit `0` instead. The summary rows, the
|
|
938
|
-
per-resource warnings, the `⚠` banner and the `FAILED` run record all survive
|
|
939
|
-
it, because they record what happened rather than what the operator chose to
|
|
940
|
-
tolerate. It does suppress the run-level error message along with the exit code
|
|
941
|
-
— that message is the only place the "delete it by hand" remedy appears — and
|
|
942
|
-
the banner's closing sentence changes to say the flag was passed. See
|
|
943
|
-
[docs/cli-reference.md](docs/cli-reference.md#--allow-unaddressed-deploy). The flag exists because the
|
|
944
|
-
orphaned-predecessor case can be temporarily unfixable (an ACM replacement
|
|
945
|
-
blocked on `DescribeCertificate.InUseBy` clears once the consumer finishes
|
|
946
|
-
updating). Prefer it over a shell `|| [ $? -eq 2 ]` wrapper, which would also
|
|
947
|
-
swallow the unrelated failures that exit `2` — macro expansion errors and
|
|
948
|
-
unsupported in-place updates.
|
|
949
|
-
|
|
950
|
-
## Local execution
|
|
951
|
-
|
|
952
|
-
The `cdkd local` family runs AWS workloads on the developer's machine
|
|
953
|
-
via Docker — Lambda functions, API Gateway routes, ECS tasks, and
|
|
954
|
-
long-running ECS services — without an AWS deploy. Modeled on `sam local *` but reuses cdkd's
|
|
955
|
-
synthesis / asset / construct-path plumbing — no `template.yaml` to
|
|
956
|
-
maintain, no `cdk synth | sam ...` round-trip.
|
|
957
|
-
|
|
958
|
-
| Subcommand | Emulates |
|
|
959
|
-
| --- | --- |
|
|
960
|
-
| `cdkd local invoke <target>` | One-shot Lambda invoke via the AWS Lambda Runtime Interface Emulator (RIE) |
|
|
961
|
-
| `cdkd local start-api` | Long-running HTTP server for REST v1 / HTTP API / Function URL routes |
|
|
962
|
-
| `cdkd local run-task <target>` | ECS RunTask — every container in a task definition started on a per-task docker network |
|
|
963
|
-
| `cdkd local start-service <target>` | Long-running ECS Service emulator — `DesiredCount` replicas with restart-on-exit (no local load balancer in v1) |
|
|
964
|
-
| `cdkd local invoke-agentcore <target>` | One-shot Bedrock AgentCore Runtime invoke (HTTP `/invocations` / MCP `/mcp` / A2A `/a2a` / AGUI / WebSocket `--ws`) |
|
|
965
|
-
| `cdkd local start-agentcore [target]` | Long-running serve of a Bedrock AgentCore Runtime against a warm container (all four protocols): HTTP / AGUI serve `POST /invocations` + `GET /ping` plus the `/ws` bridge (injects the session-id / Authorization a header-less browser client cannot set); MCP serves `/mcp`, A2A serves `/`. `--sigv4` / `--watch` supported |
|
|
966
|
-
| `cdkd local start-alb <targets...>` | Long-running local ALB front-door (HTTP + HTTPS listeners, path / host / header / weighted / redirect / fixed-response routing, authenticate-cognito / authenticate-oidc) for ECS / Lambda backing services |
|
|
967
|
-
| `cdkd local start-cloudfront [target]` | Long-running local CloudFront distribution — viewer-request -> S3 / Lambda Function URL origin -> viewer-response pipeline, CloudFront Functions run in-process (Function URL origins use Docker/RIE) |
|
|
968
|
-
|
|
969
|
-
The Docker-backed commands above require Docker. Pass `--from-state`
|
|
970
|
-
(cdkd-deployed) or `--from-cfn-stack` (cdk-deployed / CFn-managed) to
|
|
971
|
-
substitute deployed physical IDs into intrinsic-valued env vars /
|
|
972
|
-
secrets / image URIs; without either, intrinsic values are dropped with
|
|
973
|
-
a per-key warning (matches `sam local *`). The two flags are mutually
|
|
974
|
-
exclusive. `start-cloudfront` carries both `--from-state` and
|
|
975
|
-
`--from-cfn-stack` too (since cdk-local 0.128.0 / issue #766); a
|
|
976
|
-
CloudFront-Functions + S3-origin distribution still serves entirely
|
|
977
|
-
in-process (no Docker), while a Lambda Function URL origin runs via the
|
|
978
|
-
RIE container.
|
|
979
|
-
|
|
980
|
-
### `local invoke`
|
|
981
|
-
|
|
982
|
-
```bash
|
|
983
|
-
cdkd local invoke MyStack/Handler # one-shot invoke
|
|
984
|
-
cdkd local invoke MyStack/Handler --event events/get.json
|
|
985
|
-
cdkd local invoke MyStack/Handler --from-state # OR --from-cfn-stack
|
|
986
|
-
```
|
|
987
|
-
|
|
988
|
-
All AWS Lambda runtimes (Node.js / Python / Ruby / Java / .NET /
|
|
989
|
-
`provided.al2023`), ZIP and container Lambdas, same-stack Lambda Layers
|
|
990
|
-
bind-mounted at `/opt`.
|
|
991
|
-
|
|
992
|
-
### `local start-api`
|
|
993
|
-
|
|
994
|
-
```bash
|
|
995
|
-
cdkd local start-api # one HTTP server per discovered API
|
|
996
|
-
cdkd local start-api MyStack/MyHttpApi --watch # filter + hot reload
|
|
997
|
-
cdkd local start-api --from-state # OR --from-cfn-stack
|
|
998
|
-
|
|
999
|
-
# Typical shape — the bare `--from-cfn-stack` flag auto-resolves to the
|
|
1000
|
-
# routed stack's name (here `MyStack`). Pass an explicit value only when
|
|
1001
|
-
# the deployed CFn stack name differs from the CDK stack name.
|
|
1002
|
-
cdkd local start-api MyStack/MyHttpApi --from-cfn-stack
|
|
1003
|
-
```
|
|
1004
|
-
|
|
1005
|
-
REST v1 + HTTP API v2 + Function URL with all integration kinds
|
|
1006
|
-
(AWS_PROXY / MOCK / HTTP_PROXY / HTTP / AWS Lambda non-proxy via
|
|
1007
|
-
hand-rolled VTL), authorizers (Lambda / Cognito / HTTP v2 JWT /
|
|
1008
|
-
AWS_IAM SigV4 on REST v1 + Function URL), CORS, stage variables,
|
|
1009
|
-
`--watch` hot reload.
|
|
1010
|
-
|
|
1011
|
-
### `local run-task`
|
|
1012
|
-
|
|
1013
|
-
```bash
|
|
1014
|
-
cdkd local run-task MyStack/MyService/TaskDef
|
|
1015
|
-
cdkd local run-task MyTaskDef --from-state # OR --from-cfn-stack
|
|
1016
|
-
```
|
|
1017
|
-
|
|
1018
|
-
Every container in the task definition on a per-task docker network
|
|
1019
|
-
with the AWS-published ECS metadata sidecar.
|
|
1020
|
-
|
|
1021
|
-
### `local start-service`
|
|
1022
|
-
|
|
1023
|
-
```bash
|
|
1024
|
-
cdkd local start-service MyStack/Orders MyStack/Web # multiple services in one invocation
|
|
1025
|
-
cdkd local start-service MyStack/Orders --from-state # OR --from-cfn-stack
|
|
1026
|
-
cdkd local start-service MyStack/Web --watch # hot reload (sub-second on interpreted handlers)
|
|
1027
|
-
```
|
|
1028
|
-
|
|
1029
|
-
Long-running ECS Service emulator: `DesiredCount` replicas with
|
|
1030
|
-
restart-on-exit, cross-service Service Connect / Cloud Map DNS
|
|
1031
|
-
discovery (peer containers reach each other by `<discoveryName>.<namespace>`).
|
|
1032
|
-
No local load-balancer in v1. `--watch` re-synths on every CDK source edit
|
|
1033
|
-
and reloads one replica at a time — source-only edits on
|
|
1034
|
-
interpreted-language handlers (Node / Python / Ruby / shell) take a
|
|
1035
|
-
bind-mount fast path (`docker cp` + `docker restart`; no rebuild);
|
|
1036
|
-
Dockerfile / dependency manifest / compiled-language source edits fall
|
|
1037
|
-
through to a full rebuild + shadow boot + atomic swap.
|
|
1038
|
-
|
|
1039
|
-
### `local start-alb`
|
|
1040
|
-
|
|
1041
|
-
```bash
|
|
1042
|
-
cdkd local start-alb MyStack/MyAlb --lb-port 80=8080 # remap privileged listener port
|
|
1043
|
-
cdkd local start-alb MyStack/MyAlb --from-state # OR --from-cfn-stack
|
|
1044
|
-
cdkd local start-alb MyStack/MyAlb --watch # hot reload (sub-second on interpreted handlers)
|
|
1045
|
-
```
|
|
1046
|
-
|
|
1047
|
-
Long-running local ALB front-door: names an `AWS::ElasticLoadBalancingV2::LoadBalancer`,
|
|
1048
|
-
boots every ECS service behind its listeners, and stands up a local
|
|
1049
|
-
HTTP / HTTPS front-door on each listener port that round-robins across
|
|
1050
|
-
the running replicas and routes its listener rules across the backing
|
|
1051
|
-
services. Forward / redirect / fixed-response actions; ECS or Lambda
|
|
1052
|
-
targets; authenticate-cognito / authenticate-oidc via a local Bearer-JWT
|
|
1053
|
-
check. `--watch` reloads one backing-replica at a time across edits —
|
|
1054
|
-
interpreted-handler source edits go through the bind-mount fast path
|
|
1055
|
-
(no rebuild); Dockerfile / dependency / compiled-source edits fall
|
|
1056
|
-
through to a rebuild + atomic front-door pool swap.
|
|
1057
|
-
|
|
1058
|
-
### `local start-cloudfront`
|
|
1059
|
-
|
|
1060
|
-
```bash
|
|
1061
|
-
cdkd local start-cloudfront # interactive picker
|
|
1062
|
-
cdkd local start-cloudfront MyStack/MyDistribution # name the distribution
|
|
1063
|
-
cdkd local start-cloudfront MyStack/MyDistribution --watch # re-synth + swap on edit
|
|
1064
|
-
cdkd local start-cloudfront MyStack/MyDistribution --tls # real HTTPS termination
|
|
1065
|
-
```
|
|
1066
|
-
|
|
1067
|
-
Serves a CloudFront distribution's **viewer-request -> S3 origin ->
|
|
1068
|
-
viewer-response** pipeline locally so a routing-function change is
|
|
1069
|
-
verifiable in seconds instead of a deploy round-trip. The distribution's
|
|
1070
|
-
`AWS::CloudFront::Function`s (URL rewrites, trailing-slash normalization,
|
|
1071
|
-
SPA fallback, header tweaks) run in-process in a `node:vm` sandbox; the
|
|
1072
|
-
S3 origin content is the `BucketDeployment` source asset resolved out of
|
|
1073
|
-
the cloud assembly, served with `DefaultRootObject` and
|
|
1074
|
-
`CustomErrorResponses`. Path patterns route across the default + ordered
|
|
1075
|
-
cache behaviors. Pure-local: no Docker, no AWS call — `--watch` is just
|
|
1076
|
-
re-synth + an in-memory routing-model swap. S3 origins only (custom /
|
|
1077
|
-
Lambda@Edge origins are warn-and-skip); `--origin <id>=<dir>` points an
|
|
1078
|
-
origin at a local directory when `BucketDeployment` resolution can't.
|
|
150
|
+
Cold end-to-end wall clock including synth / plan, median of 7 runs, seconds, `us-east-1`.
|
|
1079
151
|
|
|
1080
|
-
|
|
1081
|
-
full reference — runtimes, target resolution, every flag, integration
|
|
1082
|
-
and authorizer detail, route precedence, container pool, networking,
|
|
1083
|
-
`--from-cfn-stack` semantics, v1 scope.
|
|
152
|
+
Full methodology, distribution analysis, per-run data, and the complete suite (SDK Provider path, Cloud Control fallback path, the 15x headline stack): **[cdkd.dev/benchmarks/](https://cdkd.dev/benchmarks/)**.
|
|
1084
153
|
|
|
1085
154
|
## License
|
|
1086
155
|
|