@go-to-k/cdkd 0.22.0 → 0.23.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -429,13 +429,10 @@ cdkd destroy --all --force
429
429
  cdkd force-unlock MyStack
430
430
 
431
431
  # Adopt already-deployed AWS resources into cdkd state.
432
- # Reads the CDK app to find logical IDs, types, and dependencies; uses the
433
- # `aws:cdk:path` tag (or explicit overrides) to find each resource in AWS.
434
- cdkd import MyStack --app "npx ts-node app.ts" --dry-run # preview
435
- cdkd import MyStack --app "npx ts-node app.ts" --yes # auto-import via tags
436
- cdkd import MyStack --resource MyBucket=my-bucket-name --yes # explicit override (repeatable)
437
- cdkd import MyStack --resource-mapping mapping.json --yes # CDK CLI mapping-file compat
438
- cdkd import MyStack --force # overwrite existing state
432
+ # See "Importing existing resources" below for the full guide (auto / selective /
433
+ # hybrid modes, --resource overrides, --resource-mapping CDK CLI compatibility).
434
+ cdkd import MyStack --dry-run
435
+ cdkd import MyStack --yes
439
436
 
440
437
  # Inspect state-bucket info on demand (bucket name, region, source, schema version, stack count).
441
438
  # Routine commands (deploy / destroy / etc.) no longer print the bucket banner by default —
@@ -543,6 +540,107 @@ Built on modern AWS tooling:
543
540
  - **Cloud Control API** - Fallback resource management for types without SDK Providers
544
541
  - **S3 Conditional Writes** - State locking via `If-None-Match`/`If-Match`
545
542
 
543
+ ## Importing existing resources
544
+
545
+ `cdkd import` adopts AWS resources that are already deployed (e.g. via
546
+ `cdk deploy`, manual creation, or another tool) into cdkd state, so the
547
+ next `cdkd deploy` updates them in-place instead of trying to CREATE
548
+ duplicates.
549
+
550
+ It reads the CDK app to find logical IDs, resource types, and
551
+ dependencies, then matches each logical ID to a real AWS resource in
552
+ one of three modes:
553
+
554
+ All examples below assume cdkd reads the CDK app command from `cdk.json`
555
+ (the typical case). Pass `--app "<command>"` only if you're running cdkd
556
+ outside the CDK project directory or want to override `cdk.json`.
557
+
558
+ ### Mode 1: auto (default — no flags)
559
+
560
+ ```bash
561
+ cdkd import MyStack
562
+ ```
563
+
564
+ Imports **every** resource in the synthesized template by tag. cdkd
565
+ looks up each resource using its `aws:cdk:path` tag (which CDK
566
+ automatically writes), so resources deployed by `cdk deploy` are found
567
+ without any manual work. Useful for **adopting a whole stack** that was
568
+ previously deployed by `cdk deploy`. This is cdkd's value-add over
569
+ `cdk import` — CDK CLI does not have a tag-based bulk-import mode.
570
+
571
+ ### Mode 2: selective (CDK CLI parity — when explicit overrides are given)
572
+
573
+ ```bash
574
+ # Import ONLY MyBucket; the other resources in the template are left alone.
575
+ cdkd import MyStack --resource MyBucket=my-bucket-name
576
+
577
+ # Several resources at once (--resource is repeatable).
578
+ cdkd import MyStack \
579
+ --resource MyBucket=my-bucket-name \
580
+ --resource MyFn=my-function-name
581
+
582
+ # CDK CLI compat: read overrides from a JSON file.
583
+ cdkd import MyStack --resource-mapping mapping.json
584
+ # mapping.json: { "MyBucket": "my-bucket-name", "MyFn": "my-function-name" }
585
+ ```
586
+
587
+ When at least one `--resource` flag (or a `--resource-mapping` file) is
588
+ supplied, **only the listed resources are imported**. Every other
589
+ resource in the template is reported as `out of scope` and left out of
590
+ state — the next `cdkd deploy` will treat them as new and CREATE them.
591
+ This matches the semantics of `cdk import --resource-mapping`. cdkd
592
+ validates that every override key is a real logical ID in the
593
+ template; a typo aborts the run rather than silently importing nothing.
594
+
595
+ Use selective mode when you want to **adopt a few specific resources**
596
+ out of a larger stack — for example, you have one S3 bucket that was
597
+ created manually that you want cdkd to manage, while the rest of the
598
+ stack will be deployed fresh.
599
+
600
+ ### Mode 3: hybrid (`--auto` with overrides)
601
+
602
+ ```bash
603
+ cdkd import MyStack \
604
+ --resource MyBucket=my-bucket-name \
605
+ --auto
606
+ ```
607
+
608
+ Listed resources use the explicit physical ID you supplied; **every
609
+ other resource still goes through tag-based auto-import**. Useful when
610
+ you have one resource whose tag-based lookup is unreliable (e.g. you
611
+ deleted and re-created it without the tag) but you want cdkd to find
612
+ the rest by tag automatically.
613
+
614
+ ### Common flags
615
+
616
+ | Flag | Purpose |
617
+ | ----------- | ----------------------------------------------------------------------------- |
618
+ | `--dry-run` | Preview what would be imported. State is NOT written. |
619
+ | `--yes` | Skip the confirmation prompt before writing state. |
620
+ | `--force` | Overwrite an existing state record. Without this, existing state aborts. |
621
+
622
+ ### After import
623
+
624
+ Run `cdkd diff` to see how the imported state lines up with the
625
+ template. If the resource's actual properties differ from the template,
626
+ the next `cdkd deploy` will UPDATE them to match. If you imported only
627
+ some resources (selective mode), the remaining template resources
628
+ appear as `to create` in the diff.
629
+
630
+ ### Provider support
631
+
632
+ Tag-based auto-lookup is implemented for the most-used resource types
633
+ (S3 Bucket, Lambda Function, IAM Role, SNS Topic, SQS Queue, DynamoDB
634
+ Table, Logs LogGroup, EventBridge EventBus, KMS Key/Alias, Secrets
635
+ Manager Secret, SSM Parameter, EC2 VPC/Subnet/SecurityGroup, RDS,
636
+ ECS Cluster/Service/TaskDefinition, CloudFront Distribution, Cognito
637
+ User Pool — the full list is in [CLAUDE.md](CLAUDE.md)). For resource
638
+ types without auto-lookup support (ApiGateway sub-resources, niche
639
+ services, anything in Cloud Control API), use the explicit
640
+ `--resource <id>=<physicalId>` override mode — selective mode handles
641
+ exactly this case. Resource types whose provider does not implement
642
+ import are reported as `unsupported` and skipped.
643
+
546
644
  ## State Management
547
645
 
548
646
  State is stored in S3. Keys are scoped by `(stackName, region)` so the same
package/dist/cli.js CHANGED
@@ -34058,15 +34058,38 @@ async function importCommand(stackArg, options) {
34058
34058
  if (overrides.size > 0) {
34059
34059
  logger.debug(`User-supplied physical IDs: ${[...overrides.keys()].join(", ")}`);
34060
34060
  }
34061
+ const selectiveMode = overrides.size > 0 && !options.auto;
34062
+ if (selectiveMode) {
34063
+ logger.info(
34064
+ `Selective mode: only importing the ${overrides.size} resource(s) you listed (${[...overrides.keys()].join(", ")}). Pass --auto to also tag-import the rest.`
34065
+ );
34066
+ }
34061
34067
  const template = stackInfo.template;
34062
34068
  const templateParser = new TemplateParser();
34063
34069
  const resources = collectImportableResources(template);
34064
34070
  logger.info(`Found ${resources.length} resource(s) in template`);
34071
+ const templateLogicalIds = new Set(resources.map((r) => r.logicalId));
34072
+ for (const overrideId of overrides.keys()) {
34073
+ if (!templateLogicalIds.has(overrideId)) {
34074
+ throw new Error(
34075
+ `--resource / --resource-mapping references logical ID '${overrideId}' which is not in the synthesized template for stack '${stackInfo.stackName}'. Available IDs: ${[...templateLogicalIds].join(", ")}`
34076
+ );
34077
+ }
34078
+ }
34065
34079
  const owner = `${process.env["USER"] || "unknown"}@${process.env["HOSTNAME"] || "host"}:${process.pid}`;
34066
34080
  await lockManager.acquireLock(stackInfo.stackName, targetRegion, owner, "import");
34067
34081
  try {
34068
34082
  const rows = [];
34069
34083
  for (const { logicalId, resource } of resources) {
34084
+ if (selectiveMode && !overrides.has(logicalId)) {
34085
+ rows.push({
34086
+ logicalId,
34087
+ resourceType: resource.Type,
34088
+ outcome: "skipped-out-of-scope",
34089
+ reason: "not in --resource / --resource-mapping (use --auto to include)"
34090
+ });
34091
+ continue;
34092
+ }
34070
34093
  const outcome = await importOne({
34071
34094
  logicalId,
34072
34095
  resource,
@@ -34256,6 +34279,7 @@ function printSummary(rows) {
34256
34279
  imported: 0,
34257
34280
  "skipped-no-impl": 0,
34258
34281
  "skipped-not-found": 0,
34282
+ "skipped-out-of-scope": 0,
34259
34283
  failed: 0
34260
34284
  };
34261
34285
  logger.info("");
@@ -34268,7 +34292,7 @@ function printSummary(rows) {
34268
34292
  }
34269
34293
  logger.info("");
34270
34294
  logger.info(
34271
- `Summary: ${counts.imported} imported, ${counts["skipped-not-found"]} not found, ${counts["skipped-no-impl"]} unsupported, ${counts.failed} failed`
34295
+ `Summary: ${counts.imported} imported, ${counts["skipped-not-found"]} not found, ${counts["skipped-no-impl"]} unsupported, ${counts["skipped-out-of-scope"]} out of scope, ${counts.failed} failed`
34272
34296
  );
34273
34297
  }
34274
34298
  function formatOutcome(outcome) {
@@ -34279,6 +34303,8 @@ function formatOutcome(outcome) {
34279
34303
  return "\xB7";
34280
34304
  case "skipped-no-impl":
34281
34305
  return "?";
34306
+ case "skipped-out-of-scope":
34307
+ return "-";
34282
34308
  case "failed":
34283
34309
  return "\u2717";
34284
34310
  }
@@ -34294,18 +34320,22 @@ async function confirmPrompt2(prompt) {
34294
34320
  }
34295
34321
  function createImportCommand() {
34296
34322
  const cmd = new Command12("import").description(
34297
- "Adopt already-deployed AWS resources into cdkd state. Reads the CDK app to find logical IDs, resource types, and dependencies; uses the aws:cdk:path tag (or explicit --resource overrides) to find each resource in AWS."
34323
+ "Adopt already-deployed AWS resources into cdkd state. Reads the CDK app to find logical IDs, resource types, and dependencies. With no flags, imports every resource via the aws:cdk:path tag. With --resource / --resource-mapping, only the listed resources are imported (CDK CLI parity); pass --auto to also tag-import the rest."
34298
34324
  ).argument(
34299
34325
  "[stack]",
34300
34326
  "Stack to import. Optional when the synthesized app contains exactly one stack."
34301
34327
  ).option(
34302
34328
  "--resource <id=physical>",
34303
- "Explicit physical-id override for one logical ID. Repeatable. Bypasses tag-based auto-lookup for that resource only.",
34329
+ "Explicit physical-id override for one logical ID. Repeatable. When at least one --resource is given, only listed resources are imported (CDK CLI parity). Pass --auto to also tag-import everything else.",
34304
34330
  collectMultiple,
34305
34331
  []
34306
34332
  ).option(
34307
34333
  "--resource-mapping <file>",
34308
- "Path to a JSON file of {logicalId: physicalId} overrides (CDK CLI `cdk import --resource-mapping` compatible)."
34334
+ "Path to a JSON file of {logicalId: physicalId} overrides (CDK CLI `cdk import --resource-mapping` compatible). Implies selective mode unless --auto is set."
34335
+ ).option(
34336
+ "--auto",
34337
+ "Hybrid mode: when explicit overrides are supplied, ALSO tag-import every other resource in the template. Without this flag, --resource / --resource-mapping behave as a whitelist (CDK CLI parity).",
34338
+ false
34309
34339
  ).option("--dry-run", "Show planned imports without writing state", false).option(
34310
34340
  "--force",
34311
34341
  "Overwrite an existing state record. Without this, an existing state file aborts the import.",
@@ -34347,7 +34377,7 @@ function reorderArgs(argv) {
34347
34377
  }
34348
34378
  async function main() {
34349
34379
  const program = new Command13();
34350
- program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.22.0");
34380
+ program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.23.0");
34351
34381
  program.addCommand(createBootstrapCommand());
34352
34382
  program.addCommand(createSynthCommand());
34353
34383
  program.addCommand(createListCommand());