@go-to-k/cdkd 0.75.1 → 0.75.2
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 +39 -58
- package/dist/cli.js +22 -5
- package/dist/cli.js.map +2 -2
- package/dist/go-to-k-cdkd-0.75.2.tgz +0 -0
- package/package.json +1 -1
- package/dist/go-to-k-cdkd-0.75.1.tgz +0 -0
package/README.md
CHANGED
|
@@ -24,6 +24,7 @@
|
|
|
24
24
|
- **Diff calculation**: Self-implemented resource/property-level diff between desired template and current state
|
|
25
25
|
- **S3-based state management**: No DynamoDB required, uses S3 conditional writes for locking
|
|
26
26
|
- **DAG-based parallelization**: Analyze `Ref`/`Fn::GetAtt` dependencies and execute in parallel
|
|
27
|
+
- **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).
|
|
27
28
|
- **`--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)
|
|
28
29
|
- **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.
|
|
29
30
|
|
|
@@ -161,7 +162,7 @@ the full per-type table.
|
|
|
161
162
|
| Asset publishing (ECR) | ✅ | Self-implemented Docker image publishing |
|
|
162
163
|
| Custom Resources (SNS-backed) | ✅ | SNS Topic ServiceToken + S3 response |
|
|
163
164
|
| Custom Resources (CDK Provider) | ✅ | isCompleteHandler/onEventHandler async pattern detection |
|
|
164
|
-
| Rollback | ✅ |
|
|
165
|
+
| Rollback | ✅ | Auto-rollback on mid-deploy failure (deletes already-completed resources to keep state consistent); `--no-rollback` skips for Terraform-style failed-state inspection. See [Rollback behavior](#rollback-behavior) below. |
|
|
165
166
|
| DeletionPolicy: Retain | ✅ | Skip deletion for retained resources |
|
|
166
167
|
| UpdateReplacePolicy: Retain | ✅ | Keep old resource on replacement |
|
|
167
168
|
| Implicit delete dependencies | ✅ | VPC/IGW/EventBus/Subnet/RouteTable ordering |
|
|
@@ -180,33 +181,15 @@ the full per-type table.
|
|
|
180
181
|
|
|
181
182
|
## Installation
|
|
182
183
|
|
|
183
|
-
### From npm
|
|
184
|
-
|
|
185
184
|
```bash
|
|
186
185
|
npm i -g @go-to-k/cdkd # latest release
|
|
187
186
|
npm i -g @go-to-k/cdkd@0.0.2 # pin to a specific version
|
|
188
187
|
```
|
|
189
188
|
|
|
190
|
-
The installed binary is `cdkd
|
|
189
|
+
The installed binary is `cdkd`.
|
|
191
190
|
|
|
192
191
|
> cdkd is an experimental / educational project and is not intended for production use — see the warning at the top of this README. Pin to a specific version if you need reproducible installs.
|
|
193
192
|
|
|
194
|
-
### From source
|
|
195
|
-
|
|
196
|
-
```bash
|
|
197
|
-
git clone https://github.com/go-to-k/cdkd.git
|
|
198
|
-
cd cdkd
|
|
199
|
-
pnpm install
|
|
200
|
-
pnpm run build
|
|
201
|
-
npm link
|
|
202
|
-
```
|
|
203
|
-
|
|
204
|
-
If `cdkd` is not found after `npm link`, set an alias in the current shell:
|
|
205
|
-
|
|
206
|
-
```bash
|
|
207
|
-
alias cdkd="node $(pwd)/dist/cli.js"
|
|
208
|
-
```
|
|
209
|
-
|
|
210
193
|
## Quick Start
|
|
211
194
|
|
|
212
195
|
> **First-time setup**: cdkd requires a one-time `cdkd bootstrap` per AWS
|
|
@@ -405,6 +388,27 @@ cdkd state destroy --all -y # every stack in the bucket
|
|
|
405
388
|
cdkd state destroy MyStack --region us-east-1
|
|
406
389
|
```
|
|
407
390
|
|
|
391
|
+
## Rollback behavior
|
|
392
|
+
|
|
393
|
+
When a deploy fails mid-stack (e.g. a resource hits a validation error
|
|
394
|
+
or AWS rejects the request), cdkd by default **rolls back the
|
|
395
|
+
already-completed resources in the same deploy** so the stack state
|
|
396
|
+
stays consistent — every resource cdkd just created in this run is
|
|
397
|
+
deleted in reverse dependency order, the state record is updated to
|
|
398
|
+
match, and the CLI exits non-zero. Resources that existed before this
|
|
399
|
+
deploy are NOT touched.
|
|
400
|
+
|
|
401
|
+
Pass `cdkd deploy --no-rollback` to skip the rollback (Terraform-style:
|
|
402
|
+
the partial state is preserved so you can `cdkd state show <stack>`,
|
|
403
|
+
inspect what landed, fix the underlying issue, and re-run `cdkd deploy`
|
|
404
|
+
to continue from the half-deployed state). Recommended only when you
|
|
405
|
+
plan to manually inspect / repair; the default is safer for CI.
|
|
406
|
+
|
|
407
|
+
Mid-deploy state is also saved per-resource as work completes, so even
|
|
408
|
+
if cdkd itself crashes between the failure and the rollback, the state
|
|
409
|
+
file accurately reflects what's on AWS and a follow-up `cdkd destroy`
|
|
410
|
+
won't orphan anything.
|
|
411
|
+
|
|
408
412
|
## `--no-wait`: skip async-resource waits
|
|
409
413
|
|
|
410
414
|
CloudFront / RDS / ElastiCache / NAT Gateway typically take 1–15
|
|
@@ -493,28 +497,16 @@ Two `orphan` variants at different granularities:
|
|
|
493
497
|
Both `cdkd destroy` (synth-driven) and `cdkd state destroy`
|
|
494
498
|
(state-driven, no synth) delete AWS resources + state.
|
|
495
499
|
|
|
496
|
-
##
|
|
500
|
+
## `--remove-protection`: one-shot bypass for protected resources
|
|
497
501
|
|
|
498
|
-
CDK's `new Stack(app, 'X', { terminationProtection: true })` is
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
per-resource delete runs; in `--all` runs sibling unprotected
|
|
502
|
-
stacks still destroy and the protected ones contribute to the
|
|
503
|
-
partial-failure exit code 2.
|
|
504
|
-
|
|
505
|
-
Bypass workflow:
|
|
506
|
-
|
|
507
|
-
1. Edit the CDK code to set `terminationProtection: false`.
|
|
508
|
-
2. Redeploy: `cdkd deploy MyStack`.
|
|
509
|
-
3. Retry: `cdkd destroy MyStack`.
|
|
510
|
-
|
|
511
|
-
`cdkd state destroy` (state-only, no synth) does **not** honor
|
|
512
|
-
`terminationProtection` — the flag is a CDK property surfaced via
|
|
513
|
-
synth and is not stored in cdkd's state.json. Use `cdkd destroy`
|
|
514
|
-
when synth is available, or accept that `state destroy` is the
|
|
502
|
+
CDK's `new Stack(app, 'X', { terminationProtection: true })` is honored
|
|
503
|
+
by `cdkd destroy` (refused before any per-resource delete). The
|
|
504
|
+
state-only path `cdkd state destroy` does NOT honor it — that's the
|
|
515
505
|
explicit "I know what I'm doing, ignore CDK guards" escape hatch.
|
|
516
506
|
|
|
517
|
-
|
|
507
|
+
For resource-level protection (`DeletionProtection` etc.), the standard
|
|
508
|
+
workflow is edit CDK → redeploy → destroy. `--remove-protection` is the
|
|
509
|
+
one-shot bypass:
|
|
518
510
|
|
|
519
511
|
`cdkd destroy --remove-protection` and `cdkd state destroy
|
|
520
512
|
--remove-protection` flip every protection flag off in-place
|
|
@@ -538,25 +530,14 @@ types:
|
|
|
538
530
|
| `AWS::Cognito::UserPool` | `DeletionProtection` (`ACTIVE` / `INACTIVE`) |
|
|
539
531
|
| `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 |
|
|
540
532
|
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
DELETION PROTECTION on K of them. Continue? (y/N)`. The default
|
|
550
|
-
flips from `Y/n` to `y/N` so the destructive bypass requires an
|
|
551
|
-
explicit `y` / `yes`. `--yes` / `-y` / `-f` skips the prompt.
|
|
552
|
-
|
|
553
|
-
Other protected resource types (CloudFront Distributions, Lambda
|
|
554
|
-
function reserved concurrency, S3 bucket retention, etc.) are
|
|
555
|
-
out of scope — the flag list is curated to the cases where AWS
|
|
556
|
-
exposes a synchronous "flip protection off" API call.
|
|
557
|
-
|
|
558
|
-
`cdkd diff` (read-only) and `cdkd deploy` (forward-only) are
|
|
559
|
-
unaffected — only destroy is gated.
|
|
533
|
+
A single `--remove-protection` covers every type listed above (no
|
|
534
|
+
per-type variant). The interactive confirm prompt switches to
|
|
535
|
+
`y/N` (requiring an explicit `y` for the destructive bypass);
|
|
536
|
+
`--yes` / `-y` / `-f` skips it.
|
|
537
|
+
|
|
538
|
+
Out of scope: types where AWS doesn't expose a synchronous "flip
|
|
539
|
+
protection off" API call (CloudFront Distributions, Lambda function
|
|
540
|
+
reserved concurrency, S3 bucket retention, etc.).
|
|
560
541
|
|
|
561
542
|
## `publish-assets`: synth + build + publish, no deploy
|
|
562
543
|
|
package/dist/cli.js
CHANGED
|
@@ -73023,8 +73023,25 @@ function resourceMatches(pattern, methodArn) {
|
|
|
73023
73023
|
return true;
|
|
73024
73024
|
if (!pattern.includes("*") && !pattern.includes("?"))
|
|
73025
73025
|
return false;
|
|
73026
|
-
|
|
73027
|
-
|
|
73026
|
+
let regex = "";
|
|
73027
|
+
for (let i = 0; i < pattern.length; i++) {
|
|
73028
|
+
const ch = pattern[i];
|
|
73029
|
+
if (ch === "*") {
|
|
73030
|
+
if (pattern[i + 1] === "*") {
|
|
73031
|
+
regex += ".*";
|
|
73032
|
+
i++;
|
|
73033
|
+
} else {
|
|
73034
|
+
regex += "[^:/]*";
|
|
73035
|
+
}
|
|
73036
|
+
} else if (ch === "?") {
|
|
73037
|
+
regex += "[^:/]";
|
|
73038
|
+
} else if (".+^${}()|[]\\".includes(ch)) {
|
|
73039
|
+
regex += "\\" + ch;
|
|
73040
|
+
} else {
|
|
73041
|
+
regex += ch;
|
|
73042
|
+
}
|
|
73043
|
+
}
|
|
73044
|
+
const re = new RegExp(`^${regex}$`);
|
|
73028
73045
|
return re.test(methodArn);
|
|
73029
73046
|
}
|
|
73030
73047
|
function evaluateCachedLambdaPolicy(cached, methodArn) {
|
|
@@ -73226,10 +73243,10 @@ function pickStringClaim(claims, key) {
|
|
|
73226
73243
|
function extractBearer(header) {
|
|
73227
73244
|
if (!header)
|
|
73228
73245
|
return void 0;
|
|
73229
|
-
const m = /^\s*Bearer\s+(
|
|
73246
|
+
const m = /^\s*Bearer\s+([A-Za-z0-9._-]+)\s*$/i.exec(header);
|
|
73230
73247
|
if (!m)
|
|
73231
73248
|
return void 0;
|
|
73232
|
-
return m[1]
|
|
73249
|
+
return m[1];
|
|
73233
73250
|
}
|
|
73234
73251
|
function parseJwt(token) {
|
|
73235
73252
|
const parts = token.split(".");
|
|
@@ -77011,7 +77028,7 @@ function reorderArgs(argv) {
|
|
|
77011
77028
|
}
|
|
77012
77029
|
async function main() {
|
|
77013
77030
|
const program = new Command16();
|
|
77014
|
-
program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.75.
|
|
77031
|
+
program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.75.2");
|
|
77015
77032
|
program.addCommand(createBootstrapCommand());
|
|
77016
77033
|
program.addCommand(createSynthCommand());
|
|
77017
77034
|
program.addCommand(createListCommand());
|