@go-to-k/cdkd 0.249.0 → 0.250.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/dist/{asg-provider-CMWe8LlY.js → asg-provider-er3xGYRo.js} +2 -2
- package/dist/{asg-provider-CMWe8LlY.js.map → asg-provider-er3xGYRo.js.map} +1 -1
- package/dist/cli.js +625 -59
- package/dist/cli.js.map +1 -1
- package/dist/{deploy-engine-DqAyGFJu.js → deploy-engine-D-gBbMiZ.js} +32 -4
- package/dist/{deploy-engine-DqAyGFJu.js.map → deploy-engine-D-gBbMiZ.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 ensureAssetStorage, A as WAFv2WebACLProvider, B as LockManager, Bt as LocalInvokeBuildError$1, C as findActionableSilentDrops, Ct as CFN_TEMPLATE_BODY_LIMIT, D as IntrinsicFunctionResolver, Dt as uploadCfnTemplate, E as isTerminationProtectionPropagationError, Et as findLargeInlineResources, F as assertRegionMatch, Ft as setAwsClients, G as stringifyValue, Gt as NestedStackChildDirectDestroyError, H as rebuildClientForBucketRegion, Ht as LocalStartServiceError, I as applyRoleArnIfSet, J as createAssetRedirectResolver, Jt as ResourceTimeoutError, K as WorkGraph, Kt as PartialFailureError, L as DiffCalculator, Lt as CdkdError, M as matchesCdkPath, Mt as AwsClients, N as normalizeAwsTagsToCfn, Nt as getAwsClients, O as cfnRefValueFromPhysicalId, Ot as expectedOwnerParam, P as resolveExplicitPhysicalId, Pt as resetAwsClients, Q as BOOTSTRAP_MARKER_PREFIX, R as DagBuilder, S as ProviderRegistry, St as warnDeprecatedNoPrefixCliFlag, T as disableInstanceApiTermination, Tt as MIGRATE_TMP_PREFIX, U as shouldRetainResource, V as S3StateBackend, Vt as LocalMigrateError, W as AssetPublisher, Wt as MissingCdkCliError, X as rewriteTemplateAssetReferences, Xt as StackHasActiveImportsError, Y as loadPublishableAssetManifest, Yt as ResourceUpdateNotSupportedError, Z as AssetModeResolver, Zt as StackTerminationProtectionError, _ as green, _t as resolveCaptureObservedState, a as withRetry, at as formatDockerLoginError, b as IAMRoleProvider, bt as resolveStateBucketWithDefaultAndSource, c as computeImplicitDeleteEdges, ct as runDockerStreaming, d as isStatefulRecreateTargetSync, dt as Synthesizer, et as getBootstrapMarkerKey, f as renderStatefulReason, ft as synthesisStatusMessage, g as gray, gt as resolveAutoAssetStorage, h as cyan, ht as resolveApp, i as withResourceDeadline, it as buildDockerImage, j as CDK_PATH_TAG, jt as resolveBucketRegion, k as refStateLookupFromResource, kt as AssemblyReader, l as extractDeploymentEventError, lt as AssetManifestLoader, m as bold, mt as getLegacyStateBucketName, n as DEFAULT_RESOURCE_WARN_AFTER_MS, nn as normalizeAwsError, nt as validateAssetBucketName, o as isRetryableTransientError, ot as getDockerCmd, p as formatResourceLine, pt as getDefaultStateBucketName, q as buildAssetRedirectMap, qt as ProvisioningError, r as DeployEngine, rn as withErrorHandling, rt as validateContainerRepoName, s as IMPLICIT_DELETE_DEPENDENCIES, st as runDockerForeground, t as DEFAULT_RESOURCE_TIMEOUT_MS, tt as parseBootstrapMarker, u as MULTI_REGION_RECREATE_BLOCKED_TYPES, ut as getDockerImageBySourceHash, v as red, vt as resolveSkipPrefix, w as CloudControlProvider, wt as CFN_TEMPLATE_URL_LIMIT, x as collectInlinePolicyNamesManagedBySiblings, xt as resolveUseCdkBootstrapAssets, y as yellow, yt as resolveStateBucketWithDefault, z as TemplateParser } from "./deploy-engine-
|
|
2
|
+
import { $ as ensureAssetStorage, A as WAFv2WebACLProvider, B as LockManager, Bt as LocalInvokeBuildError$1, C as findActionableSilentDrops, Ct as CFN_TEMPLATE_BODY_LIMIT, D as IntrinsicFunctionResolver, Dt as uploadCfnTemplate, E as isTerminationProtectionPropagationError, Et as findLargeInlineResources, F as assertRegionMatch, Ft as setAwsClients, G as stringifyValue, Gt as NestedStackChildDirectDestroyError, H as rebuildClientForBucketRegion, Ht as LocalStartServiceError, I as applyRoleArnIfSet, J as createAssetRedirectResolver, Jt as ResourceTimeoutError, K as WorkGraph, Kt as PartialFailureError, L as DiffCalculator, Lt as CdkdError, M as matchesCdkPath, Mt as AwsClients, N as normalizeAwsTagsToCfn, Nt as getAwsClients, O as cfnRefValueFromPhysicalId, Ot as expectedOwnerParam, P as resolveExplicitPhysicalId, Pt as resetAwsClients, Q as BOOTSTRAP_MARKER_PREFIX, R as DagBuilder, S as ProviderRegistry, St as warnDeprecatedNoPrefixCliFlag, T as disableInstanceApiTermination, Tt as MIGRATE_TMP_PREFIX, U as shouldRetainResource, V as S3StateBackend, Vt as LocalMigrateError, W as AssetPublisher, Wt as MissingCdkCliError, X as rewriteTemplateAssetReferences, Xt as StackHasActiveImportsError, Y as loadPublishableAssetManifest, Yt as ResourceUpdateNotSupportedError, Z as AssetModeResolver, Zt as StackTerminationProtectionError, _ as green, _t as resolveCaptureObservedState, a as withRetry, at as formatDockerLoginError, b as IAMRoleProvider, bt as resolveStateBucketWithDefaultAndSource, c as computeImplicitDeleteEdges, ct as runDockerStreaming, d as isStatefulRecreateTargetSync, dt as Synthesizer, et as getBootstrapMarkerKey, f as renderStatefulReason, ft as synthesisStatusMessage, g as gray, gt as resolveAutoAssetStorage, h as cyan, ht as resolveApp, i as withResourceDeadline, it as buildDockerImage, j as CDK_PATH_TAG, jt as resolveBucketRegion, k as refStateLookupFromResource, kt as AssemblyReader, l as extractDeploymentEventError, lt as AssetManifestLoader, m as bold, mt as getLegacyStateBucketName, n as DEFAULT_RESOURCE_WARN_AFTER_MS, nn as normalizeAwsError, nt as validateAssetBucketName, o as isRetryableTransientError, ot as getDockerCmd, p as formatResourceLine, pt as getDefaultStateBucketName, q as buildAssetRedirectMap, qt as ProvisioningError, r as DeployEngine, rn as withErrorHandling, rt as validateContainerRepoName, s as IMPLICIT_DELETE_DEPENDENCIES, st as runDockerForeground, t as DEFAULT_RESOURCE_TIMEOUT_MS, tt as parseBootstrapMarker, u as MULTI_REGION_RECREATE_BLOCKED_TYPES, ut as getDockerImageBySourceHash, v as red, vt as resolveSkipPrefix, w as CloudControlProvider, wt as CFN_TEMPLATE_URL_LIMIT, x as collectInlinePolicyNamesManagedBySiblings, xt as resolveUseCdkBootstrapAssets, y as yellow, yt as resolveStateBucketWithDefault, z as TemplateParser } from "./deploy-engine-D-gBbMiZ.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-er3xGYRo.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, DeleteBucketIntelligentTieringConfigurationCommand, DeleteBucketInventoryConfigurationCommand, DeleteBucketLifecycleCommand, DeleteBucketMetricsConfigurationCommand, DeleteBucketPolicyCommand, DeleteBucketReplicationCommand, DeleteBucketTaggingCommand, DeleteBucketWebsiteCommand, DeleteObjectsCommand, GetBucketAccelerateConfigurationCommand, GetBucketCorsCommand, GetBucketEncryptionCommand, GetBucketLifecycleConfigurationCommand, GetBucketLocationCommand, GetBucketLoggingCommand, GetBucketNotificationConfigurationCommand, GetBucketPolicyCommand, GetBucketReplicationCommand, GetBucketTaggingCommand, GetBucketVersioningCommand, GetBucketWebsiteCommand, GetObjectCommand, GetObjectLockConfigurationCommand, GetPublicAccessBlockCommand, HeadBucketCommand, ListBucketAnalyticsConfigurationsCommand, ListBucketIntelligentTieringConfigurationsCommand, ListBucketInventoryConfigurationsCommand, ListBucketMetricsConfigurationsCommand, ListBucketsCommand, ListDirectoryBucketsCommand, 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";
|
|
@@ -57,7 +57,7 @@ import { AddTagsToStreamCommand, CreateStreamCommand, DecreaseStreamRetentionPer
|
|
|
57
57
|
import { CreateScheduleCommand, DeleteScheduleCommand, GetScheduleCommand, ResourceNotFoundException as ResourceNotFoundException$9, SchedulerClient, UpdateScheduleCommand } from "@aws-sdk/client-scheduler";
|
|
58
58
|
import { AccessPointNotFound, CreateAccessPointCommand, CreateFileSystemCommand, CreateMountTargetCommand, DeleteAccessPointCommand, DeleteFileSystemCommand, DeleteMountTargetCommand, DescribeAccessPointsCommand, DescribeBackupPolicyCommand, DescribeFileSystemPolicyCommand, DescribeFileSystemsCommand, DescribeLifecycleConfigurationCommand, DescribeMountTargetSecurityGroupsCommand, DescribeMountTargetsCommand, EFSClient, FileSystemNotFound, ModifyMountTargetSecurityGroupsCommand, MountTargetNotFound, PutBackupPolicyCommand, PutFileSystemPolicyCommand, PutLifecycleConfigurationCommand, UpdateFileSystemCommand, UpdateFileSystemProtectionCommand } from "@aws-sdk/client-efs";
|
|
59
59
|
import { CreateFileSystemCommand as CreateFileSystemCommand$1, CreateFileSystemFromBackupCommand, DeleteFileSystemCommand as DeleteFileSystemCommand$1, DescribeFileSystemsCommand as DescribeFileSystemsCommand$1, FSxClient, FileSystemNotFound as FileSystemNotFound$1, TagResourceCommand as TagResourceCommand$18, UntagResourceCommand as UntagResourceCommand$18, UpdateFileSystemCommand as UpdateFileSystemCommand$1 } from "@aws-sdk/client-fsx";
|
|
60
|
-
import { AddTagsCommand as AddTagsCommand$1, DescribeClusterCommand, EMRClient, InvalidRequestException, ListClustersCommand as ListClustersCommand$1, ListInstanceFleetsCommand, ListInstanceGroupsCommand, ModifyClusterCommand, PutAutoTerminationPolicyCommand, PutManagedScalingPolicyCommand, RemoveAutoTerminationPolicyCommand, RemoveManagedScalingPolicyCommand, RemoveTagsCommand as RemoveTagsCommand$1, RunJobFlowCommand, SetTerminationProtectionCommand, SetVisibleToAllUsersCommand, TerminateJobFlowsCommand } from "@aws-sdk/client-emr";
|
|
60
|
+
import { AddInstanceFleetCommand, AddInstanceGroupsCommand, AddTagsCommand as AddTagsCommand$1, DescribeClusterCommand, EMRClient, InvalidRequestException, ListClustersCommand as ListClustersCommand$1, ListInstanceFleetsCommand, ListInstanceGroupsCommand, ModifyClusterCommand, ModifyInstanceFleetCommand, ModifyInstanceGroupsCommand, PutAutoScalingPolicyCommand, PutAutoTerminationPolicyCommand, PutManagedScalingPolicyCommand, RemoveAutoScalingPolicyCommand, RemoveAutoTerminationPolicyCommand, RemoveManagedScalingPolicyCommand, RemoveTagsCommand as RemoveTagsCommand$1, RunJobFlowCommand, SetTerminationProtectionCommand, SetVisibleToAllUsersCommand, TerminateJobFlowsCommand } from "@aws-sdk/client-emr";
|
|
61
61
|
import { CreateDeliveryStreamCommand, DeleteDeliveryStreamCommand, DescribeDeliveryStreamCommand, FirehoseClient, ListDeliveryStreamsCommand, ListTagsForDeliveryStreamCommand, ResourceNotFoundException as ResourceNotFoundException$10, TagDeliveryStreamCommand, UntagDeliveryStreamCommand, UpdateDestinationCommand } from "@aws-sdk/client-firehose";
|
|
62
62
|
import { AddTagsCommand as AddTagsCommand$2, CloudTrailClient, CreateTrailCommand, DeleteTrailCommand, GetEventSelectorsCommand, GetInsightSelectorsCommand, GetTrailCommand, GetTrailStatusCommand, ListTagsCommand as ListTagsCommand$1, ListTrailsCommand, PutEventSelectorsCommand, PutInsightSelectorsCommand, RemoveTagsCommand as RemoveTagsCommand$2, StartLoggingCommand, StopLoggingCommand, TrailNotFoundException, UpdateTrailCommand } from "@aws-sdk/client-cloudtrail";
|
|
63
63
|
import { BatchGetProjectsCommand, CodeBuildClient, CreateProjectCommand, DeleteProjectCommand, ListProjectsCommand, ResourceNotFoundException as ResourceNotFoundException$11, UpdateProjectCommand } from "@aws-sdk/client-codebuild";
|
|
@@ -1888,7 +1888,7 @@ const FLUSH_INTERVAL_MS = 2e3;
|
|
|
1888
1888
|
const FLUSH_EVENT_THRESHOLD = 50;
|
|
1889
1889
|
/** Build-time cdkd version, with a dev fallback for non-built contexts. */
|
|
1890
1890
|
function getCdkdVersion() {
|
|
1891
|
-
return "0.
|
|
1891
|
+
return "0.250.0";
|
|
1892
1892
|
}
|
|
1893
1893
|
/**
|
|
1894
1894
|
* Generate a time-sortable unique run id, e.g.
|
|
@@ -34410,8 +34410,8 @@ var EFSProvider = class {
|
|
|
34410
34410
|
* storage-capacity growth and deletes can take substantially longer —
|
|
34411
34411
|
* mirror the Custom Resource provider's 1-hour ceiling.
|
|
34412
34412
|
*/
|
|
34413
|
-
const DEFAULT_MAX_WAIT_MS$
|
|
34414
|
-
const DEFAULT_POLL_INTERVAL_MS$
|
|
34413
|
+
const DEFAULT_MAX_WAIT_MS$3 = 3600 * 1e3;
|
|
34414
|
+
const DEFAULT_POLL_INTERVAL_MS$3 = 15e3;
|
|
34415
34415
|
/**
|
|
34416
34416
|
* Lustre sub-properties that `UpdateFileSystem` accepts (the mutable
|
|
34417
34417
|
* subset of the CFn `LustreConfiguration` block). Everything else in the
|
|
@@ -34530,7 +34530,7 @@ const TOP_LEVEL_IMMUTABLE_PROPS = [
|
|
|
34530
34530
|
"KmsKeyId",
|
|
34531
34531
|
"BackupId"
|
|
34532
34532
|
];
|
|
34533
|
-
const toNumber$
|
|
34533
|
+
const toNumber$3 = (v) => v === void 0 ? void 0 : Number(v);
|
|
34534
34534
|
const toBoolean$1 = (v) => {
|
|
34535
34535
|
if (v === void 0) return void 0;
|
|
34536
34536
|
if (typeof v === "string") return v === "true";
|
|
@@ -34581,8 +34581,8 @@ var FSxFileSystemProvider = class {
|
|
|
34581
34581
|
pollIntervalMs;
|
|
34582
34582
|
maxWaitMs;
|
|
34583
34583
|
constructor(options) {
|
|
34584
|
-
this.pollIntervalMs = options?.pollIntervalMs ?? DEFAULT_POLL_INTERVAL_MS$
|
|
34585
|
-
this.maxWaitMs = options?.maxWaitMs ?? DEFAULT_MAX_WAIT_MS$
|
|
34584
|
+
this.pollIntervalMs = options?.pollIntervalMs ?? DEFAULT_POLL_INTERVAL_MS$3;
|
|
34585
|
+
this.maxWaitMs = options?.maxWaitMs ?? DEFAULT_MAX_WAIT_MS$3;
|
|
34586
34586
|
}
|
|
34587
34587
|
handledProperties = /* @__PURE__ */ new Map([["AWS::FSx::FileSystem", /* @__PURE__ */ new Set([
|
|
34588
34588
|
"BackupId",
|
|
@@ -34635,7 +34635,7 @@ var FSxFileSystemProvider = class {
|
|
|
34635
34635
|
SecurityGroupIds: properties["SecurityGroupIds"],
|
|
34636
34636
|
KmsKeyId: properties["KmsKeyId"],
|
|
34637
34637
|
StorageType: properties["StorageType"],
|
|
34638
|
-
StorageCapacity: toNumber$
|
|
34638
|
+
StorageCapacity: toNumber$3(properties["StorageCapacity"]),
|
|
34639
34639
|
FileSystemTypeVersion: properties["FileSystemTypeVersion"],
|
|
34640
34640
|
NetworkType: properties["NetworkType"],
|
|
34641
34641
|
LustreConfiguration: this.toCreateLustreConfiguration(properties["LustreConfiguration"]),
|
|
@@ -34691,24 +34691,24 @@ var FSxFileSystemProvider = class {
|
|
|
34691
34691
|
WeeklyMaintenanceStartTime: config["WeeklyMaintenanceStartTime"],
|
|
34692
34692
|
ImportPath: config["ImportPath"],
|
|
34693
34693
|
ExportPath: config["ExportPath"],
|
|
34694
|
-
ImportedFileChunkSize: toNumber$
|
|
34694
|
+
ImportedFileChunkSize: toNumber$3(config["ImportedFileChunkSize"]),
|
|
34695
34695
|
DeploymentType: config["DeploymentType"],
|
|
34696
34696
|
AutoImportPolicy: config["AutoImportPolicy"],
|
|
34697
|
-
PerUnitStorageThroughput: toNumber$
|
|
34697
|
+
PerUnitStorageThroughput: toNumber$3(config["PerUnitStorageThroughput"]),
|
|
34698
34698
|
DailyAutomaticBackupStartTime: config["DailyAutomaticBackupStartTime"],
|
|
34699
|
-
AutomaticBackupRetentionDays: toNumber$
|
|
34699
|
+
AutomaticBackupRetentionDays: toNumber$3(config["AutomaticBackupRetentionDays"]),
|
|
34700
34700
|
CopyTagsToBackups: toBoolean$1(config["CopyTagsToBackups"]),
|
|
34701
34701
|
DriveCacheType: config["DriveCacheType"],
|
|
34702
34702
|
DataCompressionType: config["DataCompressionType"],
|
|
34703
34703
|
EfaEnabled: toBoolean$1(config["EfaEnabled"]),
|
|
34704
|
-
ThroughputCapacity: toNumber$
|
|
34704
|
+
ThroughputCapacity: toNumber$3(config["ThroughputCapacity"]),
|
|
34705
34705
|
MetadataConfiguration: metadata ? {
|
|
34706
34706
|
Mode: metadata["Mode"],
|
|
34707
|
-
Iops: toNumber$
|
|
34707
|
+
Iops: toNumber$3(metadata["Iops"])
|
|
34708
34708
|
} : void 0,
|
|
34709
34709
|
DataReadCacheConfiguration: readCache ? {
|
|
34710
34710
|
SizingMode: readCache["SizingMode"],
|
|
34711
|
-
SizeGiB: toNumber$
|
|
34711
|
+
SizeGiB: toNumber$3(readCache["SizeGiB"])
|
|
34712
34712
|
} : void 0
|
|
34713
34713
|
};
|
|
34714
34714
|
}
|
|
@@ -34720,10 +34720,10 @@ var FSxFileSystemProvider = class {
|
|
|
34720
34720
|
SelfManagedActiveDirectoryConfiguration: this.toSelfManagedAdConfiguration(config["SelfManagedActiveDirectoryConfiguration"]),
|
|
34721
34721
|
DeploymentType: config["DeploymentType"],
|
|
34722
34722
|
PreferredSubnetId: config["PreferredSubnetId"],
|
|
34723
|
-
ThroughputCapacity: toNumber$
|
|
34723
|
+
ThroughputCapacity: toNumber$3(config["ThroughputCapacity"]),
|
|
34724
34724
|
WeeklyMaintenanceStartTime: config["WeeklyMaintenanceStartTime"],
|
|
34725
34725
|
DailyAutomaticBackupStartTime: config["DailyAutomaticBackupStartTime"],
|
|
34726
|
-
AutomaticBackupRetentionDays: toNumber$
|
|
34726
|
+
AutomaticBackupRetentionDays: toNumber$3(config["AutomaticBackupRetentionDays"]),
|
|
34727
34727
|
CopyTagsToBackups: toBoolean$1(config["CopyTagsToBackups"]),
|
|
34728
34728
|
Aliases: config["Aliases"],
|
|
34729
34729
|
AuditLogConfiguration: this.toWindowsAuditLogConfiguration(config["AuditLogConfiguration"]),
|
|
@@ -34735,7 +34735,7 @@ var FSxFileSystemProvider = class {
|
|
|
34735
34735
|
toCreateOntapConfiguration(config) {
|
|
34736
34736
|
if (!config) return void 0;
|
|
34737
34737
|
return {
|
|
34738
|
-
AutomaticBackupRetentionDays: toNumber$
|
|
34738
|
+
AutomaticBackupRetentionDays: toNumber$3(config["AutomaticBackupRetentionDays"]),
|
|
34739
34739
|
DailyAutomaticBackupStartTime: config["DailyAutomaticBackupStartTime"],
|
|
34740
34740
|
DeploymentType: config["DeploymentType"],
|
|
34741
34741
|
EndpointIpAddressRange: config["EndpointIpAddressRange"],
|
|
@@ -34743,10 +34743,10 @@ var FSxFileSystemProvider = class {
|
|
|
34743
34743
|
DiskIopsConfiguration: this.toDiskIopsConfiguration(config["DiskIopsConfiguration"]),
|
|
34744
34744
|
PreferredSubnetId: config["PreferredSubnetId"],
|
|
34745
34745
|
RouteTableIds: config["RouteTableIds"],
|
|
34746
|
-
ThroughputCapacity: toNumber$
|
|
34746
|
+
ThroughputCapacity: toNumber$3(config["ThroughputCapacity"]),
|
|
34747
34747
|
WeeklyMaintenanceStartTime: config["WeeklyMaintenanceStartTime"],
|
|
34748
|
-
HAPairs: toNumber$
|
|
34749
|
-
ThroughputCapacityPerHAPair: toNumber$
|
|
34748
|
+
HAPairs: toNumber$3(config["HAPairs"]),
|
|
34749
|
+
ThroughputCapacityPerHAPair: toNumber$3(config["ThroughputCapacityPerHAPair"]),
|
|
34750
34750
|
EndpointIpv6AddressRange: config["EndpointIpv6AddressRange"]
|
|
34751
34751
|
};
|
|
34752
34752
|
}
|
|
@@ -34754,12 +34754,12 @@ var FSxFileSystemProvider = class {
|
|
|
34754
34754
|
toCreateOpenZFSConfiguration(config) {
|
|
34755
34755
|
if (!config) return void 0;
|
|
34756
34756
|
return {
|
|
34757
|
-
AutomaticBackupRetentionDays: toNumber$
|
|
34757
|
+
AutomaticBackupRetentionDays: toNumber$3(config["AutomaticBackupRetentionDays"]),
|
|
34758
34758
|
CopyTagsToBackups: toBoolean$1(config["CopyTagsToBackups"]),
|
|
34759
34759
|
CopyTagsToVolumes: toBoolean$1(config["CopyTagsToVolumes"]),
|
|
34760
34760
|
DailyAutomaticBackupStartTime: config["DailyAutomaticBackupStartTime"],
|
|
34761
34761
|
DeploymentType: config["DeploymentType"],
|
|
34762
|
-
ThroughputCapacity: toNumber$
|
|
34762
|
+
ThroughputCapacity: toNumber$3(config["ThroughputCapacity"]),
|
|
34763
34763
|
WeeklyMaintenanceStartTime: config["WeeklyMaintenanceStartTime"],
|
|
34764
34764
|
DiskIopsConfiguration: this.toDiskIopsConfiguration(config["DiskIopsConfiguration"]),
|
|
34765
34765
|
RootVolumeConfiguration: this.toOpenZFSRootVolumeConfiguration(config["RootVolumeConfiguration"]),
|
|
@@ -34774,7 +34774,7 @@ var FSxFileSystemProvider = class {
|
|
|
34774
34774
|
if (!config) return void 0;
|
|
34775
34775
|
return {
|
|
34776
34776
|
Mode: config["Mode"],
|
|
34777
|
-
Iops: toNumber$
|
|
34777
|
+
Iops: toNumber$3(config["Iops"])
|
|
34778
34778
|
};
|
|
34779
34779
|
}
|
|
34780
34780
|
toSelfManagedAdConfiguration(config) {
|
|
@@ -34821,7 +34821,7 @@ var FSxFileSystemProvider = class {
|
|
|
34821
34821
|
const nfsExports = config["NfsExports"];
|
|
34822
34822
|
const quotas = config["UserAndGroupQuotas"];
|
|
34823
34823
|
return {
|
|
34824
|
-
RecordSizeKiB: toNumber$
|
|
34824
|
+
RecordSizeKiB: toNumber$3(config["RecordSizeKiB"]),
|
|
34825
34825
|
DataCompressionType: config["DataCompressionType"],
|
|
34826
34826
|
NfsExports: nfsExports?.map((exp) => ({ ClientConfigurations: (exp["ClientConfigurations"] ?? []).map((cc) => ({
|
|
34827
34827
|
Clients: cc["Clients"],
|
|
@@ -34829,8 +34829,8 @@ var FSxFileSystemProvider = class {
|
|
|
34829
34829
|
})) })),
|
|
34830
34830
|
UserAndGroupQuotas: quotas?.map((q) => ({
|
|
34831
34831
|
Type: q["Type"],
|
|
34832
|
-
Id: toNumber$
|
|
34833
|
-
StorageCapacityQuotaGiB: toNumber$
|
|
34832
|
+
Id: toNumber$3(q["Id"]),
|
|
34833
|
+
StorageCapacityQuotaGiB: toNumber$3(q["StorageCapacityQuotaGiB"])
|
|
34834
34834
|
})),
|
|
34835
34835
|
CopyTagsToSnapshots: toBoolean$1(config["CopyTagsToSnapshots"]),
|
|
34836
34836
|
ReadOnly: toBoolean$1(config["ReadOnly"])
|
|
@@ -34840,7 +34840,7 @@ var FSxFileSystemProvider = class {
|
|
|
34840
34840
|
if (!config) return void 0;
|
|
34841
34841
|
return {
|
|
34842
34842
|
SizingMode: config["SizingMode"],
|
|
34843
|
-
SizeGiB: toNumber$
|
|
34843
|
+
SizeGiB: toNumber$3(config["SizeGiB"])
|
|
34844
34844
|
};
|
|
34845
34845
|
}
|
|
34846
34846
|
async update(logicalId, physicalId, resourceType, properties, previousProperties) {
|
|
@@ -34875,7 +34875,7 @@ var FSxFileSystemProvider = class {
|
|
|
34875
34875
|
const callTimeMs = Date.now();
|
|
34876
34876
|
const respPendingActions = ((await this.getClient().send(new UpdateFileSystemCommand$1({
|
|
34877
34877
|
FileSystemId: physicalId,
|
|
34878
|
-
...storageCapacityChanged && { StorageCapacity: toNumber$
|
|
34878
|
+
...storageCapacityChanged && { StorageCapacity: toNumber$3(properties["StorageCapacity"]) },
|
|
34879
34879
|
...storageTypeChanged && { StorageType: properties["StorageType"] },
|
|
34880
34880
|
...typeVersionChanged && { FileSystemTypeVersion: properties["FileSystemTypeVersion"] },
|
|
34881
34881
|
...networkTypeChanged && { NetworkType: properties["NetworkType"] },
|
|
@@ -34944,7 +34944,7 @@ var FSxFileSystemProvider = class {
|
|
|
34944
34944
|
case "AutomaticBackupRetentionDays":
|
|
34945
34945
|
case "PerUnitStorageThroughput":
|
|
34946
34946
|
case "ThroughputCapacity":
|
|
34947
|
-
diff[key] = toNumber$
|
|
34947
|
+
diff[key] = toNumber$3(next);
|
|
34948
34948
|
break;
|
|
34949
34949
|
case "AutoImportPolicy":
|
|
34950
34950
|
case "DataCompressionType":
|
|
@@ -34954,7 +34954,7 @@ var FSxFileSystemProvider = class {
|
|
|
34954
34954
|
const metadata = next;
|
|
34955
34955
|
out.MetadataConfiguration = metadata ? {
|
|
34956
34956
|
Mode: metadata["Mode"],
|
|
34957
|
-
Iops: toNumber$
|
|
34957
|
+
Iops: toNumber$3(metadata["Iops"])
|
|
34958
34958
|
} : void 0;
|
|
34959
34959
|
break;
|
|
34960
34960
|
}
|
|
@@ -34962,7 +34962,7 @@ var FSxFileSystemProvider = class {
|
|
|
34962
34962
|
const readCache = next;
|
|
34963
34963
|
out.DataReadCacheConfiguration = readCache ? {
|
|
34964
34964
|
SizingMode: readCache["SizingMode"],
|
|
34965
|
-
SizeGiB: toNumber$
|
|
34965
|
+
SizeGiB: toNumber$3(readCache["SizeGiB"])
|
|
34966
34966
|
} : void 0;
|
|
34967
34967
|
break;
|
|
34968
34968
|
}
|
|
@@ -34978,7 +34978,7 @@ var FSxFileSystemProvider = class {
|
|
|
34978
34978
|
break;
|
|
34979
34979
|
case "AutomaticBackupRetentionDays":
|
|
34980
34980
|
case "ThroughputCapacity":
|
|
34981
|
-
diff[key] = toNumber$
|
|
34981
|
+
diff[key] = toNumber$3(next);
|
|
34982
34982
|
break;
|
|
34983
34983
|
case "SelfManagedActiveDirectoryConfiguration":
|
|
34984
34984
|
out.SelfManagedActiveDirectoryConfiguration = this.toSelfManagedAdConfigurationUpdates(next);
|
|
@@ -35008,7 +35008,7 @@ var FSxFileSystemProvider = class {
|
|
|
35008
35008
|
case "ThroughputCapacity":
|
|
35009
35009
|
case "ThroughputCapacityPerHAPair":
|
|
35010
35010
|
case "HAPairs":
|
|
35011
|
-
diff[key] = toNumber$
|
|
35011
|
+
diff[key] = toNumber$3(next);
|
|
35012
35012
|
break;
|
|
35013
35013
|
case "DiskIopsConfiguration":
|
|
35014
35014
|
out.DiskIopsConfiguration = this.toDiskIopsConfiguration(next);
|
|
@@ -35036,7 +35036,7 @@ var FSxFileSystemProvider = class {
|
|
|
35036
35036
|
break;
|
|
35037
35037
|
case "AutomaticBackupRetentionDays":
|
|
35038
35038
|
case "ThroughputCapacity":
|
|
35039
|
-
diff[key] = toNumber$
|
|
35039
|
+
diff[key] = toNumber$3(next);
|
|
35040
35040
|
break;
|
|
35041
35041
|
case "DiskIopsConfiguration":
|
|
35042
35042
|
out.DiskIopsConfiguration = this.toDiskIopsConfiguration(next);
|
|
@@ -35353,8 +35353,8 @@ var FSxFileSystemProvider = class {
|
|
|
35353
35353
|
* FSx providers' 1-hour ceiling so the slowest realistic create/terminate
|
|
35354
35354
|
* still fits inside the per-resource deadline.
|
|
35355
35355
|
*/
|
|
35356
|
-
const DEFAULT_MAX_WAIT_MS = 3600 * 1e3;
|
|
35357
|
-
const DEFAULT_POLL_INTERVAL_MS = 15e3;
|
|
35356
|
+
const DEFAULT_MAX_WAIT_MS$2 = 3600 * 1e3;
|
|
35357
|
+
const DEFAULT_POLL_INTERVAL_MS$2 = 15e3;
|
|
35358
35358
|
/** Cluster states that mean "create succeeded, the cluster is up". */
|
|
35359
35359
|
const CREATE_READY_STATES = /* @__PURE__ */ new Set(["WAITING", "RUNNING"]);
|
|
35360
35360
|
/**
|
|
@@ -35388,7 +35388,7 @@ const MUTABLE_TOP_LEVEL_PROPS = /* @__PURE__ */ new Set([
|
|
|
35388
35388
|
"ManagedScalingPolicy",
|
|
35389
35389
|
"AutoTerminationPolicy"
|
|
35390
35390
|
]);
|
|
35391
|
-
const toNumber = (v) => {
|
|
35391
|
+
const toNumber$2 = (v) => {
|
|
35392
35392
|
if (v === void 0) return void 0;
|
|
35393
35393
|
const n = Number(v);
|
|
35394
35394
|
return Number.isNaN(n) ? void 0 : n;
|
|
@@ -35398,7 +35398,7 @@ const toBoolean = (v) => {
|
|
|
35398
35398
|
if (typeof v === "string") return v === "true";
|
|
35399
35399
|
return Boolean(v);
|
|
35400
35400
|
};
|
|
35401
|
-
const jsonEqual = (a, b) => JSON.stringify(a) === JSON.stringify(b);
|
|
35401
|
+
const jsonEqual$2 = (a, b) => JSON.stringify(a) === JSON.stringify(b);
|
|
35402
35402
|
/**
|
|
35403
35403
|
* SDK Provider for `AWS::EMR::Cluster` (EMR on EC2).
|
|
35404
35404
|
*
|
|
@@ -35444,8 +35444,8 @@ var EMRClusterProvider = class {
|
|
|
35444
35444
|
pollIntervalMs;
|
|
35445
35445
|
maxWaitMs;
|
|
35446
35446
|
constructor(options) {
|
|
35447
|
-
this.pollIntervalMs = options?.pollIntervalMs ?? DEFAULT_POLL_INTERVAL_MS;
|
|
35448
|
-
this.maxWaitMs = options?.maxWaitMs ?? DEFAULT_MAX_WAIT_MS;
|
|
35447
|
+
this.pollIntervalMs = options?.pollIntervalMs ?? DEFAULT_POLL_INTERVAL_MS$2;
|
|
35448
|
+
this.maxWaitMs = options?.maxWaitMs ?? DEFAULT_MAX_WAIT_MS$2;
|
|
35449
35449
|
}
|
|
35450
35450
|
handledProperties = /* @__PURE__ */ new Map([["AWS::EMR::Cluster", /* @__PURE__ */ new Set([
|
|
35451
35451
|
"AdditionalInfo",
|
|
@@ -35517,10 +35517,10 @@ var EMRClusterProvider = class {
|
|
|
35517
35517
|
CustomAmiId: properties["CustomAmiId"],
|
|
35518
35518
|
OSReleaseLabel: properties["OSReleaseLabel"],
|
|
35519
35519
|
SecurityConfiguration: properties["SecurityConfiguration"],
|
|
35520
|
-
EbsRootVolumeSize: toNumber(properties["EbsRootVolumeSize"]),
|
|
35521
|
-
EbsRootVolumeIops: toNumber(properties["EbsRootVolumeIops"]),
|
|
35522
|
-
EbsRootVolumeThroughput: toNumber(properties["EbsRootVolumeThroughput"]),
|
|
35523
|
-
StepConcurrencyLevel: toNumber(properties["StepConcurrencyLevel"]),
|
|
35520
|
+
EbsRootVolumeSize: toNumber$2(properties["EbsRootVolumeSize"]),
|
|
35521
|
+
EbsRootVolumeIops: toNumber$2(properties["EbsRootVolumeIops"]),
|
|
35522
|
+
EbsRootVolumeThroughput: toNumber$2(properties["EbsRootVolumeThroughput"]),
|
|
35523
|
+
StepConcurrencyLevel: toNumber$2(properties["StepConcurrencyLevel"]),
|
|
35524
35524
|
VisibleToAllUsers: toBoolean(properties["VisibleToAllUsers"]),
|
|
35525
35525
|
Applications: properties["Applications"],
|
|
35526
35526
|
Configurations: properties["Configurations"],
|
|
@@ -35609,7 +35609,7 @@ var EMRClusterProvider = class {
|
|
|
35609
35609
|
return {
|
|
35610
35610
|
InstanceRole: role,
|
|
35611
35611
|
InstanceType: raw["InstanceType"],
|
|
35612
|
-
InstanceCount: toNumber(raw["InstanceCount"]),
|
|
35612
|
+
InstanceCount: toNumber$2(raw["InstanceCount"]),
|
|
35613
35613
|
Name: raw["Name"],
|
|
35614
35614
|
Market: raw["Market"],
|
|
35615
35615
|
BidPrice: raw["BidPrice"],
|
|
@@ -35623,8 +35623,8 @@ var EMRClusterProvider = class {
|
|
|
35623
35623
|
return {
|
|
35624
35624
|
InstanceFleetType: type,
|
|
35625
35625
|
Name: raw["Name"],
|
|
35626
|
-
TargetOnDemandCapacity: toNumber(raw["TargetOnDemandCapacity"]),
|
|
35627
|
-
TargetSpotCapacity: toNumber(raw["TargetSpotCapacity"]),
|
|
35626
|
+
TargetOnDemandCapacity: toNumber$2(raw["TargetOnDemandCapacity"]),
|
|
35627
|
+
TargetSpotCapacity: toNumber$2(raw["TargetSpotCapacity"]),
|
|
35628
35628
|
InstanceTypeConfigs: raw["InstanceTypeConfigs"],
|
|
35629
35629
|
LaunchSpecifications: raw["LaunchSpecifications"],
|
|
35630
35630
|
ResizeSpecifications: raw["ResizeSpecifications"]
|
|
@@ -35637,28 +35637,28 @@ var EMRClusterProvider = class {
|
|
|
35637
35637
|
return {
|
|
35638
35638
|
ComputeLimits: {
|
|
35639
35639
|
UnitType: limits["UnitType"],
|
|
35640
|
-
MinimumCapacityUnits: toNumber(limits["MinimumCapacityUnits"]),
|
|
35641
|
-
MaximumCapacityUnits: toNumber(limits["MaximumCapacityUnits"]),
|
|
35642
|
-
MaximumOnDemandCapacityUnits: toNumber(limits["MaximumOnDemandCapacityUnits"]),
|
|
35643
|
-
MaximumCoreCapacityUnits: toNumber(limits["MaximumCoreCapacityUnits"])
|
|
35640
|
+
MinimumCapacityUnits: toNumber$2(limits["MinimumCapacityUnits"]),
|
|
35641
|
+
MaximumCapacityUnits: toNumber$2(limits["MaximumCapacityUnits"]),
|
|
35642
|
+
MaximumOnDemandCapacityUnits: toNumber$2(limits["MaximumOnDemandCapacityUnits"]),
|
|
35643
|
+
MaximumCoreCapacityUnits: toNumber$2(limits["MaximumCoreCapacityUnits"])
|
|
35644
35644
|
},
|
|
35645
|
-
UtilizationPerformanceIndex: toNumber(config["UtilizationPerformanceIndex"]),
|
|
35645
|
+
UtilizationPerformanceIndex: toNumber$2(config["UtilizationPerformanceIndex"]),
|
|
35646
35646
|
ScalingStrategy: config["ScalingStrategy"]
|
|
35647
35647
|
};
|
|
35648
35648
|
}
|
|
35649
35649
|
toAutoTerminationPolicy(config) {
|
|
35650
35650
|
if (!config) return void 0;
|
|
35651
|
-
return { IdleTimeout: toNumber(config["IdleTimeout"]) };
|
|
35651
|
+
return { IdleTimeout: toNumber$2(config["IdleTimeout"]) };
|
|
35652
35652
|
}
|
|
35653
35653
|
async update(logicalId, physicalId, resourceType, properties, previousProperties) {
|
|
35654
|
-
const changed = (key) => !jsonEqual(properties[key], previousProperties[key]);
|
|
35654
|
+
const changed = (key) => !jsonEqual$2(properties[key], previousProperties[key]);
|
|
35655
35655
|
const nextInstances = properties["Instances"] ?? {};
|
|
35656
35656
|
const prevInstances = previousProperties["Instances"] ?? {};
|
|
35657
35657
|
let terminationProtectedChanged = false;
|
|
35658
35658
|
if (changed("Instances")) {
|
|
35659
35659
|
const instanceKeys = /* @__PURE__ */ new Set([...Object.keys(nextInstances), ...Object.keys(prevInstances)]);
|
|
35660
35660
|
for (const key of instanceKeys) {
|
|
35661
|
-
if (jsonEqual(nextInstances[key], prevInstances[key])) continue;
|
|
35661
|
+
if (jsonEqual$2(nextInstances[key], prevInstances[key])) continue;
|
|
35662
35662
|
if (key === "TerminationProtected") {
|
|
35663
35663
|
terminationProtectedChanged = true;
|
|
35664
35664
|
continue;
|
|
@@ -35698,7 +35698,7 @@ var EMRClusterProvider = class {
|
|
|
35698
35698
|
}));
|
|
35699
35699
|
if (stepConcurrencyChanged) await this.getClient().send(new ModifyClusterCommand({
|
|
35700
35700
|
ClusterId: physicalId,
|
|
35701
|
-
StepConcurrencyLevel: toNumber(properties["StepConcurrencyLevel"])
|
|
35701
|
+
StepConcurrencyLevel: toNumber$2(properties["StepConcurrencyLevel"])
|
|
35702
35702
|
}));
|
|
35703
35703
|
if (managedScalingChanged) {
|
|
35704
35704
|
const next = this.toManagedScalingPolicy(properties["ManagedScalingPolicy"]);
|
|
@@ -36150,6 +36150,570 @@ var EMRClusterProvider = class {
|
|
|
36150
36150
|
}
|
|
36151
36151
|
};
|
|
36152
36152
|
|
|
36153
|
+
//#endregion
|
|
36154
|
+
//#region src/provisioning/providers/emr-instance-group-config-provider.ts
|
|
36155
|
+
/**
|
|
36156
|
+
* Default polling budget for an instance group reaching RUNNING. Adding a
|
|
36157
|
+
* group to an already-WAITING cluster provisions + bootstraps its EC2
|
|
36158
|
+
* instances (typically 2-6 minutes); a resize settles faster. Reuse the
|
|
36159
|
+
* EMR Cluster provider's 1-hour ceiling so the slowest realistic add still
|
|
36160
|
+
* fits inside the per-resource deadline.
|
|
36161
|
+
*/
|
|
36162
|
+
const DEFAULT_MAX_WAIT_MS$1 = 3600 * 1e3;
|
|
36163
|
+
const DEFAULT_POLL_INTERVAL_MS$1 = 15e3;
|
|
36164
|
+
/** Instance-group state that means "the group is up and idle/serving". */
|
|
36165
|
+
const READY_STATES$1 = /* @__PURE__ */ new Set(["RUNNING"]);
|
|
36166
|
+
/**
|
|
36167
|
+
* Instance-group states that mean "the group is gone / failed" — a hard
|
|
36168
|
+
* error during a create/resize wait (an ARRESTED group failed to provision;
|
|
36169
|
+
* TERMINATED/ENDED mean it will never reach RUNNING).
|
|
36170
|
+
*/
|
|
36171
|
+
const FAILED_STATES$1 = /* @__PURE__ */ new Set([
|
|
36172
|
+
"ARRESTED",
|
|
36173
|
+
"TERMINATED",
|
|
36174
|
+
"ENDED"
|
|
36175
|
+
]);
|
|
36176
|
+
const toNumber$1 = (v) => {
|
|
36177
|
+
if (v === void 0) return void 0;
|
|
36178
|
+
const n = Number(v);
|
|
36179
|
+
return Number.isNaN(n) ? void 0 : n;
|
|
36180
|
+
};
|
|
36181
|
+
const jsonEqual$1 = (a, b) => JSON.stringify(a) === JSON.stringify(b);
|
|
36182
|
+
/**
|
|
36183
|
+
* SDK Provider for `AWS::EMR::InstanceGroupConfig` (issue #1070).
|
|
36184
|
+
*
|
|
36185
|
+
* This type adds a standalone instance group (MASTER / CORE / TASK) to an
|
|
36186
|
+
* EXISTING EMR cluster (referenced by `JobFlowId`), rather than declaring the
|
|
36187
|
+
* group inline in `AWS::EMR::Cluster.Instances`. It is
|
|
36188
|
+
* `ProvisioningType: NON_PROVISIONABLE` in the CFn registry, so Cloud Control
|
|
36189
|
+
* cannot handle it — pre-flight would otherwise reject it via
|
|
36190
|
+
* `unsupported-types.generated.ts`.
|
|
36191
|
+
*
|
|
36192
|
+
* Lifecycle:
|
|
36193
|
+
* - `create` → `AddInstanceGroups` (one group per call) + poll
|
|
36194
|
+
* `ListInstanceGroups` until the new group is `RUNNING`. A failed terminal
|
|
36195
|
+
* (`ARRESTED` / `TERMINATED` / `ENDED`) during the wait is a hard error.
|
|
36196
|
+
* - `update` → only the two AWS-mutable properties: `InstanceCount`
|
|
36197
|
+
* (`ModifyInstanceGroups`, resize; polled until settled) and
|
|
36198
|
+
* `AutoScalingPolicy` (`PutAutoScalingPolicy` / `RemoveAutoScalingPolicy`).
|
|
36199
|
+
* Every other property is registry-createOnly → routed through
|
|
36200
|
+
* DELETE+CREATE by the replacement-detection layer; a createOnly change
|
|
36201
|
+
* that reaches `update()` anyway is refused with a `--replace` pointer.
|
|
36202
|
+
* - `delete` → **no standalone AWS API exists.** EMR cannot remove an
|
|
36203
|
+
* instance group from a running cluster; a group's only lifecycle end is
|
|
36204
|
+
* cluster termination. In the normal `cdkd destroy` the parent
|
|
36205
|
+
* `AWS::EMR::Cluster` is terminated in the same run (its `TerminateJobFlows`
|
|
36206
|
+
* releases every group + its EC2 instances), so this delete is a no-op that
|
|
36207
|
+
* just drops cdkd state — leaving ZERO orphans. As a best effort for the
|
|
36208
|
+
* less common "delete only the group, keep the cluster" case, a TASK group
|
|
36209
|
+
* is scaled to 0 instances (`ModifyInstanceGroups InstanceCount: 0`) to
|
|
36210
|
+
* release its instances; MASTER/CORE groups cannot be scaled to 0 and are a
|
|
36211
|
+
* pure no-op. Never blocks the destroy (warn-and-continue).
|
|
36212
|
+
*
|
|
36213
|
+
* `getMinResourceTimeoutMs()` lifts the deploy engine's per-resource deadline
|
|
36214
|
+
* to the polling ceiling (mirrors `EMRClusterProvider`) so a slow add/resize
|
|
36215
|
+
* does not require `--resource-timeout`.
|
|
36216
|
+
*/
|
|
36217
|
+
var EMRInstanceGroupConfigProvider = class {
|
|
36218
|
+
/**
|
|
36219
|
+
* Cloud Control has NO handlers for this type
|
|
36220
|
+
* (`ProvisioningType: NON_PROVISIONABLE`), so the deploy engine's #614
|
|
36221
|
+
* silent-drop auto-route MUST NOT send an unhandled-property template to CC
|
|
36222
|
+
* — it would fail at provisioning time with an opaque
|
|
36223
|
+
* UnsupportedActionException. With this opt-out the ProviderRegistry rejects
|
|
36224
|
+
* such templates pre-flight with a clear error instead.
|
|
36225
|
+
*/
|
|
36226
|
+
disableCcApiFallback = true;
|
|
36227
|
+
client;
|
|
36228
|
+
providerRegion = process.env["AWS_REGION"];
|
|
36229
|
+
logger = getLogger().child("EMRInstanceGroupConfigProvider");
|
|
36230
|
+
pollIntervalMs;
|
|
36231
|
+
maxWaitMs;
|
|
36232
|
+
constructor(options) {
|
|
36233
|
+
this.pollIntervalMs = options?.pollIntervalMs ?? DEFAULT_POLL_INTERVAL_MS$1;
|
|
36234
|
+
this.maxWaitMs = options?.maxWaitMs ?? DEFAULT_MAX_WAIT_MS$1;
|
|
36235
|
+
}
|
|
36236
|
+
handledProperties = /* @__PURE__ */ new Map([["AWS::EMR::InstanceGroupConfig", /* @__PURE__ */ new Set([
|
|
36237
|
+
"AutoScalingPolicy",
|
|
36238
|
+
"BidPrice",
|
|
36239
|
+
"Configurations",
|
|
36240
|
+
"CustomAmiId",
|
|
36241
|
+
"EbsConfiguration",
|
|
36242
|
+
"InstanceCount",
|
|
36243
|
+
"InstanceRole",
|
|
36244
|
+
"InstanceType",
|
|
36245
|
+
"JobFlowId",
|
|
36246
|
+
"Market",
|
|
36247
|
+
"Name"
|
|
36248
|
+
])]]);
|
|
36249
|
+
getClient() {
|
|
36250
|
+
if (!this.client) this.client = new EMRClient(this.providerRegion ? { region: this.providerRegion } : {});
|
|
36251
|
+
return this.client;
|
|
36252
|
+
}
|
|
36253
|
+
getMinResourceTimeoutMs() {
|
|
36254
|
+
return this.maxWaitMs + this.pollIntervalMs;
|
|
36255
|
+
}
|
|
36256
|
+
async create(logicalId, resourceType, properties) {
|
|
36257
|
+
if (resourceType !== "AWS::EMR::InstanceGroupConfig") throw new ProvisioningError(`Unsupported resource type: ${resourceType}`, resourceType, logicalId);
|
|
36258
|
+
const jobFlowId = properties["JobFlowId"];
|
|
36259
|
+
if (!jobFlowId) throw new ProvisioningError(`EMR InstanceGroupConfig ${logicalId} is missing JobFlowId (the parent cluster id)`, resourceType, logicalId);
|
|
36260
|
+
this.logger.debug(`Adding EMR instance group ${logicalId} to cluster ${jobFlowId}`);
|
|
36261
|
+
try {
|
|
36262
|
+
const group = this.toInstanceGroupConfig(properties);
|
|
36263
|
+
const groupId = (await this.getClient().send(new AddInstanceGroupsCommand({
|
|
36264
|
+
JobFlowId: jobFlowId,
|
|
36265
|
+
InstanceGroups: [group]
|
|
36266
|
+
}))).InstanceGroupIds?.[0];
|
|
36267
|
+
if (!groupId) throw new ProvisioningError(`EMR AddInstanceGroups for ${logicalId} returned no instance group id`, resourceType, logicalId);
|
|
36268
|
+
await this.waitForGroupReady(jobFlowId, groupId, logicalId, resourceType, toNumber$1(properties["InstanceCount"]) ?? 0);
|
|
36269
|
+
this.logger.debug(`Successfully added EMR instance group ${logicalId}: ${groupId}`);
|
|
36270
|
+
return {
|
|
36271
|
+
physicalId: groupId,
|
|
36272
|
+
attributes: { Id: groupId }
|
|
36273
|
+
};
|
|
36274
|
+
} catch (error) {
|
|
36275
|
+
if (error instanceof ProvisioningError) throw error;
|
|
36276
|
+
const cause = error instanceof Error ? error : void 0;
|
|
36277
|
+
throw new ProvisioningError(`Failed to add EMR instance group ${logicalId}: ${error instanceof Error ? error.message : String(error)}`, resourceType, logicalId, void 0, cause);
|
|
36278
|
+
}
|
|
36279
|
+
}
|
|
36280
|
+
toInstanceGroupConfig(properties) {
|
|
36281
|
+
return {
|
|
36282
|
+
InstanceRole: properties["InstanceRole"],
|
|
36283
|
+
InstanceType: properties["InstanceType"],
|
|
36284
|
+
InstanceCount: toNumber$1(properties["InstanceCount"]),
|
|
36285
|
+
Name: properties["Name"],
|
|
36286
|
+
Market: properties["Market"],
|
|
36287
|
+
BidPrice: properties["BidPrice"],
|
|
36288
|
+
Configurations: properties["Configurations"],
|
|
36289
|
+
EbsConfiguration: properties["EbsConfiguration"],
|
|
36290
|
+
AutoScalingPolicy: properties["AutoScalingPolicy"],
|
|
36291
|
+
CustomAmiId: properties["CustomAmiId"]
|
|
36292
|
+
};
|
|
36293
|
+
}
|
|
36294
|
+
async update(logicalId, physicalId, resourceType, properties, previousProperties) {
|
|
36295
|
+
const changed = (key) => !jsonEqual$1(properties[key], previousProperties[key]);
|
|
36296
|
+
const MUTABLE = /* @__PURE__ */ new Set(["InstanceCount", "AutoScalingPolicy"]);
|
|
36297
|
+
for (const key of Object.keys({
|
|
36298
|
+
...properties,
|
|
36299
|
+
...previousProperties
|
|
36300
|
+
})) {
|
|
36301
|
+
if (!changed(key)) continue;
|
|
36302
|
+
if (!MUTABLE.has(key)) throw new ResourceUpdateNotSupportedError(resourceType, logicalId, `AWS EMR InstanceGroupConfig ${key} is immutable on AWS — it is fixed when the instance group is created. Re-deploy with cdkd deploy --replace, or destroy + redeploy the stack.`);
|
|
36303
|
+
}
|
|
36304
|
+
const instanceCountChanged = changed("InstanceCount");
|
|
36305
|
+
const autoScalingChanged = changed("AutoScalingPolicy");
|
|
36306
|
+
if (!instanceCountChanged && !autoScalingChanged) {
|
|
36307
|
+
this.logger.debug(`No mutable diff for EMR instance group ${logicalId}, skipping update`);
|
|
36308
|
+
return {
|
|
36309
|
+
physicalId,
|
|
36310
|
+
wasReplaced: false
|
|
36311
|
+
};
|
|
36312
|
+
}
|
|
36313
|
+
const jobFlowId = properties["JobFlowId"];
|
|
36314
|
+
this.logger.debug(`Updating EMR instance group ${logicalId}: ${physicalId}`);
|
|
36315
|
+
try {
|
|
36316
|
+
if (instanceCountChanged) {
|
|
36317
|
+
await this.getClient().send(new ModifyInstanceGroupsCommand({
|
|
36318
|
+
...jobFlowId && { ClusterId: jobFlowId },
|
|
36319
|
+
InstanceGroups: [{
|
|
36320
|
+
InstanceGroupId: physicalId,
|
|
36321
|
+
InstanceCount: toNumber$1(properties["InstanceCount"])
|
|
36322
|
+
}]
|
|
36323
|
+
}));
|
|
36324
|
+
if (jobFlowId) await this.waitForGroupReady(jobFlowId, physicalId, logicalId, resourceType, toNumber$1(properties["InstanceCount"]) ?? 0);
|
|
36325
|
+
}
|
|
36326
|
+
if (autoScalingChanged) {
|
|
36327
|
+
if (!jobFlowId) throw new ProvisioningError(`EMR InstanceGroupConfig ${logicalId} AutoScalingPolicy update needs JobFlowId (the cluster id), which is absent`, resourceType, logicalId, physicalId);
|
|
36328
|
+
const policy = properties["AutoScalingPolicy"];
|
|
36329
|
+
if (policy) await this.getClient().send(new PutAutoScalingPolicyCommand({
|
|
36330
|
+
ClusterId: jobFlowId,
|
|
36331
|
+
InstanceGroupId: physicalId,
|
|
36332
|
+
AutoScalingPolicy: policy
|
|
36333
|
+
}));
|
|
36334
|
+
else await this.getClient().send(new RemoveAutoScalingPolicyCommand({
|
|
36335
|
+
ClusterId: jobFlowId,
|
|
36336
|
+
InstanceGroupId: physicalId
|
|
36337
|
+
}));
|
|
36338
|
+
}
|
|
36339
|
+
this.logger.debug(`Successfully updated EMR instance group ${logicalId}`);
|
|
36340
|
+
return {
|
|
36341
|
+
physicalId,
|
|
36342
|
+
wasReplaced: false,
|
|
36343
|
+
attributes: { Id: physicalId }
|
|
36344
|
+
};
|
|
36345
|
+
} catch (error) {
|
|
36346
|
+
if (error instanceof ProvisioningError || error instanceof ResourceUpdateNotSupportedError) throw error;
|
|
36347
|
+
const cause = error instanceof Error ? error : void 0;
|
|
36348
|
+
throw new ProvisioningError(`Failed to update EMR instance group ${logicalId}: ${error instanceof Error ? error.message : String(error)}`, resourceType, logicalId, physicalId, cause);
|
|
36349
|
+
}
|
|
36350
|
+
}
|
|
36351
|
+
async delete(logicalId, physicalId, resourceType, properties, context) {
|
|
36352
|
+
const role = properties?.["InstanceRole"];
|
|
36353
|
+
const jobFlowId = properties?.["JobFlowId"];
|
|
36354
|
+
if (role === "TASK" && jobFlowId) {
|
|
36355
|
+
try {
|
|
36356
|
+
await this.getClient().send(new ModifyInstanceGroupsCommand({
|
|
36357
|
+
ClusterId: jobFlowId,
|
|
36358
|
+
InstanceGroups: [{
|
|
36359
|
+
InstanceGroupId: physicalId,
|
|
36360
|
+
InstanceCount: 0
|
|
36361
|
+
}]
|
|
36362
|
+
}));
|
|
36363
|
+
this.logger.debug(`Scaled EMR TASK instance group ${physicalId} to 0 to release its instances (no standalone delete API exists)`);
|
|
36364
|
+
} catch (error) {
|
|
36365
|
+
if (error instanceof InvalidRequestException) {
|
|
36366
|
+
assertRegionMatch(await this.getClient().config.region(), context?.expectedRegion, resourceType, logicalId, physicalId);
|
|
36367
|
+
this.logger.debug(`EMR instance group ${physicalId} scale-to-0 skipped (cluster/group gone): ${error.message}`);
|
|
36368
|
+
} else this.logger.warn(`Best-effort scale-to-0 of EMR instance group ${physicalId} failed: ${error instanceof Error ? error.message : String(error)} — its instances are released when the parent cluster terminates`);
|
|
36369
|
+
}
|
|
36370
|
+
return;
|
|
36371
|
+
}
|
|
36372
|
+
this.logger.debug(`EMR instance group ${physicalId} (role ${role ?? "unknown"}) has no standalone delete API; its instances are released when the parent cluster terminates. Removing cdkd state only.`);
|
|
36373
|
+
}
|
|
36374
|
+
async getAttribute(physicalId, _resourceType, attributeName) {
|
|
36375
|
+
if (attributeName === "Id") return physicalId;
|
|
36376
|
+
}
|
|
36377
|
+
/**
|
|
36378
|
+
* Poll until the group is `RUNNING` AND its `RunningInstanceCount` equals
|
|
36379
|
+
* `expectedCount`. The count check is load-bearing on a resize: right after
|
|
36380
|
+
* `ModifyInstanceGroups` the group is still in the PRE-resize `RUNNING`
|
|
36381
|
+
* state (EMR has not flipped it to `RESIZING` yet), so a State-only wait
|
|
36382
|
+
* would return before the resize even starts. Waiting on the running count
|
|
36383
|
+
* reaching the requested target settles both create (0 -> N provisioning)
|
|
36384
|
+
* and resize (M -> N add/remove) correctly.
|
|
36385
|
+
*/
|
|
36386
|
+
async waitForGroupReady(clusterId, groupId, logicalId, resourceType, expectedCount) {
|
|
36387
|
+
const startTime = Date.now();
|
|
36388
|
+
const transientState = { count: 0 };
|
|
36389
|
+
while (Date.now() - startTime < this.maxWaitMs) {
|
|
36390
|
+
const group = await this.findGroupForPoll(clusterId, groupId, transientState);
|
|
36391
|
+
const state = group?.Status?.State;
|
|
36392
|
+
if (state && READY_STATES$1.has(state) && group?.RunningInstanceCount === expectedCount) return;
|
|
36393
|
+
if (state && FAILED_STATES$1.has(state)) throw new ProvisioningError(`EMR instance group ${groupId} entered failed state ${state}: ${group?.Status?.StateChangeReason?.Message ?? "no state-change reason reported"}`, resourceType, logicalId, groupId);
|
|
36394
|
+
this.logger.debug(`EMR instance group ${groupId} state: ${state ?? "unknown"}, running ${group?.RunningInstanceCount ?? "?"}/${expectedCount}, waiting...`);
|
|
36395
|
+
await new Promise((resolve) => setTimeout(resolve, this.pollIntervalMs));
|
|
36396
|
+
}
|
|
36397
|
+
throw new ProvisioningError(`Timed out waiting for EMR instance group ${groupId} to reach RUNNING with ${expectedCount} instance(s) (${Math.round(this.maxWaitMs / 6e4)} min)`, resourceType, logicalId, groupId);
|
|
36398
|
+
}
|
|
36399
|
+
/**
|
|
36400
|
+
* `ListInstanceGroups` (paginated) for the cluster, returning the single
|
|
36401
|
+
* group whose `Id` matches. Absorbs up to `maxConsecutiveTransient`
|
|
36402
|
+
* consecutive transient errors (throttle / 5xx / reset) so a single blip
|
|
36403
|
+
* during a 10-minute poll does not spuriously fail the create.
|
|
36404
|
+
*/
|
|
36405
|
+
async findGroupForPoll(clusterId, groupId, transientState, maxConsecutiveTransient = 5) {
|
|
36406
|
+
try {
|
|
36407
|
+
let marker;
|
|
36408
|
+
do {
|
|
36409
|
+
const resp = await this.getClient().send(new ListInstanceGroupsCommand({
|
|
36410
|
+
ClusterId: clusterId,
|
|
36411
|
+
...marker && { Marker: marker }
|
|
36412
|
+
}));
|
|
36413
|
+
const found = (resp.InstanceGroups ?? []).find((g) => g.Id === groupId);
|
|
36414
|
+
if (found) {
|
|
36415
|
+
transientState.count = 0;
|
|
36416
|
+
return found;
|
|
36417
|
+
}
|
|
36418
|
+
marker = resp.Marker;
|
|
36419
|
+
} while (marker);
|
|
36420
|
+
transientState.count = 0;
|
|
36421
|
+
return;
|
|
36422
|
+
} catch (error) {
|
|
36423
|
+
const name = error instanceof Error ? error.name : "";
|
|
36424
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
36425
|
+
if ((name === "ThrottlingException" || name === "InternalServerException" || name === "InternalServerError" || name === "TimeoutError" || /rate exceeded|too many requests|throttl|timed? ?out|ECONNRESET|EPIPE|socket hang up/i.test(msg)) && transientState.count < maxConsecutiveTransient) {
|
|
36426
|
+
transientState.count += 1;
|
|
36427
|
+
this.logger.debug(`Transient ListInstanceGroups error while polling ${groupId} (${transientState.count}/${maxConsecutiveTransient}): ${msg} — retrying`);
|
|
36428
|
+
return;
|
|
36429
|
+
}
|
|
36430
|
+
throw error;
|
|
36431
|
+
}
|
|
36432
|
+
}
|
|
36433
|
+
};
|
|
36434
|
+
|
|
36435
|
+
//#endregion
|
|
36436
|
+
//#region src/provisioning/providers/emr-instance-fleet-config-provider.ts
|
|
36437
|
+
/**
|
|
36438
|
+
* Default polling budget for an instance fleet reaching RUNNING. Adding a
|
|
36439
|
+
* fleet to an already-WAITING cluster provisions + bootstraps its EC2
|
|
36440
|
+
* instances (typically 2-6 minutes); a resize settles faster. Reuse the
|
|
36441
|
+
* EMR Cluster provider's 1-hour ceiling so the slowest realistic add still
|
|
36442
|
+
* fits inside the per-resource deadline.
|
|
36443
|
+
*/
|
|
36444
|
+
const DEFAULT_MAX_WAIT_MS = 3600 * 1e3;
|
|
36445
|
+
const DEFAULT_POLL_INTERVAL_MS = 15e3;
|
|
36446
|
+
/** Instance-fleet state that means "the fleet is up and idle/serving". */
|
|
36447
|
+
const READY_STATES = /* @__PURE__ */ new Set(["RUNNING"]);
|
|
36448
|
+
/**
|
|
36449
|
+
* Instance-fleet states that mean "the fleet is gone" — a hard error during a
|
|
36450
|
+
* create/resize wait (it will never reach RUNNING).
|
|
36451
|
+
*/
|
|
36452
|
+
const FAILED_STATES = /* @__PURE__ */ new Set(["TERMINATED"]);
|
|
36453
|
+
const toNumber = (v) => {
|
|
36454
|
+
if (v === void 0) return void 0;
|
|
36455
|
+
const n = Number(v);
|
|
36456
|
+
return Number.isNaN(n) ? void 0 : n;
|
|
36457
|
+
};
|
|
36458
|
+
const jsonEqual = (a, b) => JSON.stringify(a) === JSON.stringify(b);
|
|
36459
|
+
/**
|
|
36460
|
+
* SDK Provider for `AWS::EMR::InstanceFleetConfig` (issue #1070).
|
|
36461
|
+
*
|
|
36462
|
+
* This type adds a standalone instance fleet (MASTER / CORE / TASK) to an
|
|
36463
|
+
* EXISTING EMR cluster (referenced by `ClusterId`), rather than declaring the
|
|
36464
|
+
* fleet inline in `AWS::EMR::Cluster.Instances`. It is
|
|
36465
|
+
* `ProvisioningType: NON_PROVISIONABLE` in the CFn registry, so Cloud Control
|
|
36466
|
+
* cannot handle it — pre-flight would otherwise reject it via
|
|
36467
|
+
* `unsupported-types.generated.ts`.
|
|
36468
|
+
*
|
|
36469
|
+
* Lifecycle:
|
|
36470
|
+
* - `create` → `AddInstanceFleet` + poll `ListInstanceFleets` until the new
|
|
36471
|
+
* fleet is `RUNNING`. A `TERMINATED` terminal during the wait is a hard
|
|
36472
|
+
* error.
|
|
36473
|
+
* - `update` → only the AWS-mutable properties: `TargetOnDemandCapacity`,
|
|
36474
|
+
* `TargetSpotCapacity`, `ResizeSpecifications`, and `InstanceTypeConfigs`
|
|
36475
|
+
* (all via `ModifyInstanceFleet`; the resize is polled until settled).
|
|
36476
|
+
* `Name` / `LaunchSpecifications` / `InstanceFleetType` are
|
|
36477
|
+
* registry-createOnly → routed through DELETE+CREATE by the
|
|
36478
|
+
* replacement-detection layer; a createOnly change that reaches `update()`
|
|
36479
|
+
* anyway is refused with a `--replace` pointer.
|
|
36480
|
+
* - `delete` → **no standalone AWS API exists.** EMR cannot remove an
|
|
36481
|
+
* instance fleet from a running cluster; a fleet's only lifecycle end is
|
|
36482
|
+
* cluster termination. In the normal `cdkd destroy` the parent
|
|
36483
|
+
* `AWS::EMR::Cluster` is terminated in the same run (its `TerminateJobFlows`
|
|
36484
|
+
* releases every fleet + its EC2 instances), so this delete is a no-op that
|
|
36485
|
+
* just drops cdkd state — leaving ZERO orphans. As a best effort for the
|
|
36486
|
+
* less common "delete only the fleet, keep the cluster" case, a TASK fleet
|
|
36487
|
+
* is scaled to 0 target capacity (`ModifyInstanceFleet`) to release its
|
|
36488
|
+
* instances; MASTER/CORE fleets cannot be scaled to 0 and are a pure no-op.
|
|
36489
|
+
* Never blocks the destroy (warn-and-continue).
|
|
36490
|
+
*
|
|
36491
|
+
* `getMinResourceTimeoutMs()` lifts the deploy engine's per-resource deadline
|
|
36492
|
+
* to the polling ceiling (mirrors `EMRClusterProvider`) so a slow add/resize
|
|
36493
|
+
* does not require `--resource-timeout`.
|
|
36494
|
+
*/
|
|
36495
|
+
var EMRInstanceFleetConfigProvider = class {
|
|
36496
|
+
/**
|
|
36497
|
+
* Cloud Control has NO handlers for this type
|
|
36498
|
+
* (`ProvisioningType: NON_PROVISIONABLE`), so the deploy engine's #614
|
|
36499
|
+
* silent-drop auto-route MUST NOT send an unhandled-property template to CC
|
|
36500
|
+
* — it would fail at provisioning time with an opaque
|
|
36501
|
+
* UnsupportedActionException. With this opt-out the ProviderRegistry rejects
|
|
36502
|
+
* such templates pre-flight with a clear error instead.
|
|
36503
|
+
*/
|
|
36504
|
+
disableCcApiFallback = true;
|
|
36505
|
+
client;
|
|
36506
|
+
providerRegion = process.env["AWS_REGION"];
|
|
36507
|
+
logger = getLogger().child("EMRInstanceFleetConfigProvider");
|
|
36508
|
+
pollIntervalMs;
|
|
36509
|
+
maxWaitMs;
|
|
36510
|
+
constructor(options) {
|
|
36511
|
+
this.pollIntervalMs = options?.pollIntervalMs ?? DEFAULT_POLL_INTERVAL_MS;
|
|
36512
|
+
this.maxWaitMs = options?.maxWaitMs ?? DEFAULT_MAX_WAIT_MS;
|
|
36513
|
+
}
|
|
36514
|
+
handledProperties = /* @__PURE__ */ new Map([["AWS::EMR::InstanceFleetConfig", /* @__PURE__ */ new Set([
|
|
36515
|
+
"ClusterId",
|
|
36516
|
+
"InstanceFleetType",
|
|
36517
|
+
"InstanceTypeConfigs",
|
|
36518
|
+
"LaunchSpecifications",
|
|
36519
|
+
"Name",
|
|
36520
|
+
"ResizeSpecifications",
|
|
36521
|
+
"TargetOnDemandCapacity",
|
|
36522
|
+
"TargetSpotCapacity"
|
|
36523
|
+
])]]);
|
|
36524
|
+
getClient() {
|
|
36525
|
+
if (!this.client) this.client = new EMRClient(this.providerRegion ? { region: this.providerRegion } : {});
|
|
36526
|
+
return this.client;
|
|
36527
|
+
}
|
|
36528
|
+
getMinResourceTimeoutMs() {
|
|
36529
|
+
return this.maxWaitMs + this.pollIntervalMs;
|
|
36530
|
+
}
|
|
36531
|
+
async create(logicalId, resourceType, properties) {
|
|
36532
|
+
if (resourceType !== "AWS::EMR::InstanceFleetConfig") throw new ProvisioningError(`Unsupported resource type: ${resourceType}`, resourceType, logicalId);
|
|
36533
|
+
const clusterId = properties["ClusterId"];
|
|
36534
|
+
if (!clusterId) throw new ProvisioningError(`EMR InstanceFleetConfig ${logicalId} is missing ClusterId (the parent cluster id)`, resourceType, logicalId);
|
|
36535
|
+
this.logger.debug(`Adding EMR instance fleet ${logicalId} to cluster ${clusterId}`);
|
|
36536
|
+
try {
|
|
36537
|
+
const fleet = this.toInstanceFleetConfig(properties);
|
|
36538
|
+
const fleetId = (await this.getClient().send(new AddInstanceFleetCommand({
|
|
36539
|
+
ClusterId: clusterId,
|
|
36540
|
+
InstanceFleet: fleet
|
|
36541
|
+
}))).InstanceFleetId;
|
|
36542
|
+
if (!fleetId) throw new ProvisioningError(`EMR AddInstanceFleet for ${logicalId} returned no instance fleet id`, resourceType, logicalId);
|
|
36543
|
+
await this.waitForFleetReady(clusterId, fleetId, logicalId, resourceType, this.targetCapacity(properties), true);
|
|
36544
|
+
this.logger.debug(`Successfully added EMR instance fleet ${logicalId}: ${fleetId}`);
|
|
36545
|
+
return {
|
|
36546
|
+
physicalId: fleetId,
|
|
36547
|
+
attributes: { Id: fleetId }
|
|
36548
|
+
};
|
|
36549
|
+
} catch (error) {
|
|
36550
|
+
if (error instanceof ProvisioningError) throw error;
|
|
36551
|
+
const cause = error instanceof Error ? error : void 0;
|
|
36552
|
+
throw new ProvisioningError(`Failed to add EMR instance fleet ${logicalId}: ${error instanceof Error ? error.message : String(error)}`, resourceType, logicalId, void 0, cause);
|
|
36553
|
+
}
|
|
36554
|
+
}
|
|
36555
|
+
toInstanceFleetConfig(properties) {
|
|
36556
|
+
return {
|
|
36557
|
+
InstanceFleetType: properties["InstanceFleetType"],
|
|
36558
|
+
Name: properties["Name"],
|
|
36559
|
+
TargetOnDemandCapacity: toNumber(properties["TargetOnDemandCapacity"]),
|
|
36560
|
+
TargetSpotCapacity: toNumber(properties["TargetSpotCapacity"]),
|
|
36561
|
+
InstanceTypeConfigs: properties["InstanceTypeConfigs"],
|
|
36562
|
+
LaunchSpecifications: properties["LaunchSpecifications"],
|
|
36563
|
+
ResizeSpecifications: properties["ResizeSpecifications"]
|
|
36564
|
+
};
|
|
36565
|
+
}
|
|
36566
|
+
async update(logicalId, physicalId, resourceType, properties, previousProperties) {
|
|
36567
|
+
const changed = (key) => !jsonEqual(properties[key], previousProperties[key]);
|
|
36568
|
+
const MUTABLE = /* @__PURE__ */ new Set([
|
|
36569
|
+
"TargetOnDemandCapacity",
|
|
36570
|
+
"TargetSpotCapacity",
|
|
36571
|
+
"ResizeSpecifications",
|
|
36572
|
+
"InstanceTypeConfigs"
|
|
36573
|
+
]);
|
|
36574
|
+
for (const key of Object.keys({
|
|
36575
|
+
...properties,
|
|
36576
|
+
...previousProperties
|
|
36577
|
+
})) {
|
|
36578
|
+
if (!changed(key)) continue;
|
|
36579
|
+
if (!MUTABLE.has(key)) throw new ResourceUpdateNotSupportedError(resourceType, logicalId, `AWS EMR InstanceFleetConfig ${key} is immutable on AWS — it is fixed when the instance fleet is created. Re-deploy with cdkd deploy --replace, or destroy + redeploy the stack.`);
|
|
36580
|
+
}
|
|
36581
|
+
if (![...MUTABLE].some((k) => changed(k))) {
|
|
36582
|
+
this.logger.debug(`No mutable diff for EMR instance fleet ${logicalId}, skipping update`);
|
|
36583
|
+
return {
|
|
36584
|
+
physicalId,
|
|
36585
|
+
wasReplaced: false
|
|
36586
|
+
};
|
|
36587
|
+
}
|
|
36588
|
+
const clusterId = properties["ClusterId"];
|
|
36589
|
+
if (!clusterId) throw new ProvisioningError(`EMR InstanceFleetConfig ${logicalId} update needs ClusterId (the cluster id), which is absent`, resourceType, logicalId, physicalId);
|
|
36590
|
+
this.logger.debug(`Updating EMR instance fleet ${logicalId}: ${physicalId}`);
|
|
36591
|
+
try {
|
|
36592
|
+
const modify = {
|
|
36593
|
+
InstanceFleetId: physicalId,
|
|
36594
|
+
TargetOnDemandCapacity: toNumber(properties["TargetOnDemandCapacity"]),
|
|
36595
|
+
TargetSpotCapacity: toNumber(properties["TargetSpotCapacity"]),
|
|
36596
|
+
ResizeSpecifications: properties["ResizeSpecifications"],
|
|
36597
|
+
InstanceTypeConfigs: properties["InstanceTypeConfigs"]
|
|
36598
|
+
};
|
|
36599
|
+
await this.getClient().send(new ModifyInstanceFleetCommand({
|
|
36600
|
+
ClusterId: clusterId,
|
|
36601
|
+
InstanceFleet: modify
|
|
36602
|
+
}));
|
|
36603
|
+
const newTarget = this.targetCapacity(properties);
|
|
36604
|
+
const prevTarget = this.targetCapacity(previousProperties);
|
|
36605
|
+
await this.waitForFleetReady(clusterId, physicalId, logicalId, resourceType, newTarget, newTarget >= prevTarget);
|
|
36606
|
+
this.logger.debug(`Successfully updated EMR instance fleet ${logicalId}`);
|
|
36607
|
+
return {
|
|
36608
|
+
physicalId,
|
|
36609
|
+
wasReplaced: false,
|
|
36610
|
+
attributes: { Id: physicalId }
|
|
36611
|
+
};
|
|
36612
|
+
} catch (error) {
|
|
36613
|
+
if (error instanceof ProvisioningError || error instanceof ResourceUpdateNotSupportedError) throw error;
|
|
36614
|
+
const cause = error instanceof Error ? error : void 0;
|
|
36615
|
+
throw new ProvisioningError(`Failed to update EMR instance fleet ${logicalId}: ${error instanceof Error ? error.message : String(error)}`, resourceType, logicalId, physicalId, cause);
|
|
36616
|
+
}
|
|
36617
|
+
}
|
|
36618
|
+
async delete(logicalId, physicalId, resourceType, properties, context) {
|
|
36619
|
+
const fleetType = properties?.["InstanceFleetType"];
|
|
36620
|
+
const clusterId = properties?.["ClusterId"];
|
|
36621
|
+
if (fleetType === "TASK" && clusterId) {
|
|
36622
|
+
try {
|
|
36623
|
+
await this.getClient().send(new ModifyInstanceFleetCommand({
|
|
36624
|
+
ClusterId: clusterId,
|
|
36625
|
+
InstanceFleet: {
|
|
36626
|
+
InstanceFleetId: physicalId,
|
|
36627
|
+
TargetOnDemandCapacity: 0,
|
|
36628
|
+
TargetSpotCapacity: 0
|
|
36629
|
+
}
|
|
36630
|
+
}));
|
|
36631
|
+
this.logger.debug(`Scaled EMR TASK instance fleet ${physicalId} to 0 to release its instances (no standalone delete API exists)`);
|
|
36632
|
+
} catch (error) {
|
|
36633
|
+
if (error instanceof InvalidRequestException) {
|
|
36634
|
+
assertRegionMatch(await this.getClient().config.region(), context?.expectedRegion, resourceType, logicalId, physicalId);
|
|
36635
|
+
this.logger.debug(`EMR instance fleet ${physicalId} scale-to-0 skipped (cluster/fleet gone): ${error.message}`);
|
|
36636
|
+
} else this.logger.warn(`Best-effort scale-to-0 of EMR instance fleet ${physicalId} failed: ${error instanceof Error ? error.message : String(error)} — its instances are released when the parent cluster terminates`);
|
|
36637
|
+
}
|
|
36638
|
+
return;
|
|
36639
|
+
}
|
|
36640
|
+
this.logger.debug(`EMR instance fleet ${physicalId} (type ${fleetType ?? "unknown"}) has no standalone delete API; its instances are released when the parent cluster terminates. Removing cdkd state only.`);
|
|
36641
|
+
}
|
|
36642
|
+
async getAttribute(physicalId, _resourceType, attributeName) {
|
|
36643
|
+
if (attributeName === "Id") return physicalId;
|
|
36644
|
+
}
|
|
36645
|
+
/** Total target capacity (On-Demand + Spot) requested for the fleet. */
|
|
36646
|
+
targetCapacity(properties) {
|
|
36647
|
+
return (toNumber(properties["TargetOnDemandCapacity"]) ?? 0) + (toNumber(properties["TargetSpotCapacity"]) ?? 0);
|
|
36648
|
+
}
|
|
36649
|
+
/**
|
|
36650
|
+
* Poll until the fleet is `RUNNING` AND its provisioned capacity
|
|
36651
|
+
* (On-Demand + Spot) has settled at `targetCapacity`. The capacity check is
|
|
36652
|
+
* load-bearing on a resize: right after `ModifyInstanceFleet` the fleet is
|
|
36653
|
+
* still in the PRE-resize `RUNNING` state, so a State-only wait would return
|
|
36654
|
+
* before the resize even starts.
|
|
36655
|
+
*
|
|
36656
|
+
* `atLeast` selects the settle direction:
|
|
36657
|
+
* - `true` (create / scale-UP): ready when `provisioned >= targetCapacity`
|
|
36658
|
+
* (`>=`, not `==`, because a weighted-capacity allocation may overshoot).
|
|
36659
|
+
* - `false` (scale-DOWN): ready when `provisioned <= targetCapacity` — the
|
|
36660
|
+
* stale pre-resize provisioned capacity is ABOVE the new lower target, so
|
|
36661
|
+
* an `>=` check would return instantly before instances drain.
|
|
36662
|
+
*
|
|
36663
|
+
* A `targetCapacity` of 0 on the up path (never valid for a real create —
|
|
36664
|
+
* at least one target must be > 0) degrades to a State-only wait.
|
|
36665
|
+
*/
|
|
36666
|
+
async waitForFleetReady(clusterId, fleetId, logicalId, resourceType, targetCapacity, atLeast) {
|
|
36667
|
+
const startTime = Date.now();
|
|
36668
|
+
const transientState = { count: 0 };
|
|
36669
|
+
while (Date.now() - startTime < this.maxWaitMs) {
|
|
36670
|
+
const fleet = await this.findFleetForPoll(clusterId, fleetId, transientState);
|
|
36671
|
+
const state = fleet?.Status?.State;
|
|
36672
|
+
const provisioned = (fleet?.ProvisionedOnDemandCapacity ?? 0) + (fleet?.ProvisionedSpotCapacity ?? 0);
|
|
36673
|
+
const capacityReady = atLeast ? provisioned >= targetCapacity : provisioned <= targetCapacity;
|
|
36674
|
+
if (state && READY_STATES.has(state) && capacityReady) return;
|
|
36675
|
+
if (state && FAILED_STATES.has(state)) throw new ProvisioningError(`EMR instance fleet ${fleetId} entered failed state ${state}: ${fleet?.Status?.StateChangeReason?.Message ?? "no state-change reason reported"}`, resourceType, logicalId, fleetId);
|
|
36676
|
+
this.logger.debug(`EMR instance fleet ${fleetId} state: ${state ?? "unknown"}, provisioned ${provisioned}/${targetCapacity}, waiting...`);
|
|
36677
|
+
await new Promise((resolve) => setTimeout(resolve, this.pollIntervalMs));
|
|
36678
|
+
}
|
|
36679
|
+
throw new ProvisioningError(`Timed out waiting for EMR instance fleet ${fleetId} to reach RUNNING with capacity ${targetCapacity} (${Math.round(this.maxWaitMs / 6e4)} min)`, resourceType, logicalId, fleetId);
|
|
36680
|
+
}
|
|
36681
|
+
/**
|
|
36682
|
+
* `ListInstanceFleets` (paginated) for the cluster, returning the single
|
|
36683
|
+
* fleet whose `Id` matches. Absorbs up to `maxConsecutiveTransient`
|
|
36684
|
+
* consecutive transient errors (throttle / 5xx / reset) so a single blip
|
|
36685
|
+
* during a 10-minute poll does not spuriously fail the create.
|
|
36686
|
+
*/
|
|
36687
|
+
async findFleetForPoll(clusterId, fleetId, transientState, maxConsecutiveTransient = 5) {
|
|
36688
|
+
try {
|
|
36689
|
+
let marker;
|
|
36690
|
+
do {
|
|
36691
|
+
const resp = await this.getClient().send(new ListInstanceFleetsCommand({
|
|
36692
|
+
ClusterId: clusterId,
|
|
36693
|
+
...marker && { Marker: marker }
|
|
36694
|
+
}));
|
|
36695
|
+
const found = (resp.InstanceFleets ?? []).find((f) => f.Id === fleetId);
|
|
36696
|
+
if (found) {
|
|
36697
|
+
transientState.count = 0;
|
|
36698
|
+
return found;
|
|
36699
|
+
}
|
|
36700
|
+
marker = resp.Marker;
|
|
36701
|
+
} while (marker);
|
|
36702
|
+
transientState.count = 0;
|
|
36703
|
+
return;
|
|
36704
|
+
} catch (error) {
|
|
36705
|
+
const name = error instanceof Error ? error.name : "";
|
|
36706
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
36707
|
+
if ((name === "ThrottlingException" || name === "InternalServerException" || name === "InternalServerError" || name === "TimeoutError" || /rate exceeded|too many requests|throttl|timed? ?out|ECONNRESET|EPIPE|socket hang up/i.test(msg)) && transientState.count < maxConsecutiveTransient) {
|
|
36708
|
+
transientState.count += 1;
|
|
36709
|
+
this.logger.debug(`Transient ListInstanceFleets error while polling ${fleetId} (${transientState.count}/${maxConsecutiveTransient}): ${msg} — retrying`);
|
|
36710
|
+
return;
|
|
36711
|
+
}
|
|
36712
|
+
throw error;
|
|
36713
|
+
}
|
|
36714
|
+
}
|
|
36715
|
+
};
|
|
36716
|
+
|
|
36153
36717
|
//#endregion
|
|
36154
36718
|
//#region src/provisioning/providers/firehose-provider.ts
|
|
36155
36719
|
/**
|
|
@@ -41762,6 +42326,8 @@ function registerAllProviders(registry) {
|
|
|
41762
42326
|
registry.register("AWS::EFS::AccessPoint", efsProvider);
|
|
41763
42327
|
registry.register("AWS::FSx::FileSystem", new FSxFileSystemProvider());
|
|
41764
42328
|
registry.register("AWS::EMR::Cluster", new EMRClusterProvider());
|
|
42329
|
+
registry.register("AWS::EMR::InstanceGroupConfig", new EMRInstanceGroupConfigProvider());
|
|
42330
|
+
registry.register("AWS::EMR::InstanceFleetConfig", new EMRInstanceFleetConfigProvider());
|
|
41765
42331
|
registry.register("AWS::KinesisFirehose::DeliveryStream", new FirehoseProvider());
|
|
41766
42332
|
registry.register("AWS::CloudTrail::Trail", new CloudTrailProvider());
|
|
41767
42333
|
registry.register("AWS::CodeBuild::Project", new CodeBuildProvider());
|
|
@@ -61042,7 +61608,7 @@ function reorderArgs(argv) {
|
|
|
61042
61608
|
async function main() {
|
|
61043
61609
|
installPipeCloseHandler();
|
|
61044
61610
|
const program = new Command();
|
|
61045
|
-
program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.
|
|
61611
|
+
program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.250.0");
|
|
61046
61612
|
program.addCommand(createBootstrapCommand());
|
|
61047
61613
|
program.addCommand(createSynthCommand());
|
|
61048
61614
|
program.addCommand(createListCommand());
|