@go-to-k/cdkd 0.259.0 → 0.260.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
@@ -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.0";
1904
+ return "0.260.0";
1905
1905
  }
1906
1906
  /**
1907
1907
  * Generate a time-sortable unique run id, e.g.
@@ -8516,13 +8516,13 @@ var LambdaFunctionProvider = class {
8516
8516
  Role: properties["Role"],
8517
8517
  Handler: properties["Handler"],
8518
8518
  Runtime: properties["Runtime"],
8519
- Timeout: properties["Timeout"],
8520
- MemorySize: properties["MemorySize"],
8521
- Description: properties["Description"],
8522
- Environment: properties["Environment"],
8523
- Layers: properties["Layers"],
8524
- TracingConfig: properties["TracingConfig"],
8525
- EphemeralStorage: properties["EphemeralStorage"],
8519
+ Timeout: this.clearOnUpdateRemoval(properties["Timeout"], previousProperties["Timeout"], 3),
8520
+ MemorySize: this.clearOnUpdateRemoval(properties["MemorySize"], previousProperties["MemorySize"], 128),
8521
+ Description: this.clearOnUpdateRemoval(properties["Description"], previousProperties["Description"], ""),
8522
+ Environment: this.clearOnUpdateRemoval(properties["Environment"], previousProperties["Environment"], { Variables: {} }),
8523
+ Layers: this.clearOnUpdateRemoval(properties["Layers"], previousProperties["Layers"], []),
8524
+ TracingConfig: this.clearOnUpdateRemoval(properties["TracingConfig"], previousProperties["TracingConfig"], { Mode: "PassThrough" }),
8525
+ EphemeralStorage: this.clearOnUpdateRemoval(properties["EphemeralStorage"], previousProperties["EphemeralStorage"], { Size: 512 }),
8526
8526
  VpcConfig: this.buildVpcConfigForUpdate(properties["VpcConfig"], previousProperties["VpcConfig"]),
8527
8527
  DeadLetterConfig: this.clearOnUpdateRemoval(properties["DeadLetterConfig"], previousProperties["DeadLetterConfig"], { TargetArn: "" }),
8528
8528
  KMSKeyArn: this.clearOnUpdateRemoval(properties["KmsKeyArn"], previousProperties["KmsKeyArn"], ""),
@@ -8677,9 +8677,12 @@ var LambdaFunctionProvider = class {
8677
8677
  * `UpdateFunctionConfiguration` treats an absent field as "no change", so
8678
8678
  * passing `undefined` for a field the user just dropped from the template
8679
8679
  * leaves the old value live on AWS — the update reports success while the
8680
- * field silently persists. For fields that support an explicit reset value
8681
- * (DeadLetterConfig `{TargetArn:''}`, KMSKeyArn `''`, FileSystemConfigs `[]`,
8682
- * ImageConfig `{}`, SnapStart `{ApplyOn:'None'}`) we send that reset when the
8680
+ * field silently persists. For every optional config field we send its
8681
+ * CFn-default / explicit reset value (e.g. Timeout `3`, MemorySize `128`,
8682
+ * Environment `{Variables:{}}`, Layers `[]`, TracingConfig
8683
+ * `{Mode:'PassThrough'}`, EphemeralStorage `{Size:512}`, DeadLetterConfig
8684
+ * `{TargetArn:''}`, KMSKeyArn `''`, FileSystemConfigs `[]`, ImageConfig `{}`,
8685
+ * SnapStart `{ApplyOn:'None'}`, LoggingConfig `{LogFormat:'Text'}`) when the
8683
8686
  * field was present before and is now absent. Mirrors `buildVpcConfigForUpdate`.
8684
8687
  */
8685
8688
  clearOnUpdateRemoval(newValue, previousValue, clearValue) {
@@ -10443,8 +10446,8 @@ var LambdaEventInvokeConfigProvider = class {
10443
10446
  var LambdaMicrovmImageProvider = class {
10444
10447
  client;
10445
10448
  logger = getLogger().child("LambdaMicrovmImageProvider");
10446
- maxPollAttempts = Number(process.env["CDKD_MICROVM_IMAGE_POLL_ATTEMPTS"] ?? 180);
10447
- pollIntervalMs = Number(process.env["CDKD_MICROVM_IMAGE_POLL_INTERVAL_MS"] ?? 1e4);
10449
+ maxPollAttempts = positiveIntFromEnv(process.env["CDKD_MICROVM_IMAGE_POLL_ATTEMPTS"], 180);
10450
+ pollIntervalMs = positiveIntFromEnv(process.env["CDKD_MICROVM_IMAGE_POLL_INTERVAL_MS"], 1e4);
10448
10451
  constructor() {
10449
10452
  this.client = getAwsClients().lambdaMicrovms;
10450
10453
  }
@@ -10625,6 +10628,47 @@ var LambdaMicrovmImageProvider = class {
10625
10628
  throw error;
10626
10629
  }
10627
10630
  }
10631
+ /**
10632
+ * Read the AWS-current MicroVM image state for `cdkd drift`.
10633
+ *
10634
+ * Only `Name` and `Tags` are readable back: `GetMicrovmImage` returns just
10635
+ * `imageArn` / `name` / `state` / versions / timestamps / `tags`, so the
10636
+ * build configuration (`BaseImageArn` / `BuildRoleArn` / `CodeArtifact` /
10637
+ * `Logging` / `Hooks` / ...) never comes back. Those paths are excluded from
10638
+ * the drift comparison via {@link getDriftUnknownPaths}; drift is therefore
10639
+ * scoped to the mutable, readable surface (Tags — updated in place via
10640
+ * TagResource/UntagResource).
10641
+ *
10642
+ * Tags are read via the dedicated `ListTags` (the authoritative tag source),
10643
+ * not the `GetMicrovmImage` response's `tags` field, whose population is not
10644
+ * guaranteed (the "type != populated" trap).
10645
+ *
10646
+ * Returns `undefined` when the image is gone.
10647
+ */
10648
+ async readCurrentState(physicalId, _logicalId, _resourceType) {
10649
+ let name;
10650
+ try {
10651
+ name = (await this.client.send(new GetMicrovmImageCommand({ imageIdentifier: physicalId }))).name;
10652
+ } catch (error) {
10653
+ if (error instanceof ResourceNotFoundException$7) return void 0;
10654
+ throw error;
10655
+ }
10656
+ const result = {};
10657
+ if (name !== void 0) result["Name"] = name;
10658
+ result["Tags"] = normalizeAwsTagsToCfn((await this.client.send(new ListTagsCommand$1({ Resource: physicalId }))).Tags);
10659
+ return result;
10660
+ }
10661
+ /**
10662
+ * Drift comparison paths this provider cannot read back from AWS: the build
10663
+ * configuration `GetMicrovmImage` never returns (its response carries only
10664
+ * `imageArn` / `name` / `state` / versions / timestamps / `tags`). Only
10665
+ * `Name` + `Tags` are read back (see {@link readCurrentState}), so every
10666
+ * other managed property is declared unknown to avoid guaranteed
10667
+ * false-positive drift on every run.
10668
+ */
10669
+ getDriftUnknownPaths(_resourceType) {
10670
+ return [...MICROVM_UNREADABLE_CFN_KEYS];
10671
+ }
10628
10672
  buildAttributes(imageArn, state, extra) {
10629
10673
  const attributes = { ImageArn: imageArn };
10630
10674
  if (state !== void 0) attributes["State"] = state;
@@ -10721,6 +10765,27 @@ const BUILD_AFFECTING_CFN_KEYS = [
10721
10765
  "Hooks",
10722
10766
  "EnvironmentVariables"
10723
10767
  ];
10768
+ /**
10769
+ * CFn property names `GetMicrovmImage` does NOT return (its response carries
10770
+ * only `imageArn` / `name` / `state` / versions / timestamps / `tags`), so
10771
+ * `cdkd drift` cannot read the build configuration back from AWS.
10772
+ * `getDriftUnknownPaths` declares them so they don't fire guaranteed
10773
+ * false-positive drift. Currently identical to {@link BUILD_AFFECTING_CFN_KEYS}
10774
+ * (the build config is exactly the set that is both rebuild-triggering and
10775
+ * unreadable) but kept separate as the two model different concerns
10776
+ * (drift-readability vs rebuild-triggering).
10777
+ */
10778
+ const MICROVM_UNREADABLE_CFN_KEYS = BUILD_AFFECTING_CFN_KEYS;
10779
+ /**
10780
+ * Parse a positive-integer poll-config env var, falling back to `dflt` for an
10781
+ * unset / non-numeric / non-positive value (so a garbage override cannot yield
10782
+ * `NaN`, which would make the poll loop exit immediately with a spurious
10783
+ * timeout).
10784
+ */
10785
+ function positiveIntFromEnv(value, dflt) {
10786
+ const n = Number(value);
10787
+ return Number.isFinite(n) && n > 0 ? n : dflt;
10788
+ }
10724
10789
  function sleep$2(ms) {
10725
10790
  return new Promise((resolve) => setTimeout(resolve, ms));
10726
10791
  }
@@ -37990,7 +38055,7 @@ var CloudTrailProvider = class {
37990
38055
  result["InsightSelectors"] = insightSelectors;
37991
38056
  let tags = [];
37992
38057
  if (trail.TrailARN) try {
37993
- tags = normalizeAwsTagsToCfn((await this.getClient().send(new ListTagsCommand$1({ ResourceIdList: [trail.TrailARN] }))).ResourceTagList?.[0]?.TagsList);
38058
+ tags = normalizeAwsTagsToCfn((await this.getClient().send(new ListTagsCommand$2({ ResourceIdList: [trail.TrailARN] }))).ResourceTagList?.[0]?.TagsList);
37994
38059
  } catch (err) {
37995
38060
  this.logger.debug(`CloudTrail ListTags(${trail.TrailARN}) failed: ${err instanceof Error ? err.message : String(err)}`);
37996
38061
  }
@@ -61284,7 +61349,7 @@ function createMigrateCommand() {
61284
61349
  */
61285
61350
  function buildProgram() {
61286
61351
  const program = new Command();
61287
- program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.259.0");
61352
+ program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.260.0");
61288
61353
  program.addCommand(createBootstrapCommand());
61289
61354
  program.addCommand(createSynthCommand());
61290
61355
  program.addCommand(createListCommand());