@go-to-k/cdkd 0.259.1 → 0.260.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -83,7 +83,7 @@ Reproduce the first two with `./tests/benchmark/run-benchmark.sh all`. See [test
83
83
  - **S3-based state management**: No DynamoDB required, uses S3 conditional writes for locking
84
84
  - **DAG-based parallelization**: Analyze `Ref`/`Fn::GetAtt` dependencies and execute in parallel
85
85
  - **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).
86
- - **`--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)
86
+ - **`--no-wait` for async resources**: Skip the multi-minute wait on CloudFront / RDS / ElastiCache / NAT Gateway / Lambda MicroVM Image and return as soon as the create call returns (CloudFormation always blocks)
87
87
  - **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.
88
88
  - **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).
89
89
  - **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).
package/dist/cli.js CHANGED
@@ -22,7 +22,7 @@ import { CloudWatchClient, DeleteAlarmsCommand, DescribeAlarmsCommand, ListTagsF
22
22
  import { AssociateKmsKeyCommand, CloudWatchLogsClient, CreateLogGroupCommand, DeleteDataProtectionPolicyCommand, DeleteIndexPolicyCommand, DeleteLogGroupCommand, DeleteRetentionPolicyCommand, DescribeIndexPoliciesCommand, DescribeLogGroupsCommand, DisassociateKmsKeyCommand, GetDataProtectionPolicyCommand, ListTagsForResourceCommand as ListTagsForResourceCommand$5, PutBearerTokenAuthenticationCommand, PutDataProtectionPolicyCommand, PutIndexPolicyCommand, PutLogGroupDeletionProtectionCommand, PutRetentionPolicyCommand, ResourceAlreadyExistsException, ResourceNotFoundException as ResourceNotFoundException$4, TagResourceCommand as TagResourceCommand$8, UntagResourceCommand as UntagResourceCommand$8 } from "@aws-sdk/client-cloudwatch-logs";
23
23
  import { BedrockAgentCoreControlClient, CreateAgentRuntimeCommand, CreateEvaluatorCommand, DeleteAgentRuntimeCommand, DeleteEvaluatorCommand, GetAgentRuntimeCommand, GetBrowserCommand, GetCodeInterpreterCommand, GetEvaluatorCommand, ListTagsForResourceCommand as ListTagsForResourceCommand$6, ResourceNotFoundException as ResourceNotFoundException$5, TagResourceCommand as TagResourceCommand$9, UntagResourceCommand as UntagResourceCommand$9, UpdateAgentRuntimeCommand, UpdateEvaluatorCommand } from "@aws-sdk/client-bedrock-agentcore-control";
24
24
  import { ACMClient, AddTagsToCertificateCommand, DeleteCertificateCommand, DescribeCertificateCommand, ListTagsForCertificateCommand, RemoveTagsFromCertificateCommand, RequestCertificateCommand, ResourceNotFoundException as ResourceNotFoundException$6, UpdateCertificateOptionsCommand } from "@aws-sdk/client-acm";
25
- import { CreateMicrovmImageCommand, DeleteMicrovmImageCommand, GetMicrovmImageCommand, LambdaMicrovmsClient, ResourceNotFoundException as ResourceNotFoundException$7, TagResourceCommand as TagResourceCommand$10, UntagResourceCommand as UntagResourceCommand$10, UpdateMicrovmImageCommand } from "@aws-sdk/client-lambda-microvms";
25
+ import { CreateMicrovmImageCommand, DeleteMicrovmImageCommand, GetMicrovmImageCommand, LambdaMicrovmsClient, ListTagsCommand as ListTagsCommand$1, ResourceNotFoundException as ResourceNotFoundException$7, TagResourceCommand as TagResourceCommand$10, UntagResourceCommand as UntagResourceCommand$10, UpdateMicrovmImageCommand } from "@aws-sdk/client-lambda-microvms";
26
26
  import * as fs from "node:fs";
27
27
  import { cpSync, existsSync, mkdirSync, mkdtempSync, readFileSync, readdirSync, rmSync, statSync, writeFileSync } from "node:fs";
28
28
  import * as path from "node:path";
@@ -60,7 +60,7 @@ import { AccessPointNotFound, CreateAccessPointCommand, CreateFileSystemCommand,
60
60
  import { CreateFileSystemCommand as CreateFileSystemCommand$1, CreateFileSystemFromBackupCommand, DeleteFileSystemCommand as DeleteFileSystemCommand$1, DescribeFileSystemsCommand as DescribeFileSystemsCommand$1, FSxClient, FileSystemNotFound as FileSystemNotFound$1, TagResourceCommand as TagResourceCommand$19, UntagResourceCommand as UntagResourceCommand$19, UpdateFileSystemCommand as UpdateFileSystemCommand$1 } from "@aws-sdk/client-fsx";
61
61
  import { AddInstanceFleetCommand, AddInstanceGroupsCommand, AddTagsCommand as AddTagsCommand$1, DescribeClusterCommand, EMRClient, InvalidRequestException, ListInstanceFleetsCommand, ListInstanceGroupsCommand, ModifyClusterCommand, ModifyInstanceFleetCommand, ModifyInstanceGroupsCommand, PutAutoScalingPolicyCommand, PutAutoTerminationPolicyCommand, PutManagedScalingPolicyCommand, RemoveAutoScalingPolicyCommand, RemoveAutoTerminationPolicyCommand, RemoveManagedScalingPolicyCommand, RemoveTagsCommand as RemoveTagsCommand$1, RunJobFlowCommand, SetTerminationProtectionCommand, SetVisibleToAllUsersCommand, TerminateJobFlowsCommand } from "@aws-sdk/client-emr";
62
62
  import { CreateDeliveryStreamCommand, DeleteDeliveryStreamCommand, DescribeDeliveryStreamCommand, FirehoseClient, ListTagsForDeliveryStreamCommand, ResourceNotFoundException as ResourceNotFoundException$11, TagDeliveryStreamCommand, UntagDeliveryStreamCommand, UpdateDestinationCommand } from "@aws-sdk/client-firehose";
63
- import { AddTagsCommand as AddTagsCommand$2, CloudTrailClient, CreateTrailCommand, DeleteTrailCommand, GetEventSelectorsCommand, GetInsightSelectorsCommand, GetTrailCommand, GetTrailStatusCommand, ListTagsCommand as ListTagsCommand$1, PutEventSelectorsCommand, PutInsightSelectorsCommand, RemoveTagsCommand as RemoveTagsCommand$2, StartLoggingCommand, StopLoggingCommand, TrailNotFoundException, UpdateTrailCommand } from "@aws-sdk/client-cloudtrail";
63
+ import { AddTagsCommand as AddTagsCommand$2, CloudTrailClient, CreateTrailCommand, DeleteTrailCommand, GetEventSelectorsCommand, GetInsightSelectorsCommand, GetTrailCommand, GetTrailStatusCommand, ListTagsCommand as ListTagsCommand$2, PutEventSelectorsCommand, PutInsightSelectorsCommand, RemoveTagsCommand as RemoveTagsCommand$2, StartLoggingCommand, StopLoggingCommand, TrailNotFoundException, UpdateTrailCommand } from "@aws-sdk/client-cloudtrail";
64
64
  import { BatchGetProjectsCommand, CodeBuildClient, CreateProjectCommand, DeleteProjectCommand, ResourceNotFoundException as ResourceNotFoundException$12, UpdateProjectCommand } from "@aws-sdk/client-codebuild";
65
65
  import { CodeCommitClient, CreateCommitCommand, CreateRepositoryCommand as CreateRepositoryCommand$1, DeleteRepositoryCommand as DeleteRepositoryCommand$1, GetRepositoryCommand, ListTagsForResourceCommand as ListTagsForResourceCommand$16, PutRepositoryTriggersCommand, RepositoryDoesNotExistException, TagResourceCommand as TagResourceCommand$20, UntagResourceCommand as UntagResourceCommand$20, UpdateRepositoryDescriptionCommand, UpdateRepositoryEncryptionKeyCommand, UpdateRepositoryNameCommand } from "@aws-sdk/client-codecommit";
66
66
  import AdmZip from "adm-zip";
@@ -348,7 +348,7 @@ function ensureWarnAfter(opts) {
348
348
  }
349
349
  /**
350
350
  * Skip waiting for async-stabilization resources (CloudFront, RDS,
351
- * ElastiCache, NAT Gateway) on deploy. Setting the flag mutates
351
+ * ElastiCache, NAT Gateway, Lambda MicroVM Image) on deploy. Setting the flag mutates
352
352
  * `process.env.CDKD_NO_WAIT='true'`; provider code checks that env
353
353
  * var, not the parsed CLI option (this lets nested call paths — e.g.
354
354
  * asset publish, lifecycle hooks — see the same setting without
@@ -360,7 +360,7 @@ function ensureWarnAfter(opts) {
360
360
  * destroy paths don't wait to begin with — so `destroy --no-wait`
361
361
  * would be a no-op flag.
362
362
  */
363
- const noWaitOption = new Option("--no-wait", "Skip waiting for async resources to stabilize (CloudFront, RDS, ElastiCache, NAT Gateway)");
363
+ const noWaitOption = new Option("--no-wait", "Skip waiting for async resources to stabilize (CloudFront, RDS, ElastiCache, NAT Gateway, Lambda MicroVM Image)");
364
364
  /**
365
365
  * Drop the CDK-injected defensive `DependsOn` edges from VPC Lambdas (and
366
366
  * adjacent IAM Role / Policy / Lambda::Url / EventSourceMapping resources)
@@ -1901,7 +1901,7 @@ const FLUSH_INTERVAL_MS = 2e3;
1901
1901
  const FLUSH_EVENT_THRESHOLD = 50;
1902
1902
  /** Build-time cdkd version, with a dev fallback for non-built contexts. */
1903
1903
  function getCdkdVersion() {
1904
- return "0.259.1";
1904
+ return "0.260.1";
1905
1905
  }
1906
1906
  /**
1907
1907
  * Generate a time-sortable unique run id, e.g.
@@ -8519,7 +8519,7 @@ var LambdaFunctionProvider = class {
8519
8519
  Timeout: this.clearOnUpdateRemoval(properties["Timeout"], previousProperties["Timeout"], 3),
8520
8520
  MemorySize: this.clearOnUpdateRemoval(properties["MemorySize"], previousProperties["MemorySize"], 128),
8521
8521
  Description: this.clearOnUpdateRemoval(properties["Description"], previousProperties["Description"], ""),
8522
- Environment: this.clearOnUpdateRemoval(properties["Environment"], previousProperties["Environment"], { Variables: {} }),
8522
+ Environment: this.clearOnUpdateRemoval(this.normalizeEnvironmentForUpdate(properties["Environment"]), previousProperties["Environment"], { Variables: {} }),
8523
8523
  Layers: this.clearOnUpdateRemoval(properties["Layers"], previousProperties["Layers"], []),
8524
8524
  TracingConfig: this.clearOnUpdateRemoval(properties["TracingConfig"], previousProperties["TracingConfig"], { Mode: "PassThrough" }),
8525
8525
  EphemeralStorage: this.clearOnUpdateRemoval(properties["EphemeralStorage"], previousProperties["EphemeralStorage"], { Size: 512 }),
@@ -8690,6 +8690,25 @@ var LambdaFunctionProvider = class {
8690
8690
  if (previousValue !== void 0) return clearValue;
8691
8691
  }
8692
8692
  /**
8693
+ * Normalize a template `Environment` block for UpdateFunctionConfiguration.
8694
+ *
8695
+ * `Environment: {}` (present, but no `Variables` key — a hand-written L1 /
8696
+ * imported-template shape CDK never emits) passed through verbatim does NOT
8697
+ * clear the live env vars: the API keeps the old `Variables` when the input
8698
+ * `Environment` carries none (live-verified 2026-07-22, issue #1158). The
8699
+ * template's declarative meaning is "no env vars", so a Variables-less
8700
+ * block is rewritten to the explicit-clear `{Variables: {}}`. A present
8701
+ * `Variables` map (even empty) and an absent `Environment` pass through
8702
+ * unchanged — removal handling stays with `clearOnUpdateRemoval`. A `null`
8703
+ * block (hand-written JSON) is treated like absent rather than crashing on
8704
+ * the property read.
8705
+ */
8706
+ normalizeEnvironmentForUpdate(environment) {
8707
+ if (environment == null) return void 0;
8708
+ if (environment.Variables === void 0) return { Variables: {} };
8709
+ return environment;
8710
+ }
8711
+ /**
8693
8712
  * Determine whether the function actually attaches to a VPC, i.e. has at
8694
8713
  * least one Subnet ID. A bare VpcConfig with empty arrays does not create
8695
8714
  * any ENIs, so we skip the wait in that case.
@@ -10446,8 +10465,8 @@ var LambdaEventInvokeConfigProvider = class {
10446
10465
  var LambdaMicrovmImageProvider = class {
10447
10466
  client;
10448
10467
  logger = getLogger().child("LambdaMicrovmImageProvider");
10449
- maxPollAttempts = Number(process.env["CDKD_MICROVM_IMAGE_POLL_ATTEMPTS"] ?? 180);
10450
- pollIntervalMs = Number(process.env["CDKD_MICROVM_IMAGE_POLL_INTERVAL_MS"] ?? 1e4);
10468
+ maxPollAttempts = positiveIntFromEnv(process.env["CDKD_MICROVM_IMAGE_POLL_ATTEMPTS"], 180);
10469
+ pollIntervalMs = positiveIntFromEnv(process.env["CDKD_MICROVM_IMAGE_POLL_INTERVAL_MS"], 1e4);
10451
10470
  constructor() {
10452
10471
  this.client = getAwsClients().lambdaMicrovms;
10453
10472
  }
@@ -10628,6 +10647,47 @@ var LambdaMicrovmImageProvider = class {
10628
10647
  throw error;
10629
10648
  }
10630
10649
  }
10650
+ /**
10651
+ * Read the AWS-current MicroVM image state for `cdkd drift`.
10652
+ *
10653
+ * Only `Name` and `Tags` are readable back: `GetMicrovmImage` returns just
10654
+ * `imageArn` / `name` / `state` / versions / timestamps / `tags`, so the
10655
+ * build configuration (`BaseImageArn` / `BuildRoleArn` / `CodeArtifact` /
10656
+ * `Logging` / `Hooks` / ...) never comes back. Those paths are excluded from
10657
+ * the drift comparison via {@link getDriftUnknownPaths}; drift is therefore
10658
+ * scoped to the mutable, readable surface (Tags — updated in place via
10659
+ * TagResource/UntagResource).
10660
+ *
10661
+ * Tags are read via the dedicated `ListTags` (the authoritative tag source),
10662
+ * not the `GetMicrovmImage` response's `tags` field, whose population is not
10663
+ * guaranteed (the "type != populated" trap).
10664
+ *
10665
+ * Returns `undefined` when the image is gone.
10666
+ */
10667
+ async readCurrentState(physicalId, _logicalId, _resourceType) {
10668
+ let name;
10669
+ try {
10670
+ name = (await this.client.send(new GetMicrovmImageCommand({ imageIdentifier: physicalId }))).name;
10671
+ } catch (error) {
10672
+ if (error instanceof ResourceNotFoundException$7) return void 0;
10673
+ throw error;
10674
+ }
10675
+ const result = {};
10676
+ if (name !== void 0) result["Name"] = name;
10677
+ result["Tags"] = normalizeAwsTagsToCfn((await this.client.send(new ListTagsCommand$1({ Resource: physicalId }))).Tags);
10678
+ return result;
10679
+ }
10680
+ /**
10681
+ * Drift comparison paths this provider cannot read back from AWS: the build
10682
+ * configuration `GetMicrovmImage` never returns (its response carries only
10683
+ * `imageArn` / `name` / `state` / versions / timestamps / `tags`). Only
10684
+ * `Name` + `Tags` are read back (see {@link readCurrentState}), so every
10685
+ * other managed property is declared unknown to avoid guaranteed
10686
+ * false-positive drift on every run.
10687
+ */
10688
+ getDriftUnknownPaths(_resourceType) {
10689
+ return [...MICROVM_UNREADABLE_CFN_KEYS];
10690
+ }
10631
10691
  buildAttributes(imageArn, state, extra) {
10632
10692
  const attributes = { ImageArn: imageArn };
10633
10693
  if (state !== void 0) attributes["State"] = state;
@@ -10724,6 +10784,27 @@ const BUILD_AFFECTING_CFN_KEYS = [
10724
10784
  "Hooks",
10725
10785
  "EnvironmentVariables"
10726
10786
  ];
10787
+ /**
10788
+ * CFn property names `GetMicrovmImage` does NOT return (its response carries
10789
+ * only `imageArn` / `name` / `state` / versions / timestamps / `tags`), so
10790
+ * `cdkd drift` cannot read the build configuration back from AWS.
10791
+ * `getDriftUnknownPaths` declares them so they don't fire guaranteed
10792
+ * false-positive drift. Currently identical to {@link BUILD_AFFECTING_CFN_KEYS}
10793
+ * (the build config is exactly the set that is both rebuild-triggering and
10794
+ * unreadable) but kept separate as the two model different concerns
10795
+ * (drift-readability vs rebuild-triggering).
10796
+ */
10797
+ const MICROVM_UNREADABLE_CFN_KEYS = BUILD_AFFECTING_CFN_KEYS;
10798
+ /**
10799
+ * Parse a positive-integer poll-config env var, falling back to `dflt` for an
10800
+ * unset / non-numeric / non-positive value (so a garbage override cannot yield
10801
+ * `NaN`, which would make the poll loop exit immediately with a spurious
10802
+ * timeout).
10803
+ */
10804
+ function positiveIntFromEnv(value, dflt) {
10805
+ const n = Number(value);
10806
+ return Number.isFinite(n) && n > 0 ? n : dflt;
10807
+ }
10727
10808
  function sleep$2(ms) {
10728
10809
  return new Promise((resolve) => setTimeout(resolve, ms));
10729
10810
  }
@@ -37993,7 +38074,7 @@ var CloudTrailProvider = class {
37993
38074
  result["InsightSelectors"] = insightSelectors;
37994
38075
  let tags = [];
37995
38076
  if (trail.TrailARN) try {
37996
- tags = normalizeAwsTagsToCfn((await this.getClient().send(new ListTagsCommand$1({ ResourceIdList: [trail.TrailARN] }))).ResourceTagList?.[0]?.TagsList);
38077
+ tags = normalizeAwsTagsToCfn((await this.getClient().send(new ListTagsCommand$2({ ResourceIdList: [trail.TrailARN] }))).ResourceTagList?.[0]?.TagsList);
37997
38078
  } catch (err) {
37998
38079
  this.logger.debug(`CloudTrail ListTags(${trail.TrailARN}) failed: ${err instanceof Error ? err.message : String(err)}`);
37999
38080
  }
@@ -61287,7 +61368,7 @@ function createMigrateCommand() {
61287
61368
  */
61288
61369
  function buildProgram() {
61289
61370
  const program = new Command();
61290
- program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.259.1");
61371
+ program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.260.1");
61291
61372
  program.addCommand(createBootstrapCommand());
61292
61373
  program.addCommand(createSynthCommand());
61293
61374
  program.addCommand(createListCommand());