@go-to-k/cdkd 0.280.19 → 0.280.21

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/dist/cli.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
- import { $ as requireConfigString, $t as processStackMessages, A as red, At as runDockerStreaming, B as isTerminationProtectionPropagationError, Bt as resolveSkipPrefix, C as isStatefulRecreateTargetSync, Ct as parseBootstrapMarker, D as cyan, Dn as normalizeAwsError, Dt as formatDockerLoginError, E as bold, Et as buildDockerImage, F as ProviderRegistry, Ft as getDefaultStateBucketName, G as normalizeAwsTagsToCfn, Gt as warnDeprecatedNoPrefixCliFlag, H as cfnRefValueFromPhysicalId, Ht as resolveStateBucketWithDefaultAndSource, I as findActionableSilentDrops, It as getLegacyStateBucketName, J as configStringRefusal, Jt as MIGRATE_TMP_PREFIX, K as resolveExplicitPhysicalId, Kt as CFN_TEMPLATE_BODY_LIMIT, L as CloudControlProvider, Lt as resolveApp, M as IAMRoleProvider, Mt as getDockerImageBySourceHash, N as collectInlinePolicyNamesManagedBySiblings, Nt as Synthesizer, O as gray, On as withErrorHandling, Ot as getDockerCmd, P as clearOnUpdateRemoval, Pt as synthesisStatusMessage, Q as requireConfigObject, Qt as AssemblyReader, R as slowCcOperationTimeoutMs, Rt as resolveAutoAssetStorage, S as MULTI_REGION_RECREATE_BLOCKED_TYPES, Sn as StackTerminationProtectionError, St as getBootstrapMarkerKey, T as formatResourceLine, Tt as validateContainerRepoName, U as refStateLookupFromResource, Ut as resolveUseCdkBootstrapAssets, V as IntrinsicFunctionResolver, Vt as resolveStateBucketWithDefault, W as WAFv2WebACLProvider, Wt as stateBucketExistenceConfirmed, X as replayWarn, Xt as uploadCfnTemplate, Y as readConfigString, Yt as findLargeInlineResources, Z as requireConfigArray, Zt as expectedOwnerParam, _ as createPreDeleteFinalSnapshot, _n as PartialFailureError, _t as loadPublishableAssetManifest, a as DeploymentEventsStore, an as setAwsClients, at as isThrottlingError, b as unsupportedFinalSnapshotError, bn as ResourceUpdateNotSupportedError, bt as BOOTSTRAP_MARKER_PREFIX, c as replayFailedOperations, ct as LockManager, d as IMPLICIT_DELETE_DEPENDENCIES, dn as LocalInvokeBuildError$1, dt as shouldRetainResource, et as applyRoleArnIfSet, f as computeImplicitDeleteEdges, fn as LocalMigrateError, ft as AssetPublisher, g as ccRoutedFinalSnapshotError, gn as NestedStackChildDirectDestroyError, gt as createAssetRedirectResolver, h as buildFinalSnapshotIdentifier, hn as MissingCdkCliError, ht as buildAssetRedirectMap, i as DeploymentEventsReader, in as resetAwsClients, it as isRetryableTransientError, j as yellow, jt as AssetManifestLoader, k as green, kt as runDockerForeground, l as replayRollback, lt as S3StateBackend, m as PRE_DELETE_SNAPSHOT_TYPES, mt as WorkGraph, n as DEFAULT_RESOURCE_WARN_AFTER_MS, nn as AwsClients, nt as describeTypeWithThrottleRetry, o as planFailedOps, ot as DagBuilder, p as ATOMIC_FINAL_SNAPSHOT_TYPES, pn as LocalStartServiceError, pt as stringifyValue, q as assertRegionMatch, qt as CFN_TEMPLATE_URL_LIMIT, r as DeployEngine, rn as getAwsClients, rt as withRetry, s as planRollback, sn as CdkdError, st as TemplateParser, t as DEFAULT_RESOURCE_TIMEOUT_MS, tn as resolveBucketRegion, tt as DiffCalculator, u as withResourceDeadline, un as DeployCancelledError, ut as rebuildClientForBucketRegion, v as isFinalSnapshotError, vn as ProvisioningError, vt as rewriteTemplateAssetReferences, w as renderStatefulReason, wt as validateAssetBucketName, x as extractDeploymentEventError, xn as StackHasActiveImportsError, xt as ensureAssetStorage, y as refusesFinalSnapshot, yn as ResourceTimeoutError, yt as AssetModeResolver, z as disableInstanceApiTermination, zt as resolveCaptureObservedState } from "./deploy-engine-r4N9-tZD.js";
2
+ import { $ as requireConfigString, $t as processStackMessages, A as red, At as runDockerStreaming, B as isTerminationProtectionPropagationError, Bt as resolveSkipPrefix, C as isStatefulRecreateTargetSync, Ct as parseBootstrapMarker, D as cyan, Dn as normalizeAwsError, Dt as formatDockerLoginError, E as bold, Et as buildDockerImage, F as ProviderRegistry, Ft as getDefaultStateBucketName, G as normalizeAwsTagsToCfn, Gt as warnDeprecatedNoPrefixCliFlag, H as cfnRefValueFromPhysicalId, Ht as resolveStateBucketWithDefaultAndSource, I as findActionableSilentDrops, It as getLegacyStateBucketName, J as configStringRefusal, Jt as MIGRATE_TMP_PREFIX, K as resolveExplicitPhysicalId, Kt as CFN_TEMPLATE_BODY_LIMIT, L as CloudControlProvider, Lt as resolveApp, M as IAMRoleProvider, Mt as getDockerImageBySourceHash, N as collectInlinePolicyNamesManagedBySiblings, Nt as Synthesizer, O as gray, On as withErrorHandling, Ot as getDockerCmd, P as clearOnUpdateRemoval, Pt as synthesisStatusMessage, Q as requireConfigObject, Qt as AssemblyReader, R as slowCcOperationTimeoutMs, Rt as resolveAutoAssetStorage, S as MULTI_REGION_RECREATE_BLOCKED_TYPES, Sn as StackTerminationProtectionError, St as getBootstrapMarkerKey, T as formatResourceLine, Tt as validateContainerRepoName, U as refStateLookupFromResource, Ut as resolveUseCdkBootstrapAssets, V as IntrinsicFunctionResolver, Vt as resolveStateBucketWithDefault, W as WAFv2WebACLProvider, Wt as stateBucketExistenceConfirmed, X as replayWarn, Xt as uploadCfnTemplate, Y as readConfigString, Yt as findLargeInlineResources, Z as requireConfigArray, Zt as expectedOwnerParam, _ as createPreDeleteFinalSnapshot, _n as PartialFailureError, _t as loadPublishableAssetManifest, a as DeploymentEventsStore, an as setAwsClients, at as isThrottlingError, b as unsupportedFinalSnapshotError, bn as ResourceUpdateNotSupportedError, bt as BOOTSTRAP_MARKER_PREFIX, c as replayFailedOperations, ct as LockManager, d as IMPLICIT_DELETE_DEPENDENCIES, dn as LocalInvokeBuildError$1, dt as shouldRetainResource, et as applyRoleArnIfSet, f as computeImplicitDeleteEdges, fn as LocalMigrateError, ft as AssetPublisher, g as ccRoutedFinalSnapshotError, gn as NestedStackChildDirectDestroyError, gt as createAssetRedirectResolver, h as buildFinalSnapshotIdentifier, hn as MissingCdkCliError, ht as buildAssetRedirectMap, i as DeploymentEventsReader, in as resetAwsClients, it as isRetryableTransientError, j as yellow, jt as AssetManifestLoader, k as green, kt as runDockerForeground, l as replayRollback, lt as S3StateBackend, m as PRE_DELETE_SNAPSHOT_TYPES, mt as WorkGraph, n as DEFAULT_RESOURCE_WARN_AFTER_MS, nn as AwsClients, nt as describeTypeWithThrottleRetry, o as planFailedOps, ot as DagBuilder, p as ATOMIC_FINAL_SNAPSHOT_TYPES, pn as LocalStartServiceError, pt as stringifyValue, q as assertRegionMatch, qt as CFN_TEMPLATE_URL_LIMIT, r as DeployEngine, rn as getAwsClients, rt as withRetry, s as planRollback, sn as CdkdError, st as TemplateParser, t as DEFAULT_RESOURCE_TIMEOUT_MS, tn as resolveBucketRegion, tt as DiffCalculator, u as withResourceDeadline, un as DeployCancelledError, ut as rebuildClientForBucketRegion, v as isFinalSnapshotError, vn as ProvisioningError, vt as rewriteTemplateAssetReferences, w as renderStatefulReason, wt as validateAssetBucketName, x as extractDeploymentEventError, xn as StackHasActiveImportsError, xt as ensureAssetStorage, y as refusesFinalSnapshot, yn as ResourceTimeoutError, yt as AssetModeResolver, z as disableInstanceApiTermination, zt as resolveCaptureObservedState } from "./deploy-engine-2LVq2qWa.js";
3
3
  import { a as getLiveRenderer, c as PATTERN_B_RESOURCE_TYPES, d as generateResourceNameWithFallback, f as withSkipPrefix, i as runStackBuffered, n as getLogger, o as PATTERN_B_NAME_OPTIONS, p as withStackName, s as PATTERN_B_NAME_PROPERTIES, u as generateResourceName } from "./logger-BYMEE-BS.js";
4
- import { t as ASGProvider } from "./asg-provider-B62D31jG.js";
4
+ import { t as ASGProvider } from "./asg-provider-FOwZJoaD.js";
5
5
  import { AsyncLocalStorage } from "node:async_hooks";
6
6
  import { createHash, randomBytes, randomUUID } from "node:crypto";
7
7
  import { CopyObjectCommand, CreateBucketCommand, DeleteBucketAnalyticsConfigurationCommand, DeleteBucketCommand, DeleteBucketCorsCommand, DeleteBucketEncryptionCommand, DeleteBucketIntelligentTieringConfigurationCommand, DeleteBucketInventoryConfigurationCommand, DeleteBucketLifecycleCommand, DeleteBucketMetricsConfigurationCommand, DeleteBucketOwnershipControlsCommand, DeleteBucketPolicyCommand, DeleteBucketReplicationCommand, DeleteBucketTaggingCommand, DeleteBucketWebsiteCommand, DeleteObjectsCommand, GetBucketAccelerateConfigurationCommand, GetBucketCorsCommand, GetBucketEncryptionCommand, GetBucketLifecycleConfigurationCommand, GetBucketLocationCommand, GetBucketLoggingCommand, GetBucketNotificationConfigurationCommand, GetBucketOwnershipControlsCommand, GetBucketPolicyCommand, GetBucketReplicationCommand, GetBucketTaggingCommand, GetBucketVersioningCommand, GetBucketWebsiteCommand, GetObjectCommand, GetObjectLockConfigurationCommand, GetPublicAccessBlockCommand, HeadBucketCommand, ListBucketAnalyticsConfigurationsCommand, ListBucketIntelligentTieringConfigurationsCommand, ListBucketInventoryConfigurationsCommand, ListBucketMetricsConfigurationsCommand, ListObjectVersionsCommand, ListObjectsV2Command, NoSuchBucket, PutBucketAccelerateConfigurationCommand, PutBucketAnalyticsConfigurationCommand, PutBucketCorsCommand, PutBucketEncryptionCommand, PutBucketIntelligentTieringConfigurationCommand, PutBucketInventoryConfigurationCommand, PutBucketLifecycleConfigurationCommand, PutBucketLoggingCommand, PutBucketMetricsConfigurationCommand, PutBucketNotificationConfigurationCommand, PutBucketOwnershipControlsCommand, PutBucketPolicyCommand, PutBucketReplicationCommand, PutBucketTaggingCommand, PutBucketVersioningCommand, PutBucketWebsiteCommand, PutObjectCommand, PutObjectLockConfigurationCommand, PutPublicAccessBlockCommand, S3Client, S3ServiceException } from "@aws-sdk/client-s3";
@@ -49,7 +49,7 @@ import { CreateClusterCommand, CreateServiceCommand, DeleteClusterCommand, Delet
49
49
  import { AddTagsToResourceCommand as AddTagsToResourceCommand$3, CreateDBClusterCommand as CreateDBClusterCommand$1, CreateDBInstanceCommand as CreateDBInstanceCommand$1, CreateDBSubnetGroupCommand as CreateDBSubnetGroupCommand$1, DeleteDBClusterCommand as DeleteDBClusterCommand$1, DeleteDBInstanceCommand as DeleteDBInstanceCommand$1, DeleteDBSubnetGroupCommand as DeleteDBSubnetGroupCommand$1, DescribeDBClustersCommand as DescribeDBClustersCommand$1, DescribeDBInstancesCommand as DescribeDBInstancesCommand$1, DescribeDBSubnetGroupsCommand as DescribeDBSubnetGroupsCommand$1, DocDBClient, ListTagsForResourceCommand as ListTagsForResourceCommand$12, ModifyDBClusterCommand as ModifyDBClusterCommand$1, ModifyDBInstanceCommand as ModifyDBInstanceCommand$1, ModifyDBSubnetGroupCommand as ModifyDBSubnetGroupCommand$1, RemoveTagsFromResourceCommand as RemoveTagsFromResourceCommand$3 } from "@aws-sdk/client-docdb";
50
50
  import { AddTagsToResourceCommand as AddTagsToResourceCommand$4, CreateDBClusterCommand as CreateDBClusterCommand$2, CreateDBInstanceCommand as CreateDBInstanceCommand$2, CreateDBSubnetGroupCommand as CreateDBSubnetGroupCommand$2, DeleteDBClusterCommand as DeleteDBClusterCommand$2, DeleteDBInstanceCommand as DeleteDBInstanceCommand$2, DeleteDBSubnetGroupCommand as DeleteDBSubnetGroupCommand$2, DescribeDBClustersCommand as DescribeDBClustersCommand$2, DescribeDBInstancesCommand as DescribeDBInstancesCommand$2, DescribeDBSubnetGroupsCommand as DescribeDBSubnetGroupsCommand$2, ListTagsForResourceCommand as ListTagsForResourceCommand$13, ModifyDBClusterCommand as ModifyDBClusterCommand$2, ModifyDBInstanceCommand as ModifyDBInstanceCommand$2, ModifyDBSubnetGroupCommand as ModifyDBSubnetGroupCommand$2, NeptuneClient, RemoveTagsFromResourceCommand as RemoveTagsFromResourceCommand$4 } from "@aws-sdk/client-neptune";
51
51
  import { AddCustomAttributesCommand, CognitoIdentityProviderClient, CreateUserPoolCommand, DeleteUserPoolCommand, DescribeUserPoolCommand, GetUserPoolMfaConfigCommand, ListUserPoolsCommand, ResourceNotFoundException as ResourceNotFoundException$9, SetUserPoolMfaConfigCommand, UpdateUserPoolCommand } from "@aws-sdk/client-cognito-identity-provider";
52
- import { CreateHttpNamespaceCommand, CreatePrivateDnsNamespaceCommand, CreatePublicDnsNamespaceCommand, CreateServiceCommand as CreateServiceCommand$1, DeleteNamespaceCommand, DeleteServiceAttributesCommand, DeleteServiceCommand as DeleteServiceCommand$1, GetNamespaceCommand, GetOperationCommand, GetServiceAttributesCommand, GetServiceCommand, ListNamespacesCommand, ListTagsForResourceCommand as ListTagsForResourceCommand$14, NamespaceNotFound, ServiceDiscoveryClient, ServiceNotFound, TagResourceCommand as TagResourceCommand$15, UntagResourceCommand as UntagResourceCommand$15, UpdateHttpNamespaceCommand, UpdatePrivateDnsNamespaceCommand, UpdatePublicDnsNamespaceCommand, UpdateServiceAttributesCommand, UpdateServiceCommand as UpdateServiceCommand$1 } from "@aws-sdk/client-servicediscovery";
52
+ import { CreateHttpNamespaceCommand, CreatePrivateDnsNamespaceCommand, CreatePublicDnsNamespaceCommand, CreateServiceCommand as CreateServiceCommand$1, DeleteNamespaceCommand, DeleteServiceAttributesCommand, DeleteServiceCommand as DeleteServiceCommand$1, GetNamespaceCommand, GetOperationCommand, GetServiceAttributesCommand, GetServiceCommand, ListNamespacesCommand, ListTagsForResourceCommand as ListTagsForResourceCommand$14, NamespaceNotFound, ResourceInUse, ServiceDiscoveryClient, ServiceNotFound, TagResourceCommand as TagResourceCommand$15, UntagResourceCommand as UntagResourceCommand$15, UpdateHttpNamespaceCommand, UpdatePrivateDnsNamespaceCommand, UpdatePublicDnsNamespaceCommand, UpdateServiceAttributesCommand, UpdateServiceCommand as UpdateServiceCommand$1 } from "@aws-sdk/client-servicediscovery";
53
53
  import { AppSyncClient, CreateApiKeyCommand, CreateDataSourceCommand, CreateGraphqlApiCommand, CreateResolverCommand, DeleteApiKeyCommand, DeleteDataSourceCommand, DeleteGraphqlApiCommand, DeleteResolverCommand, GetDataSourceCommand, GetGraphqlApiCommand, GetGraphqlApiEnvironmentVariablesCommand, GetIntrospectionSchemaCommand, GetResolverCommand, ListApiKeysCommand, NotFoundException as NotFoundException$4, PutGraphqlApiEnvironmentVariablesCommand, StartSchemaCreationCommand, TagResourceCommand as TagResourceCommand$16, UntagResourceCommand as UntagResourceCommand$16, UpdateApiKeyCommand, UpdateDataSourceCommand, UpdateGraphqlApiCommand, UpdateResolverCommand } from "@aws-sdk/client-appsync";
54
54
  import { parse, print } from "graphql";
55
55
  import { ConcurrentModificationException, CrawlerRunningException, CreateConnectionCommand, CreateCrawlerCommand, CreateDatabaseCommand, CreateJobCommand, CreateSecurityConfigurationCommand, CreateTableCommand as CreateTableCommand$1, CreateTriggerCommand, CreateWorkflowCommand, DeleteConnectionCommand, DeleteCrawlerCommand, DeleteDatabaseCommand, DeleteJobCommand, DeleteSecurityConfigurationCommand, DeleteTableCommand as DeleteTableCommand$1, DeleteTriggerCommand, DeleteWorkflowCommand, EntityNotFoundException, GetConnectionCommand, GetCrawlerCommand, GetDatabaseCommand, GetJobCommand, GetSecurityConfigurationCommand, GetTableCommand, GetTagsCommand, GetTriggerCommand, GetWorkflowCommand, GlueClient, StartCrawlerScheduleCommand, StartTriggerCommand, StopCrawlerCommand, StopCrawlerScheduleCommand, StopTriggerCommand, UpdateConnectionCommand, UpdateCrawlerCommand, UpdateDatabaseCommand, UpdateJobCommand, UpdateTableCommand as UpdateTableCommand$1, UpdateTriggerCommand, UpdateWorkflowCommand } from "@aws-sdk/client-glue";
@@ -26391,6 +26391,15 @@ const DEPLOYMENT_CONFIG_PRESERVE_KEYS = /* @__PURE__ */ new Set(["HookDetails"])
26391
26391
  */
26392
26392
  const DEPLOYMENT_CONFIG_PRESERVE_KEYS_CAMEL = /* @__PURE__ */ new Set(["hookDetails"]);
26393
26393
  /**
26394
+ * `ServiceConnectConfiguration.LogConfiguration.Options` is a free-form
26395
+ * log-driver option map (e.g. `awslogs-group`) whose keys are user data, NOT
26396
+ * CloudFormation property names — copy the value subtree verbatim while the
26397
+ * `Options` key itself still flips to `options` (issue #609; same rule as
26398
+ * `DEPLOYMENT_CONFIG_PRESERVE_KEYS` above and the container-level
26399
+ * `LogConfiguration.Options` handling in `convertLogConfiguration`).
26400
+ */
26401
+ const SERVICE_CONNECT_PRESERVE_KEYS = /* @__PURE__ */ new Set(["Options"]);
26402
+ /**
26394
26403
  * Derive the cluster name from a long-format ECS Service ARN
26395
26404
  * (`arn:<partition>:ecs:<region>:<account>:service/<clusterName>/<serviceName>`)
26396
26405
  * so `DescribeServices` can be scoped to the right cluster (issue #1170).
@@ -26418,6 +26427,12 @@ function clusterNameFromServiceArn(arn) {
26418
26427
  * The CC API adds unnecessary polling overhead for operations that
26419
26428
  * complete immediately. This SDK provider eliminates that polling.
26420
26429
  */
26430
+ /**
26431
+ * Test seam for `settleService`'s post-stability rollout poll (the sibling of
26432
+ * `finalSnapshotDelays` / `describeTypeRetryDelays`) — tests replace `sleep`
26433
+ * to skip the real 3s waits.
26434
+ */
26435
+ const settleRolloutDelays = { sleep: (ms) => new Promise((resolve) => setTimeout(resolve, ms)) };
26421
26436
  var ECSProvider = class {
26422
26437
  ecsClient;
26423
26438
  providerRegion = process.env["AWS_REGION"];
@@ -26470,10 +26485,18 @@ var ECSProvider = class {
26470
26485
  "PropagateTags",
26471
26486
  "EnableExecuteCommand",
26472
26487
  "ServiceRegistries",
26473
- "Tags"
26488
+ "Tags",
26489
+ "AvailabilityZoneRebalancing",
26490
+ "DeploymentController",
26491
+ "ForceNewDeployment",
26492
+ "Monitoring",
26493
+ "Role",
26494
+ "ServiceConnectConfiguration",
26495
+ "VolumeConfigurations",
26496
+ "VpcLatticeConfigurations"
26474
26497
  ])]
26475
26498
  ]);
26476
- unhandledByDesign = /* @__PURE__ */ new Map([["AWS::ECS::Service", /* @__PURE__ */ new Map([["Role", "Legacy classic-ELB service-linked-role override; AWS uses the AWSServiceRoleForECS service-linked role automatically since 2017"]])], ["AWS::ECS::TaskDefinition", /* @__PURE__ */ new Map([["InferenceAccelerators", "AWS Elastic Inference end-of-life 2024-04; use AWS Inferentia / Trainium accelerator instance families instead"]])]]);
26499
+ unhandledByDesign = /* @__PURE__ */ new Map([["AWS::ECS::TaskDefinition", /* @__PURE__ */ new Map([["InferenceAccelerators", "AWS Elastic Inference end-of-life 2024-04; use AWS Inferentia / Trainium accelerator instance families instead"]])]]);
26477
26500
  getClient() {
26478
26501
  if (!this.ecsClient) this.ecsClient = new ECSClient(this.providerRegion ? { region: this.providerRegion } : {});
26479
26502
  return this.ecsClient;
@@ -26688,7 +26711,14 @@ var ECSProvider = class {
26688
26711
  propagateTags: properties["PropagateTags"],
26689
26712
  enableExecuteCommand: properties["EnableExecuteCommand"],
26690
26713
  serviceRegistries: this.convertServiceRegistries(properties["ServiceRegistries"]),
26691
- tags: convertTags(properties["Tags"])
26714
+ tags: convertTags(properties["Tags"]),
26715
+ availabilityZoneRebalancing: properties["AvailabilityZoneRebalancing"],
26716
+ deploymentController: this.convertDeploymentController(properties["DeploymentController"]),
26717
+ role: properties["Role"],
26718
+ serviceConnectConfiguration: this.convertServiceConnectConfiguration(properties["ServiceConnectConfiguration"]),
26719
+ volumeConfigurations: this.convertServiceVolumeConfigurations(properties["VolumeConfigurations"]),
26720
+ vpcLatticeConfigurations: this.convertVpcLatticeConfigurations(properties["VpcLatticeConfigurations"]),
26721
+ monitoring: this.convertMonitoringConfiguration(properties["Monitoring"])
26692
26722
  }))).service;
26693
26723
  if (!service || !service.serviceArn) throw new Error("CreateService did not return service ARN");
26694
26724
  this.logger.debug(`Successfully created ECS service ${logicalId}: ${service.serviceArn}`);
@@ -26753,6 +26783,20 @@ var ECSProvider = class {
26753
26783
  cluster,
26754
26784
  services: [serviceRef]
26755
26785
  });
26786
+ const rolloutDeadline = Date.now() + 12e4;
26787
+ for (;;) {
26788
+ const deployments = (await this.getClient().send(new DescribeServicesCommand({
26789
+ cluster,
26790
+ services: [serviceRef]
26791
+ })))?.services?.[0]?.deployments;
26792
+ const rolloutState = deployments && deployments.length === 1 ? deployments[0]?.rolloutState : void 0;
26793
+ if (rolloutState === void 0 || rolloutState === "COMPLETED") break;
26794
+ if (Date.now() >= rolloutDeadline) {
26795
+ this.logger.warn(`ECS service ${logicalId} is steady but its rollout is still ${rolloutState} after the post-stability grace window; continuing`);
26796
+ break;
26797
+ }
26798
+ await settleRolloutDelays.sleep(3e3);
26799
+ }
26756
26800
  this.logger.debug(`ECS service ${logicalId} reached steady state`);
26757
26801
  return;
26758
26802
  }
@@ -26786,6 +26830,13 @@ var ECSProvider = class {
26786
26830
  const enableECSManagedTagsInput = clearOnUpdateRemoval(properties["EnableECSManagedTags"], previousProperties["EnableECSManagedTags"], false);
26787
26831
  const propagateTagsInput = clearOnUpdateRemoval(properties["PropagateTags"], previousProperties["PropagateTags"], "NONE");
26788
26832
  const enableExecuteCommandInput = clearOnUpdateRemoval(properties["EnableExecuteCommand"], previousProperties["EnableExecuteCommand"], false);
26833
+ const availabilityZoneRebalancingInput = JSON.stringify(previousProperties["AvailabilityZoneRebalancing"] ?? null) !== JSON.stringify(properties["AvailabilityZoneRebalancing"] ?? null) && properties["AvailabilityZoneRebalancing"] !== void 0 ? properties["AvailabilityZoneRebalancing"] : void 0;
26834
+ const deploymentControllerInput = JSON.stringify(previousProperties["DeploymentController"] ?? null) !== JSON.stringify(properties["DeploymentController"] ?? null) && properties["DeploymentController"] != null ? this.convertDeploymentController(properties["DeploymentController"]) : void 0;
26835
+ const serviceConnectConfigurationInput = JSON.stringify(previousProperties["ServiceConnectConfiguration"] ?? null) !== JSON.stringify(properties["ServiceConnectConfiguration"] ?? null) ? clearOnUpdateRemoval(this.convertServiceConnectConfiguration(properties["ServiceConnectConfiguration"]), previousProperties["ServiceConnectConfiguration"], { enabled: false }) : void 0;
26836
+ const volumeConfigurationsInput = JSON.stringify(previousProperties["VolumeConfigurations"] ?? null) !== JSON.stringify(properties["VolumeConfigurations"] ?? null) ? clearOnUpdateRemoval(this.convertServiceVolumeConfigurations(properties["VolumeConfigurations"]), previousProperties["VolumeConfigurations"], []) : void 0;
26837
+ const vpcLatticeConfigurationsInput = JSON.stringify(previousProperties["VpcLatticeConfigurations"] ?? null) !== JSON.stringify(properties["VpcLatticeConfigurations"] ?? null) ? clearOnUpdateRemoval(this.convertVpcLatticeConfigurations(properties["VpcLatticeConfigurations"]), previousProperties["VpcLatticeConfigurations"], []) : void 0;
26838
+ const monitoringInput = JSON.stringify(previousProperties["Monitoring"] ?? null) !== JSON.stringify(properties["Monitoring"] ?? null) && properties["Monitoring"] != null ? this.convertMonitoringConfiguration(properties["Monitoring"]) : void 0;
26839
+ const forceNewDeploymentInput = this.resolveForceNewDeployment(properties, previousProperties);
26789
26840
  try {
26790
26841
  const service = (await client.send(new UpdateServiceCommand({
26791
26842
  cluster: properties["Cluster"],
@@ -26803,7 +26854,14 @@ var ECSProvider = class {
26803
26854
  propagateTags: propagateTagsInput,
26804
26855
  enableExecuteCommand: enableExecuteCommandInput,
26805
26856
  loadBalancers: loadBalancersInput,
26806
- serviceRegistries: serviceRegistriesInput
26857
+ serviceRegistries: serviceRegistriesInput,
26858
+ availabilityZoneRebalancing: availabilityZoneRebalancingInput,
26859
+ deploymentController: deploymentControllerInput,
26860
+ serviceConnectConfiguration: serviceConnectConfigurationInput,
26861
+ volumeConfigurations: volumeConfigurationsInput,
26862
+ vpcLatticeConfigurations: vpcLatticeConfigurationsInput,
26863
+ monitoring: monitoringInput,
26864
+ forceNewDeployment: forceNewDeploymentInput
26807
26865
  }))).service;
26808
26866
  if (service?.serviceArn) await this.applyTagDiff(service.serviceArn, previousProperties["Tags"], properties["Tags"]);
26809
26867
  await this.settleService(logicalId, service?.serviceName ?? physicalId, properties["Cluster"]);
@@ -27537,6 +27595,96 @@ var ECSProvider = class {
27537
27595
  return pascalToCamelCaseKeys(items);
27538
27596
  }
27539
27597
  /**
27598
+ * Convert the CFn PascalCase `DeploymentController` block (`{Type}`) to the
27599
+ * ECS SDK camelCase input shape (`{type}`) — a pure first-letter flip
27600
+ * (issue #609).
27601
+ */
27602
+ convertDeploymentController(config) {
27603
+ if (!config) return void 0;
27604
+ return pascalToCamelCaseKeys(config);
27605
+ }
27606
+ /**
27607
+ * Convert the CFn PascalCase `ServiceConnectConfiguration` block to the ECS
27608
+ * SDK camelCase input shape (issue #609). Every key in the subtree is a pure
27609
+ * first-letter flip (`Enabled` / `Namespace` / `Services[].{PortName,
27610
+ * DiscoveryName, ClientAliases, IngressPortOverride, Timeout, Tls}` /
27611
+ * `LogConfiguration` / `AccessLogConfiguration`), so the shared recursive
27612
+ * converter delivers the whole subtree — EXCEPT
27613
+ * `LogConfiguration.Options`, a free-form log-driver option map copied
27614
+ * verbatim (see {@link SERVICE_CONNECT_PRESERVE_KEYS}).
27615
+ */
27616
+ convertServiceConnectConfiguration(config) {
27617
+ if (!config) return void 0;
27618
+ return pascalToCamelCaseKeys(config, SERVICE_CONNECT_PRESERVE_KEYS);
27619
+ }
27620
+ /**
27621
+ * Convert the CFn PascalCase `VolumeConfigurations` array to the ECS SDK
27622
+ * camelCase input shape (issue #609). Every key is a pure first-letter flip
27623
+ * — including the two spellings worth calling out: `ManagedEBSVolume` ->
27624
+ * `managedEBSVolume` and `SizeInGiB` -> `sizeInGiB` (both verified against
27625
+ * the SDK model; only the FIRST character flips, the interior case is
27626
+ * identical), so the shared recursive converter delivers the whole subtree
27627
+ * (`Encrypted` / `KmsKeyId` / `VolumeType` / `SnapshotId` /
27628
+ * `VolumeInitializationRate` / `Iops` / `Throughput` / `TagSpecifications`
27629
+ * / `RoleArn` / `FilesystemType`).
27630
+ */
27631
+ convertServiceVolumeConfigurations(items) {
27632
+ if (!items) return void 0;
27633
+ return pascalToCamelCaseKeys(items);
27634
+ }
27635
+ /**
27636
+ * Convert the CFn PascalCase `VpcLatticeConfigurations` array to the ECS
27637
+ * SDK camelCase input shape (issue #609). Each element `{RoleArn,
27638
+ * TargetGroupArn, PortName}` is a pure first-letter flip.
27639
+ */
27640
+ convertVpcLatticeConfigurations(items) {
27641
+ if (!items) return void 0;
27642
+ return pascalToCamelCaseKeys(items);
27643
+ }
27644
+ /**
27645
+ * Convert the CFn PascalCase `Monitoring` block to the ECS SDK camelCase
27646
+ * `monitoring` input shape (issue #609). Every key is a pure first-letter
27647
+ * flip (`MetricConfigurations[].{MetricNames, ResolutionSeconds}`).
27648
+ */
27649
+ convertMonitoringConfiguration(config) {
27650
+ if (!config) return void 0;
27651
+ return pascalToCamelCaseKeys(config);
27652
+ }
27653
+ /**
27654
+ * Translate the CFn-only `ForceNewDeployment` trigger object
27655
+ * (`{EnableForceNewDeployment, ForceNewDeploymentNonce}`) into the SDK's
27656
+ * plain `forceNewDeployment` boolean on UpdateService (issue #609).
27657
+ *
27658
+ * A forced rollout is requested when EITHER the template says
27659
+ * `EnableForceNewDeployment: true` OR the nonce changed vs the previous
27660
+ * deploy's recorded value (introducing a nonce counts as a change). On any
27661
+ * other shape — block absent, malformed, enable false with an unchanged
27662
+ * nonce — return `undefined` so the field is omitted (AWS's documented
27663
+ * default: deployments are not forced).
27664
+ *
27665
+ * Create-path: deliberate no-op — CreateService has no such member, and the
27666
+ * initial deployment IS a fresh rollout by definition.
27667
+ *
27668
+ * This is UPDATE-path code, so a malformed desired block WARNS and skips
27669
+ * rather than throwing (the config-shape doctrine: a rollback replays
27670
+ * `update()` with a historical state record as the desired bag).
27671
+ */
27672
+ resolveForceNewDeployment(properties, previousProperties) {
27673
+ const desired = properties["ForceNewDeployment"];
27674
+ if (desired == null) return void 0;
27675
+ if (typeof desired !== "object" || Array.isArray(desired)) {
27676
+ this.logger.warn(`AWS::ECS::Service ForceNewDeployment is not an object (got ${Array.isArray(desired) ? "array" : typeof desired}); skipping the forced-rollout translation`);
27677
+ return;
27678
+ }
27679
+ const block = desired;
27680
+ const enable = this.coerceBool(block["EnableForceNewDeployment"]);
27681
+ const nonce = block["ForceNewDeploymentNonce"];
27682
+ const previous = previousProperties["ForceNewDeployment"];
27683
+ const previousNonce = previous != null && typeof previous === "object" && !Array.isArray(previous) ? previous["ForceNewDeploymentNonce"] : void 0;
27684
+ const nonceChanged = nonce !== void 0 && JSON.stringify(nonce) !== JSON.stringify(previousNonce);
27685
+ return enable === true || nonceChanged ? true : void 0;
27686
+ }
27687
+ /**
27540
27688
  * Convert the CFn PascalCase `TaskDefinition.RuntimePlatform` to the ECS SDK
27541
27689
  * camelCase input shape (issue #1165). `{CpuArchitecture,
27542
27690
  * OperatingSystemFamily}` -> `{cpuArchitecture, operatingSystemFamily}`.
@@ -27645,6 +27793,35 @@ var ECSProvider = class {
27645
27793
  return false;
27646
27794
  }
27647
27795
  /**
27796
+ * State property paths `readCurrentState` deliberately cannot read back
27797
+ * from AWS (issue #609) — fed into the drift comparator's `ignorePaths` so
27798
+ * a template that sets them does not phantom-drift as "removed" on every
27799
+ * run:
27800
+ * - `ServiceConnectConfiguration` / `VolumeConfigurations` /
27801
+ * `VpcLatticeConfigurations`: DescribeServices does not return them on
27802
+ * the top-level `Service` shape (they surface only per-deployment
27803
+ * under `deployments[]`, which is rollout metadata, not service
27804
+ * config). `VolumeConfigurations` is also registry-recorded write-only.
27805
+ * - `Monitoring`: not returned by DescribeServices at all.
27806
+ * - `ForceNewDeployment`: a write-only rollout trigger, not persisted
27807
+ * service state.
27808
+ * - `Role`: AWS reports `Service.roleArn` as the service-linked
27809
+ * AWSServiceRoleForECS ARN when the template omits Role, and always as
27810
+ * a full ARN when the template may carry a bare role name — a
27811
+ * mechanical reverse-map would manufacture drift in both directions.
27812
+ */
27813
+ getDriftUnknownPaths(resourceType) {
27814
+ if (resourceType === "AWS::ECS::Service") return [
27815
+ "ServiceConnectConfiguration",
27816
+ "VolumeConfigurations",
27817
+ "VpcLatticeConfigurations",
27818
+ "Monitoring",
27819
+ "ForceNewDeployment",
27820
+ "Role"
27821
+ ];
27822
+ return [];
27823
+ }
27824
+ /**
27648
27825
  * Read the AWS-current ECS resource configuration in CFn-property shape.
27649
27826
  *
27650
27827
  * Dispatches by resource type:
@@ -27748,6 +27925,8 @@ var ECSProvider = class {
27748
27925
  result["PlacementStrategies"] = strategy;
27749
27926
  }
27750
27927
  result["ServiceRegistries"] = camelToPascalCaseKeys(s.serviceRegistries ?? []);
27928
+ if (s.availabilityZoneRebalancing !== void 0) result["AvailabilityZoneRebalancing"] = s.availabilityZoneRebalancing;
27929
+ result["DeploymentController"] = { Type: s.deploymentController?.type ?? "ECS" };
27751
27930
  result["Tags"] = normalizeAwsTagsToCfn(s.tags);
27752
27931
  return result;
27753
27932
  }
@@ -34110,8 +34289,16 @@ var ServiceDiscoveryProvider = class ServiceDiscoveryProvider {
34110
34289
  this.logger.debug(`Deleting Cloud Map namespace ${logicalId}: ${physicalId}`);
34111
34290
  const client = this.getClient();
34112
34291
  try {
34113
- const operationId = (await client.send(new DeleteNamespaceCommand({ Id: physicalId }))).OperationId;
34114
- if (operationId) await this.pollOperation(operationId, logicalId, resourceType);
34292
+ await withRetry(async () => {
34293
+ const operationId = (await client.send(new DeleteNamespaceCommand({ Id: physicalId }))).OperationId;
34294
+ if (operationId) await this.pollOperation(operationId, logicalId, resourceType);
34295
+ }, logicalId, {
34296
+ maxRetries: 24,
34297
+ initialDelayMs: 3e3,
34298
+ maxDelayMs: 15e3,
34299
+ isRetryable: (message, error) => error instanceof ResourceInUse || /has associated services/i.test(message),
34300
+ logger: this.logger
34301
+ });
34115
34302
  this.logger.debug(`Successfully deleted Cloud Map namespace ${logicalId}`);
34116
34303
  } catch (error) {
34117
34304
  if (error instanceof NamespaceNotFound) {
@@ -52746,7 +52933,7 @@ function findRevertDroppedAwsKeys(drifts, desiredProperties, awsProperties) {
52746
52933
  }
52747
52934
  for (const key of driftedTopLevelKeys) {
52748
52935
  if (!(key in desiredProperties)) continue;
52749
- collectMissingPaths(awsProperties[key], desiredProperties[key], key, dropped);
52936
+ collectMissingPaths(awsProperties[key], desiredProperties[key], key, dropped, isTagListKey(key) ? isServiceManagedTagKey : void 0);
52750
52937
  }
52751
52938
  return [...dropped].sort();
52752
52939
  }
@@ -52754,12 +52941,46 @@ function findRevertDroppedAwsKeys(drifts, desiredProperties, awsProperties) {
52754
52941
  * Walk the AWS-side value against the desired-side value, recording every path
52755
52942
  * present on the AWS side and absent on the desired side.
52756
52943
  *
52757
- * Only plain objects are descended into. An ARRAY is compared wholesale — the
52758
- * drift comparator itself treats arrays as single values (its paths never
52944
+ * Plain objects are descended into. A POSITIONAL array is compared wholesale —
52945
+ * the drift comparator itself treats arrays as single values (its paths never
52759
52946
  * carry an index), so an element-wise walk here would report positions the
52760
52947
  * rest of the revert path cannot reason about.
52761
- */
52762
- function collectMissingPaths(awsValue, desiredValue, path, out) {
52948
+ *
52949
+ * A KEYED list is the exception, and it is the shape with the most to drop
52950
+ * (issue [#1626](https://github.com/go-to-k/cdkd/issues/1626)). An
52951
+ * `[{Key, Value}]` list is semantically a MAP that CFn spells as an array —
52952
+ * ELBv2 `LoadBalancerAttributes`, `ListenerAttributes`, `TargetGroupAttributes`
52953
+ * and every `Tags` list are this shape — so its entries have stable identities,
52954
+ * not positions, and `Key` is exactly what the user would act on. Skipping it
52955
+ * left the pass blind precisely where `readCurrentState` returns AWS's FULL
52956
+ * attribute set (~20 entries) against a template that declares one or two: the
52957
+ * plan warned about nothing while the revert was about to touch eighteen keys.
52958
+ *
52959
+ * Keyed-list entries are reported in BRACKET form (`LoadBalancerAttributes
52960
+ * [deletion_protection.enabled]`) rather than dotted, because attribute keys
52961
+ * contain dots themselves and a dotted path would be ambiguous with a nested
52962
+ * object.
52963
+ *
52964
+ * `isPreservedKey` exempts entries the revert does NOT actually drop — the
52965
+ * caller passes {@link isServiceManagedTagKey} for a top-level TAG LIST, whose
52966
+ * revert goes through {@link mergeTagListForRevert} and keeps `aws:`-prefixed /
52967
+ * `AmazonECSManaged` entries (issue #1501). Reporting those would be a warning
52968
+ * about a loss that cannot happen.
52969
+ */
52970
+ function collectMissingPaths(awsValue, desiredValue, path, out, isPreservedKey) {
52971
+ if (isKeyedList(awsValue)) {
52972
+ if (!isKeyedList(desiredValue)) {
52973
+ if (desiredValue === void 0) out.add(path);
52974
+ return;
52975
+ }
52976
+ const desiredKeys = new Set(desiredValue.map((e) => e.Key));
52977
+ for (const entry of awsValue) {
52978
+ if (desiredKeys.has(entry.Key)) continue;
52979
+ if (isPreservedKey?.(entry.Key)) continue;
52980
+ out.add(`${path}[${entry.Key}]`);
52981
+ }
52982
+ return;
52983
+ }
52763
52984
  if (!isPlainRecord(awsValue)) return;
52764
52985
  if (!isPlainRecord(desiredValue)) {
52765
52986
  if (desiredValue === void 0) out.add(path);
@@ -52774,6 +52995,17 @@ function collectMissingPaths(awsValue, desiredValue, path, out) {
52774
52995
  collectMissingPaths(value, desiredValue[key], childPath, out);
52775
52996
  }
52776
52997
  }
52998
+ /**
52999
+ * A NON-EMPTY array whose every element is an object carrying a string `Key`.
53000
+ *
53001
+ * Emptiness is deliberately excluded: `[]` carries no identities, so treating
53002
+ * it as keyed would report nothing on the AWS side and — as the DESIRED side —
53003
+ * would claim every AWS entry is dropped, which is already what the
53004
+ * whole-list arm reports more legibly.
53005
+ */
53006
+ function isKeyedList(value) {
53007
+ return Array.isArray(value) && value.length > 0 && value.every((e) => typeof e === "object" && e !== null && typeof e.Key === "string");
53008
+ }
52777
53009
  function isPlainRecord(value) {
52778
53010
  return typeof value === "object" && value !== null && !Array.isArray(value);
52779
53011
  }
@@ -69920,7 +70152,7 @@ function createMigrateCommand() {
69920
70152
  */
69921
70153
  function buildProgram() {
69922
70154
  const program = new Command();
69923
- program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.280.19");
70155
+ program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.280.21");
69924
70156
  program.hook("preAction", (_thisCommand, actionCommand) => {
69925
70157
  const { profile } = actionCommand.optsWithGlobals();
69926
70158
  if (profile !== void 0) process.env["AWS_PROFILE"] = profile;