@go-to-k/cdkd 0.280.18 → 0.280.20
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/{asg-provider-C6cQkX3h.js → asg-provider-BWT5cpBO.js} +2 -2
- package/dist/{asg-provider-C6cQkX3h.js.map → asg-provider-BWT5cpBO.js.map} +1 -1
- package/dist/cli.js +336 -26
- package/dist/cli.js.map +1 -1
- package/dist/{deploy-engine-mvkiu-7h.js → deploy-engine-CC3BV-Gp.js} +13 -14
- package/dist/{deploy-engine-mvkiu-7h.js.map → deploy-engine-CC3BV-Gp.js.map} +1 -1
- package/dist/index.js +1 -1
- package/package.json +1 -1
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-
|
|
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-CC3BV-Gp.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-
|
|
4
|
+
import { t as ASGProvider } from "./asg-provider-BWT5cpBO.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::
|
|
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
|
}
|
|
@@ -27873,6 +28052,78 @@ const TARGET_GROUP_ATTRIBUTE_DEFAULTS = {
|
|
|
27873
28052
|
"proxy_protocol_v2.enabled": "false"
|
|
27874
28053
|
};
|
|
27875
28054
|
/**
|
|
28055
|
+
* Documented AWS defaults for the BOOLEAN / ENUM-valued LoadBalancer and
|
|
28056
|
+
* Listener attributes, used to reset a removed `LoadBalancerAttributes` /
|
|
28057
|
+
* `ListenerAttributes` entry.
|
|
28058
|
+
*
|
|
28059
|
+
* Unlike ModifyTargetGroupAttributes — which rejects an empty `Value` for
|
|
28060
|
+
* EVERY key — these two APIs accept `Value: ''` for the numeric and
|
|
28061
|
+
* free-form string attributes and REJECT it only where the value is
|
|
28062
|
+
* validated against a fixed set. Live A/B 2026-08-11 (issue #1609 item 1),
|
|
28063
|
+
* via the `alb` integ's removal phase:
|
|
28064
|
+
*
|
|
28065
|
+
* idle_timeout.timeout_seconds -> `Value: ''` ACCEPTED (numeric)
|
|
28066
|
+
* deletion_protection.enabled -> "The value of 'deletion_protection.enabled'
|
|
28067
|
+
* must be 'true' or 'false', but was ''"
|
|
28068
|
+
* routing.http.response.server.enabled (Listener)
|
|
28069
|
+
* -> same rejection, same shape
|
|
28070
|
+
*
|
|
28071
|
+
* A rejection fails the whole Modify* call, so ONE removed boolean took the
|
|
28072
|
+
* entire deploy down (and then the rollback with it). Hence: send the
|
|
28073
|
+
* documented default for the validated keys, and keep the empty string for
|
|
28074
|
+
* everything else — which is both these APIs' own "clear the override"
|
|
28075
|
+
* signal and the behaviour every non-boolean key already relied on.
|
|
28076
|
+
*
|
|
28077
|
+
* That fallback is the deliberate DIVERGENCE from
|
|
28078
|
+
* TARGET_GROUP_ATTRIBUTE_DEFAULTS, whose unknown-key arm warns and retains:
|
|
28079
|
+
* there the empty string is never valid, here it is valid for the majority
|
|
28080
|
+
* of keys, so falling back to it preserves working behaviour instead of
|
|
28081
|
+
* silently retaining a value the template asked to drop.
|
|
28082
|
+
*
|
|
28083
|
+
* A key is listed ONLY when ONE unconditional default is established for it —
|
|
28084
|
+
* documented in the SDK model, or (for
|
|
28085
|
+
* `routing.http.response.server.enabled`, which the model leaves unstated)
|
|
28086
|
+
* proven by the `alb` integ's live removal readback. Two exclusion classes
|
|
28087
|
+
* matter, and both are the difference between failing loudly and writing a
|
|
28088
|
+
* wrong value silently:
|
|
28089
|
+
*
|
|
28090
|
+
* - **Default depends on the LOAD BALANCER** — `load_balancing.cross_zone.enabled`
|
|
28091
|
+
* is always-on and unconfigurable for an ALB but defaults to false on an
|
|
28092
|
+
* NLB / GWLB, and `ipv6.deny_all_igw_traffic` is "false for internet-facing
|
|
28093
|
+
* load balancers and true for internal load balancers". cdkd knows neither
|
|
28094
|
+
* the type nor the scheme at diff time, so a hardcoded entry would send the
|
|
28095
|
+
* WRONG value for half of all load balancers — and since it is a valid
|
|
28096
|
+
* boolean, AWS accepts it. For `ipv6.deny_all_igw_traffic` that means
|
|
28097
|
+
* silently un-blocking internet-gateway access on an INTERNAL load balancer.
|
|
28098
|
+
* - **No documented default at all** — `dns_record.client_routing_policy`
|
|
28099
|
+
* enumerates its possible values but states no default.
|
|
28100
|
+
*
|
|
28101
|
+
* Both classes keep the empty-string behaviour they have always had, so a
|
|
28102
|
+
* removal there fails loudly (for a validated key) instead of guessing.
|
|
28103
|
+
*
|
|
28104
|
+
* Source: the `@aws-sdk/client-elastic-load-balancing-v2` model docs for
|
|
28105
|
+
* `ModifyLoadBalancerAttributes` / `ModifyListenerAttributes`, checked per key;
|
|
28106
|
+
* `routing.http.response.server.enabled`'s default is additionally LIVE-proven
|
|
28107
|
+
* by the `alb` integ's removal readback rather than taken from the docs.
|
|
28108
|
+
*/
|
|
28109
|
+
const LOAD_BALANCER_ATTRIBUTE_DEFAULTS = {
|
|
28110
|
+
"deletion_protection.enabled": "false",
|
|
28111
|
+
"access_logs.s3.enabled": "false",
|
|
28112
|
+
"connection_logs.s3.enabled": "false",
|
|
28113
|
+
"health_check_logs.s3.enabled": "false",
|
|
28114
|
+
"routing.http.desync_mitigation_mode": "defensive",
|
|
28115
|
+
"routing.http.drop_invalid_header_fields.enabled": "false",
|
|
28116
|
+
"routing.http.preserve_host_header.enabled": "false",
|
|
28117
|
+
"routing.http.x_amzn_tls_version_and_cipher_suite.enabled": "false",
|
|
28118
|
+
"routing.http.xff_client_port.enabled": "false",
|
|
28119
|
+
"routing.http.xff_header_processing.mode": "append",
|
|
28120
|
+
"routing.http2.enabled": "true",
|
|
28121
|
+
"waf.fail_open.enabled": "false",
|
|
28122
|
+
"zonal_shift.config.enabled": "false"
|
|
28123
|
+
};
|
|
28124
|
+
/** @see LOAD_BALANCER_ATTRIBUTE_DEFAULTS — same rule, Listener key table. */
|
|
28125
|
+
const LISTENER_ATTRIBUTE_DEFAULTS = { "routing.http.response.server.enabled": "true" };
|
|
28126
|
+
/**
|
|
27876
28127
|
* AWS ELBv2 Provider
|
|
27877
28128
|
*
|
|
27878
28129
|
* Implements resource provisioning for ELBv2 resources:
|
|
@@ -28085,7 +28336,7 @@ var ELBv2Provider = class {
|
|
|
28085
28336
|
return out;
|
|
28086
28337
|
};
|
|
28087
28338
|
if (JSON.stringify(stripHandled(properties)) !== JSON.stringify(stripHandled(previousProperties))) throw new ResourceUpdateNotSupportedError("AWS::ElasticLoadBalancingV2::LoadBalancer", logicalId, "ELBv2 LoadBalancer Name / Type / Scheme are immutable on AWS — none of the ELBv2 Modify* / Set* APIs accept these fields; they are fixed at creation. cdkd handles LoadBalancerAttributes / Subnets / SubnetMappings / SecurityGroups / IpAddressType / Tags in-place; for Name / Type / Scheme re-deploy with cdkd deploy --replace, or destroy + redeploy the stack.");
|
|
28088
|
-
const submittedAttrs = this.diffAttributes(this.normalizeAttributes(properties["LoadBalancerAttributes"]), this.normalizeAttributes(previousProperties["LoadBalancerAttributes"]));
|
|
28339
|
+
const submittedAttrs = this.diffAttributes(this.normalizeAttributes(properties["LoadBalancerAttributes"]), this.normalizeAttributes(previousProperties["LoadBalancerAttributes"]), this.attributeRemovalResolver(LOAD_BALANCER_ATTRIBUTE_DEFAULTS));
|
|
28089
28340
|
if (submittedAttrs.length > 0) {
|
|
28090
28341
|
await this.getClient().send(new ModifyLoadBalancerAttributesCommand({
|
|
28091
28342
|
LoadBalancerArn: physicalId,
|
|
@@ -28309,10 +28560,13 @@ var ELBv2Provider = class {
|
|
|
28309
28560
|
UnhealthyThresholdCount: properties["UnhealthyThresholdCount"] !== void 0 ? Number(properties["UnhealthyThresholdCount"]) : void 0,
|
|
28310
28561
|
...matcher && { Matcher: matcher }
|
|
28311
28562
|
}));
|
|
28312
|
-
const tgAttrDiff = this.diffAttributes(this.normalizeAttributes(properties["TargetGroupAttributes"]), this.normalizeAttributes(previousProperties["TargetGroupAttributes"]), (key) => {
|
|
28313
|
-
const fallback = TARGET_GROUP_ATTRIBUTE_DEFAULTS[key];
|
|
28314
|
-
if (fallback === void 0)
|
|
28315
|
-
|
|
28563
|
+
const tgAttrDiff = this.diffAttributes(this.normalizeAttributes(properties["TargetGroupAttributes"]), this.normalizeAttributes(previousProperties["TargetGroupAttributes"]), (key, currentValue) => {
|
|
28564
|
+
const fallback = Object.hasOwn(TARGET_GROUP_ATTRIBUTE_DEFAULTS, key) ? TARGET_GROUP_ATTRIBUTE_DEFAULTS[key] : void 0;
|
|
28565
|
+
if (fallback === void 0) {
|
|
28566
|
+
this.logger.warn(`TargetGroup attribute ${key} was removed from the template but has no documented default cdkd can reset it to — the live value is retained. Set the attribute explicitly to change it.`);
|
|
28567
|
+
return;
|
|
28568
|
+
}
|
|
28569
|
+
return currentValue === fallback ? void 0 : fallback;
|
|
28316
28570
|
});
|
|
28317
28571
|
if (tgAttrDiff.length > 0) {
|
|
28318
28572
|
await this.getClient().send(new ModifyTargetGroupAttributesCommand({
|
|
@@ -28444,7 +28698,7 @@ var ELBv2Provider = class {
|
|
|
28444
28698
|
...alpnPolicy && alpnPolicy.length > 0 && { AlpnPolicy: alpnPolicy },
|
|
28445
28699
|
...mutualAuth !== void 0 && { MutualAuthentication: mutualAuth }
|
|
28446
28700
|
}));
|
|
28447
|
-
const submittedAttrs = this.diffAttributes(this.normalizeAttributes(properties["ListenerAttributes"]), this.normalizeAttributes(previousProperties["ListenerAttributes"]));
|
|
28701
|
+
const submittedAttrs = this.diffAttributes(this.normalizeAttributes(properties["ListenerAttributes"]), this.normalizeAttributes(previousProperties["ListenerAttributes"]), this.attributeRemovalResolver(LISTENER_ATTRIBUTE_DEFAULTS));
|
|
28448
28702
|
if (submittedAttrs.length > 0) {
|
|
28449
28703
|
await withRetry(() => this.getClient().send(new ModifyListenerAttributesCommand({
|
|
28450
28704
|
ListenerArn: physicalId,
|
|
@@ -28522,14 +28776,28 @@ var ELBv2Provider = class {
|
|
|
28522
28776
|
/**
|
|
28523
28777
|
* Key-diff two normalized `{Key, Value}` attribute lists into the payload
|
|
28524
28778
|
* for a Modify*Attributes call: changed values from `newAttrs` win, and
|
|
28525
|
-
* keys present only in `oldAttrs` are pushed back through `removalValue
|
|
28526
|
-
*
|
|
28527
|
-
*
|
|
28528
|
-
*
|
|
28529
|
-
*
|
|
28530
|
-
*
|
|
28531
|
-
|
|
28532
|
-
|
|
28779
|
+
* keys present only in `oldAttrs` are pushed back through `removalValue`.
|
|
28780
|
+
* A resolver returning `undefined` SKIPS the entry (the resolver owns any
|
|
28781
|
+
* warn). An empty return means nothing changed and the call should be
|
|
28782
|
+
* skipped. Shared by the LoadBalancer / TargetGroup / Listener update
|
|
28783
|
+
* paths — and all three pass their OWN resolver, because the three APIs
|
|
28784
|
+
* disagree about what resets an attribute:
|
|
28785
|
+
*
|
|
28786
|
+
* - LoadBalancer / Listener: the empty string clears a numeric or
|
|
28787
|
+
* free-form-string override, but a BOOLEAN / ENUM key rejects it and
|
|
28788
|
+
* fails the whole call, so those take a documented default
|
|
28789
|
+
* (`LOAD_BALANCER_ATTRIBUTE_DEFAULTS` / `LISTENER_ATTRIBUTE_DEFAULTS`).
|
|
28790
|
+
* - TargetGroup: the empty string is rejected for EVERY key, so the
|
|
28791
|
+
* documented default is the only reset and an unknown key warns and
|
|
28792
|
+
* retains (`TARGET_GROUP_ATTRIBUTE_DEFAULTS`).
|
|
28793
|
+
*
|
|
28794
|
+
* All three behaviours were live-verified 2026-08-11. `removalValue` is
|
|
28795
|
+
* REQUIRED rather than defaulted: there is no reset value that is correct
|
|
28796
|
+
* for all three APIs, so a caller that forgets to pass one should fail to
|
|
28797
|
+
* compile instead of silently inheriting the empty string that two of the
|
|
28798
|
+
* three reject.
|
|
28799
|
+
*/
|
|
28800
|
+
diffAttributes(newAttrs, oldAttrs, removalValue) {
|
|
28533
28801
|
const newAttrMap = new Map(newAttrs.map((a) => [a.Key, a.Value]));
|
|
28534
28802
|
const oldAttrMap = new Map(oldAttrs.map((a) => [a.Key, a.Value]));
|
|
28535
28803
|
const submitted = [];
|
|
@@ -28537,8 +28805,8 @@ var ELBv2Provider = class {
|
|
|
28537
28805
|
Key: k,
|
|
28538
28806
|
Value: v
|
|
28539
28807
|
});
|
|
28540
|
-
for (const [k] of oldAttrMap) if (!newAttrMap.has(k)) {
|
|
28541
|
-
const value = removalValue(k);
|
|
28808
|
+
for (const [k, currentValue] of oldAttrMap) if (!newAttrMap.has(k)) {
|
|
28809
|
+
const value = removalValue(k, currentValue);
|
|
28542
28810
|
if (value !== void 0) submitted.push({
|
|
28543
28811
|
Key: k,
|
|
28544
28812
|
Value: value
|
|
@@ -28547,6 +28815,40 @@ var ELBv2Provider = class {
|
|
|
28547
28815
|
return submitted;
|
|
28548
28816
|
}
|
|
28549
28817
|
/**
|
|
28818
|
+
* Build the `removalValue` resolver for the LoadBalancer / Listener attribute
|
|
28819
|
+
* arms: reset a removed key to its documented default, or to `''` (which
|
|
28820
|
+
* those two APIs accept as "clear the override") when no default is known.
|
|
28821
|
+
*
|
|
28822
|
+
* **A key already AT its default is SKIPPED, and that is a safety property,
|
|
28823
|
+
* not an optimization.** The previous side is not always a template: `cdkd
|
|
28824
|
+
* drift --revert` calls `update(..., newProperties, outcome.awsProperties)`
|
|
28825
|
+
* (`src/cli/commands/drift.ts`), so `oldAttrs` can be the FULL
|
|
28826
|
+
* `readCurrentState` snapshot — every attribute AWS reports, including the
|
|
28827
|
+
* ~18 the user never templated. Against a state record with no
|
|
28828
|
+
* `observedProperties` the desired side is the template's one or two keys,
|
|
28829
|
+
* so every untemplated key looks REMOVED and would be "reset".
|
|
28830
|
+
*
|
|
28831
|
+
* Writing a documented default there would silently disable deletion
|
|
28832
|
+
* protection, access / connection logs, HTTP/2, WAF fail-open and zonal
|
|
28833
|
+
* shift on a live load balancer. Before the defaults table existed this was
|
|
28834
|
+
* accidentally safe — `''` fails validation, so the whole revert aborted and
|
|
28835
|
+
* changed nothing — so introducing the table without this guard would have
|
|
28836
|
+
* converted a loud refusal into a silent destructive write.
|
|
28837
|
+
*
|
|
28838
|
+
* The skip is exact rather than heuristic: a key the user never templated is
|
|
28839
|
+
* BY DEFINITION sitting at its default, so it is skipped; a key the template
|
|
28840
|
+
* really did set is set to a NON-default value (otherwise templating it
|
|
28841
|
+
* would be a no-op), so its reset still fires. A template that set a key to
|
|
28842
|
+
* exactly its default and then dropped it is skipped too — correctly, since
|
|
28843
|
+
* there is nothing to change.
|
|
28844
|
+
*/
|
|
28845
|
+
attributeRemovalResolver(defaults) {
|
|
28846
|
+
return (key, currentValue) => {
|
|
28847
|
+
const fallback = Object.hasOwn(defaults, key) ? defaults[key] : "";
|
|
28848
|
+
return currentValue === fallback ? void 0 : fallback;
|
|
28849
|
+
};
|
|
28850
|
+
}
|
|
28851
|
+
/**
|
|
28550
28852
|
* Normalize a CFn `Targets` value (an array of `{ Id, Port?,
|
|
28551
28853
|
* AvailabilityZone? }` objects) into the SDK's `TargetDescription[]` shape.
|
|
28552
28854
|
* Entries missing an `Id` are dropped (Id is the only required member);
|
|
@@ -33987,8 +34289,16 @@ var ServiceDiscoveryProvider = class ServiceDiscoveryProvider {
|
|
|
33987
34289
|
this.logger.debug(`Deleting Cloud Map namespace ${logicalId}: ${physicalId}`);
|
|
33988
34290
|
const client = this.getClient();
|
|
33989
34291
|
try {
|
|
33990
|
-
|
|
33991
|
-
|
|
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
|
+
});
|
|
33992
34302
|
this.logger.debug(`Successfully deleted Cloud Map namespace ${logicalId}`);
|
|
33993
34303
|
} catch (error) {
|
|
33994
34304
|
if (error instanceof NamespaceNotFound) {
|
|
@@ -69797,7 +70107,7 @@ function createMigrateCommand() {
|
|
|
69797
70107
|
*/
|
|
69798
70108
|
function buildProgram() {
|
|
69799
70109
|
const program = new Command();
|
|
69800
|
-
program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.280.
|
|
70110
|
+
program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.280.20");
|
|
69801
70111
|
program.hook("preAction", (_thisCommand, actionCommand) => {
|
|
69802
70112
|
const { profile } = actionCommand.optsWithGlobals();
|
|
69803
70113
|
if (profile !== void 0) process.env["AWS_PROFILE"] = profile;
|