@go-to-k/cdkd 0.308.0 → 0.308.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (30) hide show
  1. package/dist/{asg-provider-CsRMe_zh.js → asg-provider-B7pAjRIc.js} +3 -3
  2. package/dist/{asg-provider-CsRMe_zh.js.map → asg-provider-B7pAjRIc.js.map} +1 -1
  3. package/dist/cli.js +2 -2
  4. package/dist/{db-instance-modify-retry-DOJPkECL.js → db-instance-modify-retry-BUG7NMWS.js} +3 -3
  5. package/dist/{db-instance-modify-retry-DOJPkECL.js.map → db-instance-modify-retry-BUG7NMWS.js.map} +1 -1
  6. package/dist/{deploy-engine-DSpxEUjC.js → deploy-engine-CDjAtIrn.js} +188 -39
  7. package/dist/deploy-engine-CDjAtIrn.js.map +1 -0
  8. package/dist/{iam-policy-targets-TFGunWmV.js → iam-policy-targets-D94wh05t.js} +5 -2
  9. package/dist/{iam-policy-targets-TFGunWmV.js.map → iam-policy-targets-D94wh05t.js.map} +1 -1
  10. package/dist/{iam-role-provider--eWrOXce.js → iam-role-provider-DbtvFel_.js} +3 -3
  11. package/dist/{iam-role-provider--eWrOXce.js.map → iam-role-provider-DbtvFel_.js.map} +1 -1
  12. package/dist/index.d.ts +8 -1
  13. package/dist/index.d.ts.map +1 -1
  14. package/dist/index.js +3 -3
  15. package/dist/{neptune-provider-p59T8CFv.js → neptune-provider-Y3Ii8oYI.js} +11 -9
  16. package/dist/neptune-provider-Y3Ii8oYI.js.map +1 -0
  17. package/dist/{program-DOPic-aS.js → program-Ymf7svYk.js} +25 -8
  18. package/dist/program-Ymf7svYk.js.map +1 -0
  19. package/dist/{provider-classes-d9K3vBVh.js → provider-classes-BxfIHcea.js} +498 -73
  20. package/dist/provider-classes-BxfIHcea.js.map +1 -0
  21. package/dist/{rds-provider-BPs9JSk_.js → rds-provider-CZhBLQgJ.js} +24 -9
  22. package/dist/rds-provider-CZhBLQgJ.js.map +1 -0
  23. package/dist/{version-DzajQDkv.js → version-BWqrjGBS.js} +2 -2
  24. package/dist/{version-DzajQDkv.js.map → version-BWqrjGBS.js.map} +1 -1
  25. package/package.json +1 -1
  26. package/dist/deploy-engine-DSpxEUjC.js.map +0 -1
  27. package/dist/neptune-provider-p59T8CFv.js.map +0 -1
  28. package/dist/program-DOPic-aS.js.map +0 -1
  29. package/dist/provider-classes-d9K3vBVh.js.map +0 -1
  30. package/dist/rds-provider-BPs9JSk_.js.map +0 -1
@@ -1,14 +1,14 @@
1
1
  import { r as getAwsClients, s as withApiGatewayPacing } from "./aws-clients-Bu9EMILF.js";
2
2
  import { B as SECRET_REF_MAX_CODE_POINTS, C as generateResourceName, D as getCurrentStackInstanceId, J as displayStackName, K as displayIdent, M as recordedGeneratedNameKept, Q as safeMsg, T as generatedNameFor, Y as isPasteableIdent, Z as plainIdentOr, a as safeStringify, i as isAwsAuthoredFailure, k as isBeforeStateRead, n as describeAwsFailure, q as displaySafe, r as describeAwsStatusReason, s as getLogger, t as VERBOSE_POINTER, w as generateResourceNameWithFallback } from "./aws-failure-text-NSBdKPYK.js";
3
- import { $ as userPoolProtectionSite, $t as injectiveKeyPrefix, A as isPlainImportJson, C as setBounded, Cr as markNonRetryable, Ct as createMaskedLogSinks, D as markNotGone, Dn as ResourceUpdateNotSupportedError, Dt as maskerOrIdentity, Et as maskDeep, F as refusalTypeShown, Ft as isAuxiliaryFailure, G as isTerminalDbStatus, H as deleteWithProtectionCompensation, Hn as hasClauseBreak, I as remedyLogicalId, J as observeThenDisableProtection, K as isTerminalDeleteFailure, Kn as plainOrDescribed, L as resolveExplicitPhysicalId, Lt as markAuxiliaryFailure, M as isQuotableImportValue, N as normalizeAwsTagsToCfn, O as assertRegionMatch, Ot as withDerivedNameMasks, P as quotedRemedyLogicalId, Qt as injectiveKey, Rt as markCreatedBeforeFailure, S as replayedSendWindow, Sr as isThrottlingError, St as stateOrphanRecordRemedy, T as RESOURCE_NOT_FOUND, Tn as ProvisioningError, Tr as wrapMaskedAwsError, Tt as isSecretDerivedValue, Un as isInertUnquoted, V as deleteAfterProtectionFlipWithFinalSnapshot, Vn as commandHole, Wn as pasteableCommand, X as rdsFamilyProtectionSite, Xn as withheldTargetClause, Y as protectionFlipKey, Yn as shellQuote, _ as RecentIdSet, _r as isRetryableTransientError, _t as compositeIdSkipResult, a as onlySecretDerived, an as ambientCredentialConfig, ar as markNameCollision, at as protectedReplacementAdvice, b as isInsideWindow, br as THROTTLING_ERROR_NAMES, c as recordedPrincipalsRepair, cn as AccountIdUnavailableError, dr as explicitDenyPolicyKind, ft as isInterruptedWaitError, g as AmbiguousCreateLatch, gt as compositeIdSeparatorRefusal, h as AMBIGUOUS_LATCH_TTL_MS, hr as isExplicitDenyError, ht as compositeIdFormatMessage, i as holdsSecretDerivedEntry, in as ambientClientDefaults, it as pasteableAwsCommand, j as isPlainImportValue, jt as clearCreatedBeforeFailure, k as VALUE_NOT_SHOWN, mr as isAmbiguousOutcomeError, mt as canonicalizeRoute53QueryName, nt as WITHHELD_AWS_COMMAND, o as readPrincipalLists, on as clientDefaultsFor, or as markReplayMayCollide, ot as renderDisableCommand, p as withRemovalDefaults, pt as startInterruptWatch, q as logGroupProtectionSite, r as SECRET_DERIVED_READ_LIVE, rn as withPasteableAwsProfile, rt as isAwsCliLiteral, sn as credentialFingerprint, sr as relayedNameCollision, st as ElapsedBudgetRegistry, tt as UNNAMEABLE_ID_CLAUSE, u as clearOnUpdateRemoval, un as CdkdError, v as ambiguousAttemptLead, vr as isTransientServerError, vt as logicalIdShown, w as withoutServerErrorRetries, wr as markRedactedCause, wt as createMaskedRetryLogger, x as replayFollowedAmbiguousAttempt, xr as isMarkedNonRetryable, xt as segmentAfterAnchor, y as createAttemptKey, yt as packCompositeId, z as ProtectionFlipRegistry, zt as markSupersedesEarlierCreate } from "./iam-policy-targets-TFGunWmV.js";
3
+ import { $ as userPoolProtectionSite, $t as injectiveKeyPrefix, A as isPlainImportJson, C as setBounded, Cr as markNonRetryable, Ct as createMaskedLogSinks, D as markNotGone, Dn as ResourceUpdateNotSupportedError, Dt as maskerOrIdentity, Et as maskDeep, F as refusalTypeShown, Ft as isAuxiliaryFailure, G as isTerminalDbWaitStatus, H as deleteWithProtectionCompensation, Hn as hasClauseBreak, I as remedyLogicalId, J as observeThenDisableProtection, K as isTerminalDeleteFailure, Kn as plainOrDescribed, L as resolveExplicitPhysicalId, Lt as markAuxiliaryFailure, M as isQuotableImportValue, N as normalizeAwsTagsToCfn, O as assertRegionMatch, Ot as withDerivedNameMasks, P as quotedRemedyLogicalId, Qt as injectiveKey, Rt as markCreatedBeforeFailure, S as replayedSendWindow, Sr as isThrottlingError, St as stateOrphanRecordRemedy, T as RESOURCE_NOT_FOUND, Tn as ProvisioningError, Tr as wrapMaskedAwsError, Tt as isSecretDerivedValue, Un as isInertUnquoted, V as deleteAfterProtectionFlipWithFinalSnapshot, Vn as commandHole, Wn as pasteableCommand, X as rdsFamilyProtectionSite, Xn as withheldTargetClause, Y as protectionFlipKey, Yn as shellQuote, _ as RecentIdSet, _r as isRetryableTransientError, _t as compositeIdSkipResult, a as onlySecretDerived, an as ambientCredentialConfig, ar as markNameCollision, at as protectedReplacementAdvice, b as isInsideWindow, br as THROTTLING_ERROR_NAMES, c as recordedPrincipalsRepair, cn as AccountIdUnavailableError, dr as explicitDenyPolicyKind, ft as isInterruptedWaitError, g as AmbiguousCreateLatch, gt as compositeIdSeparatorRefusal, h as AMBIGUOUS_LATCH_TTL_MS, hr as isExplicitDenyError, ht as compositeIdFormatMessage, i as holdsSecretDerivedEntry, in as ambientClientDefaults, it as pasteableAwsCommand, j as isPlainImportValue, jt as clearCreatedBeforeFailure, k as VALUE_NOT_SHOWN, mr as isAmbiguousOutcomeError, mt as canonicalizeRoute53QueryName, nt as WITHHELD_AWS_COMMAND, o as readPrincipalLists, on as clientDefaultsFor, or as markReplayMayCollide, ot as renderDisableCommand, p as withRemovalDefaults, pt as startInterruptWatch, q as logGroupProtectionSite, r as SECRET_DERIVED_READ_LIVE, rn as withPasteableAwsProfile, rt as isAwsCliLiteral, sn as credentialFingerprint, sr as relayedNameCollision, st as ElapsedBudgetRegistry, tt as UNNAMEABLE_ID_CLAUSE, u as clearOnUpdateRemoval, un as CdkdError, v as ambiguousAttemptLead, vr as isTransientServerError, vt as logicalIdShown, w as withoutServerErrorRetries, wr as markRedactedCause, wt as createMaskedRetryLogger, x as replayFollowedAmbiguousAttempt, xr as isMarkedNonRetryable, xt as segmentAfterAnchor, y as createAttemptKey, yt as packCompositeId, z as ProtectionFlipRegistry, zt as markSupersedesEarlierCreate } from "./iam-policy-targets-D94wh05t.js";
4
4
  import { c as ambientRegion } from "./aws-client-defaults-BX9Y_fKp.js";
5
- import { $c as carriesSecretMask, $s as canonicalLambdaFunctionName, A as beginDeleteWait, Ai as tagPlanWarning, An as redactedDeleteAddressFields, B as waitForIndexesSettled, Bl as stringifyValue, Bs as configIntegerRefusal, C as planContributorInsightsOp, Ci as markDeleteStarted, Cs as withoutSilentDropProperties, D as reverseMapTableContributorInsights, Di as readTagList, E as reverseMapIndexContributorInsights, Ei as planTagDiff, En as getCurrentProducerRegions, Er as replacedDeleteFailureVerdict, F as DELETE_INDEX_WAIT_PROCEED_NOTE, Fs as toCfnInteger, G as S3_AUTO_DELETE_OBJECTS_TAG, Ga as getAccountInfo, Gl as rewriteTemplateAssetReferences, Gs as requireConfigObject, H as planTimeToLive, Hi as getCurrentResourceSecrets, Hs as readConfigString, I as INDEX_SETTLE_POLL_INTERVAL_MS, Is as toFiniteNumber, J as getPriorAttempts, Jc as recoverMaskedOutput, Ji as slowCcOperationTimeoutMs, Ju as derivePartitionAndUrlSuffix, K as hasCdkAutoDeleteTag, Ks as requireConfigString, L as deleteTableWithIndexBusyRetry, Ll as timePhase, Ls as coerceCfnBoolean, M as deleteBudgetKey, Mi as stringifyIfAssigned, Ms as WARM_THROUGHPUT_MEMBERS, N as resolveDynamoDbDeleteBudgetClock, Ns as coerceWarmThroughput$1, O as stripIndexContributorInsights, Oi as refuseMalformedDesiredTags, On as REDACTED_DELETE_ADDRESS_SKIP_REASON, P as resolveDynamoDbDeleteBudgetMs, Ps as isWarmThroughputDecrease, Pt as revertNestedChildFromJournal, Qs as emrClusterInstancesReplaced, Qt as withApiLimit, R as maskedLogger, Ri as waitForLambdaFunctionActive, Rs as coerceCfnInteger, Rt as getCurrentNestedStackContext, S as indexDeclaresContributorInsights, Sc as snapshotPassProvenance, Si as isRefusedByName, Sr as awaitInFlightSibling, T as readContributorInsightsSpec, Ta as outputReferenceProvenanceOf, Tc as hasMaskableValues, Ti as DBPROXY_TAG_OPTIONS, U as readTtlSpec, Us as replayWarn, V as isTtlAlreadyDisabled, Vc as dynamicReferenceTokens, Vo as refuseMalformedNestedChildOutputs, Vs as configStringRefusal, W as ECR_AUTO_DELETE_IMAGES_TAG, Ws as requireConfigArray, Wu as decodeListingKey, Xc as recordAttributeIdCopy, Xi as unchangedBehindSecretReference, Xs as withRetry, Xt as isAccessDeniedError, Y as markRefusedBeforeApplying, Yc as physicalNameCopiesOf, Yi as onlySecretReferencesDiffer, Yt as chunks, Zs as ecsServiceLaunchTypeSetOrChanged, Zt as lookupEachName, _ as streamMemberRefusals, _a as s3BucketDomainName, ao as passedParameterClassesOf, at as isAbsoluteAssetPath, b as CONTRIBUTOR_INSIGHTS_KEY, ba as s3BucketWebsiteUrl, bc as redactForState, c as DynamoDBGlobalTableProvider, ca as observeThenDisableInstanceApiTermination, cd as displayAssemblyPath, d as declaredStreamPolicyMember, ec as lambdaFunctionNameForMask, f as declaredStreamTagsMember, fo as accountArgs, g as streamDeclaresTags, ga as s3BucketArn, gi as reserveStackCreateToken, h as streamDeclaresPolicy, ha as isSettledInstanceState, ia as markWaitAbandoned, it as findNestedTemplateTreeDefect, j as compensateRemovedDeletionProtection, ji as definedAttributes, jn as redactedDeleteAddressSkip, jt as getNestedRevertRun, k as DYNAMODB_DELETE_MIN_RESOURCE_TIMEOUT_MS, ki as tagMapAsList, kn as isRedactedRecordedValue, l as STREAM_POLICY_KEY, la as reDisableInstanceApiTermination, ld as renderAssemblyPathEscape, m as reverseMapStreamPolicy, mi as earliestDefined, mt as enclosingDeadlineRemainingMs, na as withIndeterminateGuard, no as parseWebACLArn, oa as ec2InstanceProtectionSite, ot as listNestedTemplateRows, p as planStreamMemberOps, pc as passedNoEchoParametersOf, pt as enclosingDeadlineExpired, q as isTruthyCfnBoolean, qu as canonicalizeRegion, ra as isWaitAbandonedError, sa as isTerminationProtectionPropagationError, sd as describeFileReadFailure, ss as refuseMalformedResourcesForDestroy, st as renderNestedTemplateTreeDefect, t as DeployEngine, ta as deleteSkipReason, tc as sameLambdaFunctionAddress, ti as secretNamedAttributeNamesOf, u as STREAM_TAGS_KEY, ua as reEnableInstanceApiTermination, ud as resolveAssemblyPath, v as streamPolicyMatchesDeclared, va as s3BucketDualStackDomainName, vi as acquireIdempotencyToken, w as planIndexContributorInsightsOps, wi as DBPROXY_TAGS_WHAT, wr as getStackRecords, x as contributorInsightsRefusals, xc as recordReferenceProvenanceEntry, xs as findSilentDropProperties, y as streamTagsMatchDeclared, ya as s3BucketRegionalDomainName, yc as markSameGenerationBag, ys as withheldAccountClause, z as relayedIndexBusyDelete, zc as withoutPhysicalNameCopies, zs as configBooleanRefusal, zt as withNestedStackContext } from "./deploy-engine-DSpxEUjC.js";
6
- import { n as collectInlinePolicyNamesManagedBySiblings, r as IamCreateClientCache, t as IAMRoleProvider } from "./iam-role-provider--eWrOXce.js";
7
- import { a as resolveSecretDerivedPrincipals, i as isResolvableSecretPrincipalList, n as runDestroyForStack, o as canonicalizeIpProtocolValue, r as holdsUnprovenSecretPrincipalToken, s as resolvedResourceTimeoutMs, t as canonicalizeIpv4Cidr } from "./program-DOPic-aS.js";
8
- import { t as modifyDbInstanceWhenAvailable } from "./db-instance-modify-retry-DOJPkECL.js";
9
- import { RDSProvider } from "./rds-provider-BPs9JSk_.js";
10
- import { NeptuneProvider } from "./neptune-provider-p59T8CFv.js";
11
- import { ASGProvider } from "./asg-provider-CsRMe_zh.js";
5
+ import { $c as recordAttributeIdCopy, $s as blockDeviceMappingsDifferOnlyInDeleteOnTermination, $t as lookupEachName, A as beginDeleteWait, Ai as refuseMalformedDesiredTags, An as REDACTED_DELETE_ADDRESS_SKIP_REASON, B as waitForIndexesSettled, Bi as waitForLambdaFunctionActive, Bl as timePhase, Bs as coerceCfnInteger, Bt as getCurrentNestedStackContext, C as planContributorInsightsOp, Cc as redactForState, Cs as findSilentDropProperties, D as reverseMapTableContributorInsights, Da as outputReferenceProvenanceOf, Di as DBPROXY_TAG_OPTIONS, E as reverseMapIndexContributorInsights, Ei as DBPROXY_TAGS_WHAT, Er as getStackRecords, F as DELETE_INDEX_WAIT_PROCEED_NOTE, Fs as coerceWarmThroughput$1, G as sendTtlWaitingOutRateLimit, Gs as replayWarn, H as isTtlRateLimited, Hc as withoutPhysicalNameCopies, Hs as configIntegerRefusal, I as INDEX_SETTLE_POLL_INTERVAL_MS, Is as isWarmThroughputDecrease, It as revertNestedChildFromJournal, J as hasCdkAutoDeleteTag, Jl as rewriteTemplateAssetReferences, Js as requireConfigString, K as ECR_AUTO_DELETE_IMAGES_TAG, Ks as requireConfigArray, L as deleteTableWithIndexBusyRetry, Ls as toCfnInteger, M as deleteBudgetKey, Mi as tagPlanWarning, Mn as redactedDeleteAddressFields, N as resolveDynamoDbDeleteBudgetClock, Ni as definedAttributes, Nn as redactedDeleteAddressSkip, Nt as getNestedRevertRun, O as stripIndexContributorInsights, Oc as hasMaskableValues, Oi as planTagDiff, On as getCurrentProducerRegions, Or as replacedDeleteFailureVerdict, P as resolveDynamoDbDeleteBudgetMs, Pi as stringifyIfAssigned, Ps as WARM_THROUGHPUT_MEMBERS, Qc as physicalNameCopiesOf, Qi as unchangedBehindSecretReference, Qs as withRetry, Qt as isAccessDeniedError, R as maskedLogger, Rs as toFiniteNumber, S as indexDeclaresContributorInsights, Sa as s3BucketWebsiteUrl, Sc as markSameGenerationBag, T as readContributorInsightsSpec, Tc as snapshotPassProvenance, Ti as markDeleteStarted, Ts as withoutSilentDropProperties, U as planTimeToLive, Ul as stringifyValue, Uo as refuseMalformedNestedChildOutputs, Us as configStringRefusal, V as isTtlAlreadyDisabled, Vs as configBooleanRefusal, Vt as withNestedStackContext, W as readTtlSpec, Wc as dynamicReferenceTokens, Wi as getCurrentResourceSecrets, Ws as readConfigString, X as getPriorAttempts, Xi as slowCcOperationTimeoutMs, Xu as canonicalizeRegion, Y as isTruthyCfnBoolean, Z as markRefusedBeforeApplying, Zc as recoverMaskedOutput, Zi as onlySecretReferencesDiffer, Zt as chunks, Zu as derivePartitionAndUrlSuffix, _ as streamMemberRefusals, _a as isSettledInstanceState, aa as isWaitAbandonedError, b as CONTRIBUTOR_INSIGHTS_KEY, ba as s3BucketDualStackDomainName, bi as acquireIdempotencyToken, c as DynamoDBGlobalTableProvider, ca as ec2InstanceProtectionSite, ct as listNestedTemplateRows, d as declaredStreamPolicyMember, da as reDisableInstanceApiTermination, dd as displayAssemblyPath, ec as ecsServiceLaunchTypeSetOrChanged, en as withApiLimit, f as declaredStreamTagsMember, fa as reEnableInstanceApiTermination, fd as renderAssemblyPathEscape, g as streamDeclaresTags, gc as passedNoEchoParametersOf, gi as earliestDefined, gt as enclosingDeadlineRemainingMs, h as streamDeclaresPolicy, ht as enclosingDeadlineExpired, ia as withIndeterminateGuard, ic as sameLambdaFunctionAddress, io as parseWebACLArn, j as compensateRemovedDeletionProtection, ji as tagMapAsList, jn as isRedactedRecordedValue, k as DYNAMODB_DELETE_MIN_RESOURCE_TIMEOUT_MS, ki as readTagList, l as STREAM_POLICY_KEY, la as isTerminationProtectionPropagationError, ls as refuseMalformedResourcesForDestroy, lt as renderNestedTemplateTreeDefect, m as reverseMapStreamPolicy, mo as accountArgs, nc as canonicalLambdaFunctionName, nl as carriesSecretMask, oa as markWaitAbandoned, ot as findNestedTemplateTreeDefect, p as planStreamMemberOps, pd as resolveAssemblyPath, q as S3_AUTO_DELETE_OBJECTS_TAG, qa as getAccountInfo, qs as requireConfigObject, qu as decodeListingKey, ra as deleteSkipReason, rc as lambdaFunctionNameForMask, ri as secretNamedAttributeNamesOf, so as passedParameterClassesOf, st as isAbsoluteAssetPath, t as DeployEngine, tc as emrClusterInstancesReplaced, u as STREAM_TAGS_KEY, ua as observeThenDisableInstanceApiTermination, ud as describeFileReadFailure, v as streamPolicyMatchesDeclared, va as s3BucketArn, vi as reserveStackCreateToken, w as planIndexContributorInsightsOps, wc as recordReferenceProvenanceEntry, wi as isRefusedByName, wr as awaitInFlightSibling, x as contributorInsightsRefusals, xa as s3BucketRegionalDomainName, xs as withheldAccountClause, y as streamTagsMatchDeclared, ya as s3BucketDomainName, z as relayedIndexBusyDelete, zs as coerceCfnBoolean } from "./deploy-engine-CDjAtIrn.js";
6
+ import { n as collectInlinePolicyNamesManagedBySiblings, r as IamCreateClientCache, t as IAMRoleProvider } from "./iam-role-provider-DbtvFel_.js";
7
+ import { a as resolveSecretDerivedPrincipals, i as isResolvableSecretPrincipalList, n as runDestroyForStack, o as canonicalizeIpProtocolValue, r as holdsUnprovenSecretPrincipalToken, s as resolvedResourceTimeoutMs, t as canonicalizeIpv4Cidr } from "./program-Ymf7svYk.js";
8
+ import { t as modifyDbInstanceWhenAvailable } from "./db-instance-modify-retry-BUG7NMWS.js";
9
+ import { RDSProvider } from "./rds-provider-CZhBLQgJ.js";
10
+ import { NeptuneProvider } from "./neptune-provider-Y3Ii8oYI.js";
11
+ import { ASGProvider } from "./asg-provider-B7pAjRIc.js";
12
12
  import { createHash, randomUUID } from "node:crypto";
13
13
  import { 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, ListBucketsCommand, ListObjectVersionsCommand, ListObjectsV2Command, NoSuchBucket, PutBucketAccelerateConfigurationCommand, PutBucketAnalyticsConfigurationCommand, PutBucketCorsCommand, PutBucketEncryptionCommand, PutBucketIntelligentTieringConfigurationCommand, PutBucketInventoryConfigurationCommand, PutBucketLifecycleConfigurationCommand, PutBucketLoggingCommand, PutBucketMetricsConfigurationCommand, PutBucketNotificationConfigurationCommand, PutBucketOwnershipControlsCommand, PutBucketPolicyCommand, PutBucketReplicationCommand, PutBucketTaggingCommand, PutBucketVersioningCommand, PutBucketWebsiteCommand, PutObjectLockConfigurationCommand, PutPublicAccessBlockCommand, S3Client } from "@aws-sdk/client-s3";
14
14
  import { AddRoleToInstanceProfileCommand, AddUserToGroupCommand, AttachGroupPolicyCommand, AttachRolePolicyCommand, AttachUserPolicyCommand, CreateAccessKeyCommand, CreateGroupCommand, CreateInstanceProfileCommand, CreateLoginProfileCommand, CreatePolicyCommand, CreatePolicyVersionCommand, CreateUserCommand, DeleteAccessKeyCommand, DeleteGroupCommand, DeleteGroupPolicyCommand, DeleteInstanceProfileCommand, DeleteLoginProfileCommand, DeletePolicyCommand, DeletePolicyVersionCommand, DeleteRolePolicyCommand, DeleteUserCommand, DeleteUserPermissionsBoundaryCommand, DeleteUserPolicyCommand, DetachGroupPolicyCommand, DetachRolePolicyCommand, DetachUserPolicyCommand, GetAccessKeyLastUsedCommand, GetGroupCommand, GetGroupPolicyCommand, GetInstanceProfileCommand, GetPolicyCommand, GetPolicyVersionCommand, GetRolePolicyCommand, GetUserCommand, GetUserPolicyCommand, IAMClient, ListAccessKeysCommand, ListAttachedGroupPoliciesCommand, ListAttachedUserPoliciesCommand, ListEntitiesForPolicyCommand, ListGroupPoliciesCommand, ListGroupsForUserCommand, ListPoliciesCommand, ListPolicyTagsCommand, ListPolicyVersionsCommand, ListUserPoliciesCommand, NoSuchEntityException, PutGroupPolicyCommand, PutRolePolicyCommand, PutUserPermissionsBoundaryCommand, PutUserPolicyCommand, RemoveRoleFromInstanceProfileCommand, RemoveUserFromGroupCommand, TagPolicyCommand, TagUserCommand, UntagPolicyCommand, UntagUserCommand, UpdateAccessKeyCommand, UpdateGroupCommand, UpdateLoginProfileCommand, UpdateUserCommand } from "@aws-sdk/client-iam";
@@ -16,7 +16,7 @@ import { CreateQueueCommand, DeleteQueueCommand, GetQueueAttributesCommand, GetQ
16
16
  import { CreateTopicCommand, DeleteTopicCommand, GetSubscriptionAttributesCommand, GetTopicAttributesCommand, InvalidParameterException, ListSubscriptionsByTopicCommand, ListTagsForResourceCommand, ListTopicsCommand, NotFoundException, SNSClient, SetSubscriptionAttributesCommand, SetTopicAttributesCommand, SubscribeCommand, TagResourceCommand, UnsubscribeCommand, UntagResourceCommand } from "@aws-sdk/client-sns";
17
17
  import { AddPermissionCommand, CreateEventSourceMappingCommand, CreateFunctionCommand, CreateFunctionUrlConfigCommand, DeleteEventSourceMappingCommand, DeleteFunctionCodeSigningConfigCommand, DeleteFunctionCommand, DeleteFunctionConcurrencyCommand, DeleteFunctionEventInvokeConfigCommand, DeleteFunctionUrlConfigCommand, DeleteLayerVersionCommand, GetEventSourceMappingCommand, GetFunctionCodeSigningConfigCommand, GetFunctionCommand, GetFunctionConcurrencyCommand, GetFunctionEventInvokeConfigCommand, GetFunctionRecursionConfigCommand, GetFunctionUrlConfigCommand, GetLayerVersionByArnCommand, GetPolicyCommand as GetPolicyCommand$1, GetRuntimeManagementConfigCommand, LambdaClient, ListEventSourceMappingsCommand, ListLayerVersionsCommand, ListTagsCommand, PublishLayerVersionCommand, PutFunctionCodeSigningConfigCommand, PutFunctionConcurrencyCommand, PutFunctionEventInvokeConfigCommand, PutFunctionRecursionConfigCommand, PutRuntimeManagementConfigCommand, RemovePermissionCommand, ResourceNotFoundException, TagResourceCommand as TagResourceCommand$1, UntagResourceCommand as UntagResourceCommand$1, UpdateEventSourceMappingCommand, UpdateFunctionCodeCommand, UpdateFunctionConfigurationCommand, UpdateFunctionUrlConfigCommand, waitUntilFunctionActiveV2, waitUntilFunctionUpdatedV2 } from "@aws-sdk/client-lambda";
18
18
  import { GetCallerIdentityCommand, STSClient } from "@aws-sdk/client-sts";
19
- import { AllocateAddressCommand, AssociateAddressCommand, AssociateIamInstanceProfileCommand, AssociateNatGatewayAddressCommand, AssociateRouteTableCommand, AttachInternetGatewayCommand, AttachVpnGatewayCommand, AuthorizeSecurityGroupEgressCommand, AuthorizeSecurityGroupIngressCommand, CreateInternetGatewayCommand, CreateNatGatewayCommand, CreateNetworkAclCommand, CreateNetworkAclEntryCommand, CreateRouteCommand, CreateRouteTableCommand, CreateSecurityGroupCommand, CreateSubnetCommand, CreateTagsCommand, CreateVpcCommand, DeleteInternetGatewayCommand, DeleteNatGatewayCommand, DeleteNetworkAclCommand, DeleteNetworkAclEntryCommand, DeleteNetworkInterfaceCommand, DeleteRouteCommand, DeleteRouteTableCommand, DeleteSecurityGroupCommand, DeleteSubnetCommand, DeleteTagsCommand, DeleteVpcCommand, DescribeAddressesCommand, DescribeAvailabilityZonesCommand, DescribeIamInstanceProfileAssociationsCommand, DescribeInstanceAttributeCommand, DescribeInstanceCreditSpecificationsCommand, DescribeInstancesCommand, DescribeInternetGatewaysCommand, DescribeNatGatewaysCommand, DescribeNetworkAclsCommand, DescribeNetworkInterfacesCommand, DescribeRouteTablesCommand, DescribeSecurityGroupRulesCommand, DescribeSecurityGroupsCommand, DescribeSubnetsCommand, DescribeVolumesCommand, DescribeVpcAttributeCommand, DescribeVpcsCommand, DescribeVpnGatewaysCommand, DetachInternetGatewayCommand, DetachVpnGatewayCommand, DisassociateAddressCommand, DisassociateNatGatewayAddressCommand, DisassociateRouteTableCommand, EC2Client, ModifyInstanceAttributeCommand, ModifyInstanceCreditSpecificationCommand, ModifyInstanceMetadataOptionsCommand, ModifySubnetAttributeCommand, ModifyVpcAttributeCommand, MonitorInstancesCommand, ReleaseAddressCommand, ReplaceNetworkAclAssociationCommand, ReplaceNetworkAclEntryCommand, ReplaceRouteCommand, RevokeSecurityGroupEgressCommand, RevokeSecurityGroupIngressCommand, RunInstancesCommand, TerminateInstancesCommand, UnmonitorInstancesCommand, waitUntilInstanceRunning, waitUntilInstanceTerminated, waitUntilNatGatewayAvailable, waitUntilNatGatewayDeleted } from "@aws-sdk/client-ec2";
19
+ import { AllocateAddressCommand, AssociateAddressCommand, AssociateIamInstanceProfileCommand, AssociateNatGatewayAddressCommand, AssociateRouteTableCommand, AttachInternetGatewayCommand, AttachVpnGatewayCommand, AuthorizeSecurityGroupEgressCommand, AuthorizeSecurityGroupIngressCommand, CreateInternetGatewayCommand, CreateNatGatewayCommand, CreateNetworkAclCommand, CreateNetworkAclEntryCommand, CreateRouteCommand, CreateRouteTableCommand, CreateSecurityGroupCommand, CreateSubnetCommand, CreateTagsCommand, CreateVpcCommand, DeleteInternetGatewayCommand, DeleteNatGatewayCommand, DeleteNetworkAclCommand, DeleteNetworkAclEntryCommand, DeleteNetworkInterfaceCommand, DeleteRouteCommand, DeleteRouteTableCommand, DeleteSecurityGroupCommand, DeleteSubnetCommand, DeleteTagsCommand, DeleteVpcCommand, DescribeAddressesCommand, DescribeAvailabilityZonesCommand, DescribeIamInstanceProfileAssociationsCommand, DescribeInstanceAttributeCommand, DescribeInstanceCreditSpecificationsCommand, DescribeInstancesCommand, DescribeInternetGatewaysCommand, DescribeNatGatewaysCommand, DescribeNetworkAclsCommand, DescribeNetworkInterfacesCommand, DescribeRouteTablesCommand, DescribeSecurityGroupRulesCommand, DescribeSecurityGroupsCommand, DescribeSubnetsCommand, DescribeVolumesCommand, DescribeVpcAttributeCommand, DescribeVpcsCommand, DescribeVpnGatewaysCommand, DetachInternetGatewayCommand, DetachVpnGatewayCommand, DisassociateAddressCommand, DisassociateIamInstanceProfileCommand, DisassociateNatGatewayAddressCommand, DisassociateRouteTableCommand, EC2Client, ModifyInstanceAttributeCommand, ModifyInstanceCreditSpecificationCommand, ModifyInstanceMetadataOptionsCommand, ModifySubnetAttributeCommand, ModifyVpcAttributeCommand, ModifyVpcTenancyCommand, MonitorInstancesCommand, ReleaseAddressCommand, ReplaceIamInstanceProfileAssociationCommand, ReplaceNetworkAclAssociationCommand, ReplaceNetworkAclEntryCommand, ReplaceRouteCommand, RevokeSecurityGroupEgressCommand, RevokeSecurityGroupIngressCommand, RunInstancesCommand, StartInstancesCommand, StopInstancesCommand, TerminateInstancesCommand, UnmonitorInstancesCommand, waitUntilInstanceRunning, waitUntilInstanceTerminated, waitUntilNatGatewayAvailable, waitUntilNatGatewayDeleted } from "@aws-sdk/client-ec2";
20
20
  import { CreateTableCommand, DeleteResourcePolicyCommand, DeleteTableCommand, DescribeContinuousBackupsCommand, DescribeContributorInsightsCommand, DescribeKinesisStreamingDestinationCommand, DescribeTableCommand, DescribeTimeToLiveCommand, DisableKinesisStreamingDestinationCommand, DynamoDBClient, EnableKinesisStreamingDestinationCommand, GetResourcePolicyCommand, ListTagsOfResourceCommand, PolicyNotFoundException, PutResourcePolicyCommand, ResourceNotFoundException as ResourceNotFoundException$1, TagResourceCommand as TagResourceCommand$2, UntagResourceCommand as UntagResourceCommand$2, UpdateContinuousBackupsCommand, UpdateContributorInsightsCommand, UpdateKinesisStreamingDestinationCommand, UpdateTableCommand, UpdateTimeToLiveCommand } from "@aws-sdk/client-dynamodb";
21
21
  import { APIGatewayClient, CreateAuthorizerCommand, CreateDeploymentCommand, CreateResourceCommand, CreateStageCommand, DeleteAuthorizerCommand, DeleteDeploymentCommand, DeleteIntegrationCommand, DeleteIntegrationResponseCommand, DeleteMethodCommand, DeleteMethodResponseCommand, DeleteResourceCommand, DeleteStageCommand, GetAccountCommand, GetAuthorizerCommand, GetAuthorizersCommand, GetDeploymentCommand, GetDeploymentsCommand, GetMethodCommand, GetResourceCommand, GetStageCommand, NotFoundException as NotFoundException$1, PutIntegrationCommand, PutIntegrationResponseCommand, PutMethodCommand, PutMethodResponseCommand, TagResourceCommand as TagResourceCommand$3, UntagResourceCommand as UntagResourceCommand$3, UpdateAccountCommand, UpdateAuthorizerCommand, UpdateDeploymentCommand, UpdateMethodCommand, UpdateStageCommand } from "@aws-sdk/client-api-gateway";
22
22
  import { CreateEventBusCommand, DeleteEventBusCommand, DeleteRuleCommand, DescribeEventBusCommand, DescribeRuleCommand, EventBridgeClient, ListRulesCommand, ListTagsForResourceCommand as ListTagsForResourceCommand$1, ListTargetsByRuleCommand, PutPermissionCommand, PutRuleCommand, PutTargetsCommand, RemoveTargetsCommand, ResourceNotFoundException as ResourceNotFoundException$2, TagResourceCommand as TagResourceCommand$4, UntagResourceCommand as UntagResourceCommand$4, UpdateEventBusCommand } from "@aws-sdk/client-eventbridge";
@@ -12228,7 +12228,8 @@ var DynamoDBTableProvider = class {
12228
12228
  await this.applyPointInTimeRecovery(tableName, properties["PointInTimeRecoverySpecification"], void 0, maskSecrets);
12229
12229
  await this.applyTimeToLive(tableName, properties["TimeToLiveSpecification"], void 0, "create", {
12230
12230
  logicalId,
12231
- resourceType
12231
+ resourceType,
12232
+ maskSecrets
12232
12233
  });
12233
12234
  await this.applyKinesisStreamingDestination(tableName, properties["KinesisStreamSpecification"], void 0, maskSecrets);
12234
12235
  await this.applyContributorInsights(tableName, properties["ContributorInsightsSpecification"], void 0, maskSecrets);
@@ -12526,7 +12527,8 @@ var DynamoDBTableProvider = class {
12526
12527
  this.assertNoActiveTtlAttributeNameChange(logicalId, resourceType, physicalId, properties["TimeToLiveSpecification"], previousProperties["TimeToLiveSpecification"]);
12527
12528
  await this.applyTimeToLive(physicalId, properties["TimeToLiveSpecification"], previousProperties["TimeToLiveSpecification"], "update", {
12528
12529
  logicalId,
12529
- resourceType
12530
+ resourceType,
12531
+ maskSecrets
12530
12532
  });
12531
12533
  }
12532
12534
  if (JSON.stringify(properties["ResourcePolicy"]) !== JSON.stringify(previousProperties["ResourcePolicy"])) {
@@ -12732,6 +12734,7 @@ var DynamoDBTableProvider = class {
12732
12734
  const retryLine = `Transient error on "${label}" (attempt ${attempt}/${maxAttempts}): ${msg} — retrying in ${delayMs}ms`;
12733
12735
  this.logger.debug(options.maskSecrets ? options.maskSecrets(retryLine) : retryLine);
12734
12736
  await new Promise((resolve) => setTimeout(resolve, delayMs));
12737
+ if (options.stopAtDeadline && enclosingDeadlineRemainingMs() <= 0) throw error;
12735
12738
  delayMs = Math.min(delayMs * 2, 3e4);
12736
12739
  }
12737
12740
  }
@@ -12746,10 +12749,10 @@ var DynamoDBTableProvider = class {
12746
12749
  let attributeName;
12747
12750
  if (plan.kind === "none") return;
12748
12751
  if (plan.kind === "disable-live") {
12749
- const live = (await this.retryOnTransientControlPlane(() => this.dynamoDBClient.send(new DescribeTimeToLiveCommand({ TableName: tableName })), `read TTL on ${tableName}`)).TimeToLiveDescription;
12752
+ const live = (await this.retryOnTransientControlPlane(() => this.dynamoDBClient.send(new DescribeTimeToLiveCommand({ TableName: tableName })), `read TTL on ${tableName}`, void 0, { maskSecrets: ids.maskSecrets })).TimeToLiveDescription;
12750
12753
  const status = live?.TimeToLiveStatus;
12751
12754
  if (status !== "ENABLED" && status !== "ENABLING" || !live?.AttributeName) {
12752
- this.logger.debug(`TimeToLive already ${status ?? "DISABLED"} on DynamoDB table ${tableName}; nothing to disable`);
12755
+ this.logger.debug(ids.maskSecrets(`TimeToLive already ${status ?? "DISABLED"} on DynamoDB table ${tableName}; nothing to disable`));
12753
12756
  return;
12754
12757
  }
12755
12758
  enabled = false;
@@ -12759,22 +12762,28 @@ var DynamoDBTableProvider = class {
12759
12762
  attributeName = plan.attributeName;
12760
12763
  }
12761
12764
  try {
12762
- await this.retryOnTransientControlPlane(() => this.dynamoDBClient.send(new UpdateTimeToLiveCommand({
12765
+ await sendTtlWaitingOutRateLimit(() => this.retryOnTransientControlPlane(() => this.dynamoDBClient.send(new UpdateTimeToLiveCommand({
12763
12766
  TableName: tableName,
12764
12767
  TimeToLiveSpecification: {
12765
12768
  Enabled: enabled,
12766
12769
  AttributeName: attributeName
12767
12770
  }
12768
- })), `${enabled ? "set" : "disable"} TTL on ${tableName}`);
12771
+ })), `${enabled ? "set" : "disable"} TTL on ${tableName}`, void 0, {
12772
+ maskSecrets: ids.maskSecrets,
12773
+ stopAtDeadline: true
12774
+ }), {
12775
+ what: ids.maskSecrets(`DynamoDB TimeToLive rate-limit wait on ${tableName}`),
12776
+ announce: () => this.logger.info(ids.maskSecrets(`DynamoDB table ${ids.logicalId}: TimeToLive was changed recently, and AWS refuses another change until its rate-limit interval passes (up to about an hour). Retrying every minute, like CloudFormation, within the resource timeout.`))
12777
+ });
12769
12778
  } catch (error) {
12770
12779
  if (!enabled && isTtlAlreadyDisabled(describeAwsFailure(error).detail)) {
12771
- this.logger.debug(`TimeToLive already disabled on DynamoDB table ${tableName}`);
12780
+ this.logger.debug(ids.maskSecrets(`TimeToLive already disabled on DynamoDB table ${tableName}`));
12772
12781
  return;
12773
12782
  }
12774
- if (describeAwsFailure(error).detail.includes("Time to live has been modified multiple times")) throw new ProvisioningError(`DynamoDB table ${ids.logicalId}: AWS refused to ${enabled ? "enable" : "disable"} TimeToLive because it was already modified within DynamoDB's rate-limit interval. Wait for the interval to pass (up to about an hour), then redeploy.`, ids.resourceType, ids.logicalId, tableName, error instanceof Error ? error : void 0);
12783
+ if (isTtlRateLimited(describeAwsFailure(error).detail)) throw new ProvisioningError(`DynamoDB table ${ids.logicalId}: AWS refused to ${enabled ? "enable" : "disable"} TimeToLive because it was already modified within DynamoDB's rate-limit interval, and kept refusing until the resource timeout ran out. Redeploy once the interval has passed (up to about an hour), or raise --resource-timeout.`, ids.resourceType, ids.logicalId, tableName, error instanceof Error ? error : void 0);
12775
12784
  throw error;
12776
12785
  }
12777
- this.logger.debug(`Set TimeToLive Enabled=${enabled} AttributeName=${attributeName} on DynamoDB table ${tableName}`);
12786
+ this.logger.debug(ids.maskSecrets(`Set TimeToLive Enabled=${enabled} AttributeName=${attributeName} on DynamoDB table ${tableName}`));
12778
12787
  }
12779
12788
  extractResourcePolicyDocument(spec) {
12780
12789
  if (spec === void 0 || spec === null) return void 0;
@@ -16131,6 +16140,46 @@ const EC2_VPC_GATEWAY_ATTACHMENT_ID_FORMAT = {
16131
16140
  segments: ["gatewayId", "vpcId"]
16132
16141
  };
16133
16142
  const VPN_GATEWAY_ATTACHMENT_WAIT_MS = 6e5;
16143
+ const INSTANCE_STATE_WAIT_CAP_MS = 9e5;
16144
+ const INSTANCE_STATE_POLL_MS = 5e3;
16145
+ const STOPPED_AFTER_START_READS = 3;
16146
+ const PROFILE_DISASSOCIATING_POLLS = 15;
16147
+ const PROFILE_DISASSOCIATING_DELAY_MS = 2e3;
16148
+ function refusedBeforeApplying(error) {
16149
+ return markRefusedBeforeApplying(markNonRetryable(error));
16150
+ }
16151
+ const STOPPABLE_INSTANCE_STATES = /* @__PURE__ */ new Set([
16152
+ "pending",
16153
+ "running",
16154
+ "stopping",
16155
+ "stopped"
16156
+ ]);
16157
+ const instancesLeftStoppedByCdkd = /* @__PURE__ */ new Set();
16158
+ const instanceStoppedAfterStart = /* @__PURE__ */ new WeakSet();
16159
+ function isRecordedStandIn$1(value) {
16160
+ if (Array.isArray(value)) return value.some(isRecordedStandIn$1);
16161
+ if (value !== null && typeof value === "object") return Object.values(value).some(isRecordedStandIn$1);
16162
+ return typeof value === "string" && (value === "***" || dynamicReferenceTokens(value).length > 0);
16163
+ }
16164
+ function instanceProfileKey(value) {
16165
+ const fromArn = (arn) => arn.slice(arn.lastIndexOf("/") + 1);
16166
+ if (typeof value === "string") {
16167
+ const v = value.trim();
16168
+ if (v === "") return void 0;
16169
+ return v.startsWith("arn:") ? fromArn(v) : v;
16170
+ }
16171
+ if (value !== null && typeof value === "object") {
16172
+ const obj = value;
16173
+ if (typeof obj["Name"] === "string" && obj["Name"] !== "") return obj["Name"];
16174
+ if (typeof obj["Arn"] === "string" && obj["Arn"] !== "") return fromArn(obj["Arn"]);
16175
+ }
16176
+ }
16177
+ function sameStringSet(a, b) {
16178
+ if (!Array.isArray(a) || !Array.isArray(b)) return a === b;
16179
+ const sa = new Set(a.map(String));
16180
+ const sb = new Set(b.map(String));
16181
+ return sa.size === sb.size && [...sa].every((x) => sb.has(x));
16182
+ }
16134
16183
  const VPN_DETACH_IN_PROGRESS_ERRORS = /* @__PURE__ */ new Set(["IncorrectState"]);
16135
16184
  const EC2_ROUTE_ID_FORMAT = {
16136
16185
  label: "Route",
@@ -16723,19 +16772,19 @@ var EC2Provider = class {
16723
16772
  switch (resourceType) {
16724
16773
  case "AWS::EC2::VPC": return this.updateVpc(logicalId, physicalId, resourceType, properties, previousProperties, context);
16725
16774
  case "AWS::EC2::Subnet": return this.updateSubnet(logicalId, physicalId, resourceType, properties, previousProperties, context);
16726
- case "AWS::EC2::InternetGateway": return this.updateInternetGateway(logicalId, physicalId);
16775
+ case "AWS::EC2::InternetGateway": return this.updateTagsOnly(logicalId, physicalId, resourceType, false, properties, previousProperties, context);
16727
16776
  case "AWS::EC2::EIP": return this.updateEip(logicalId, physicalId, resourceType, properties, previousProperties, context);
16728
16777
  case "AWS::EC2::VPCGatewayAttachment": return this.updateVpcGatewayAttachment(logicalId, physicalId, resourceType, properties, previousProperties, context);
16729
16778
  case "AWS::EC2::NatGateway": return this.updateNatGateway(logicalId, physicalId, resourceType, properties, previousProperties, context);
16730
- case "AWS::EC2::RouteTable": return this.updateRouteTable(logicalId, physicalId);
16779
+ case "AWS::EC2::RouteTable":
16780
+ case "AWS::EC2::NetworkAcl": return this.updateTagsOnly(logicalId, physicalId, resourceType, true, properties, previousProperties, context);
16731
16781
  case "AWS::EC2::Route": return this.updateRoute(logicalId, physicalId, resourceType, properties, previousProperties, context);
16732
16782
  case "AWS::EC2::SubnetRouteTableAssociation": return this.updateSubnetRouteTableAssociation(logicalId, physicalId);
16733
16783
  case "AWS::EC2::SecurityGroup": return this.updateSecurityGroup(logicalId, physicalId, resourceType, properties, previousProperties, context);
16734
16784
  case "AWS::EC2::SecurityGroupIngress": return this.updateSecurityGroupIngress(logicalId, physicalId, resourceType, properties, previousProperties, context?.maskSecrets, context?.replayingState === true, context?.recordedAttributes);
16735
16785
  case "AWS::EC2::Instance": return this.updateInstance(logicalId, physicalId, resourceType, properties, previousProperties, context);
16736
16786
  case "AWS::EC2::NetworkAclEntry": return this.updateNetworkAclEntry(logicalId, physicalId, resourceType, properties, previousProperties, context);
16737
- case "AWS::EC2::NetworkAcl":
16738
- case "AWS::EC2::SubnetNetworkAclAssociation": throw new ResourceUpdateNotSupportedError(resourceType, logicalId, "AWS provides no in-place Update API for this EC2 sub-resource type; every property change requires Delete + Create. Re-deploy with cdkd deploy --replace, or destroy + redeploy.");
16787
+ case "AWS::EC2::SubnetNetworkAclAssociation": throw new ResourceUpdateNotSupportedError(resourceType, logicalId, "AWS provides no in-place Update API for this EC2 sub-resource type; every property change requires Delete + Create. Re-deploy with cdkd deploy --replace, or destroy + redeploy");
16739
16788
  default: throw new ProvisioningError(`Unsupported resource type: ${resourceType}`, resourceType, logicalId, physicalId);
16740
16789
  }
16741
16790
  }
@@ -16976,6 +17025,10 @@ var EC2Provider = class {
16976
17025
  this.logger.debug(`Updating VPC ${logicalId}: ${physicalId}`);
16977
17026
  refuseMalformedDesiredTags(properties["Tags"], resourceType, logicalId, physicalId);
16978
17027
  try {
17028
+ const tenancyOf = (v) => v == null ? "default" : String(v);
17029
+ const newTenancy = tenancyOf(properties["InstanceTenancy"]);
17030
+ const oldTenancy = tenancyOf(previousProperties["InstanceTenancy"]);
17031
+ if (newTenancy !== oldTenancy && newTenancy !== "default") throw new ResourceUpdateNotSupportedError(resourceType, logicalId, "destroy + redeploy the VPC (and the resources that depend on it). AWS changes InstanceTenancy in place only to default, and CloudFormation creates a new VPC for this change");
16979
17032
  const asBool = (v) => {
16980
17033
  if (v === void 0) return void 0;
16981
17034
  return v === true || v === "true";
@@ -16992,6 +17045,10 @@ var EC2Provider = class {
16992
17045
  VpcId: physicalId,
16993
17046
  EnableDnsSupport: { Value: newDnsSupport }
16994
17047
  }));
17048
+ if (newTenancy !== oldTenancy) await this.ec2Client.send(new ModifyVpcTenancyCommand({
17049
+ VpcId: physicalId,
17050
+ InstanceTenancy: "default"
17051
+ }));
16995
17052
  await this.applyTagDiff(physicalId, resourceType, logicalId, previousProperties["Tags"], properties["Tags"], maskerOrIdentity(context?.maskSecrets));
16996
17053
  this.logger.debug(`Successfully updated VPC ${logicalId}`);
16997
17054
  return {
@@ -17003,6 +17060,7 @@ var EC2Provider = class {
17003
17060
  }
17004
17061
  };
17005
17062
  } catch (error) {
17063
+ if (error instanceof CdkdError) throw error;
17006
17064
  const cause = error instanceof Error ? error : void 0;
17007
17065
  throw this.wrapCaughtError(maskerOrIdentity(context?.maskSecrets), error, (text) => new ProvisioningError(`Failed to update VPC ${logicalId}: ${text}`, resourceType, logicalId, physicalId, cause));
17008
17066
  }
@@ -17272,8 +17330,20 @@ var EC2Provider = class {
17272
17330
  throw this.wrapCaughtError(maskerOrIdentity(context?.maskSecrets), error, (text) => new ProvisioningError(`Failed to create InternetGateway ${logicalId}: ${text}`, resourceType, logicalId, void 0, cause));
17273
17331
  }
17274
17332
  }
17275
- updateInternetGateway(logicalId, physicalId) {
17276
- return Promise.reject(new ResourceUpdateNotSupportedError("AWS::EC2::InternetGateway", logicalId, "destroy + redeploy the InternetGateway. IGW properties are immutable in AWS"));
17333
+ async updateTagsOnly(logicalId, physicalId, resourceType, vpcIdCreateOnly, properties, previousProperties, context) {
17334
+ const label = resourceType.slice(10);
17335
+ this.logger.debug(safeMsg`Updating ${label} ${logicalId}: ${physicalId}`);
17336
+ refuseMalformedDesiredTags(properties["Tags"], resourceType, logicalId, physicalId);
17337
+ if (vpcIdCreateOnly) {
17338
+ const next = properties["VpcId"];
17339
+ const prev = previousProperties["VpcId"];
17340
+ if (next !== void 0 && prev !== void 0 && next !== prev) throw new ResourceUpdateNotSupportedError(resourceType, logicalId, `destroy + redeploy the ${label} (and the resources that depend on it). VpcId is immutable in AWS`);
17341
+ }
17342
+ await this.applyTagDiff(physicalId, resourceType, logicalId, previousProperties["Tags"], properties["Tags"], maskerOrIdentity(context?.maskSecrets));
17343
+ return {
17344
+ physicalId,
17345
+ wasReplaced: false
17346
+ };
17277
17347
  }
17278
17348
  async deleteInternetGateway(logicalId, physicalId, resourceType, context) {
17279
17349
  this.logger.debug(`Deleting InternetGateway ${logicalId}: ${physicalId}`);
@@ -18019,9 +18089,6 @@ var EC2Provider = class {
18019
18089
  throw this.wrapCaughtError(maskerOrIdentity(context?.maskSecrets), error, (text) => new ProvisioningError(`Failed to create RouteTable ${logicalId}: ${text}`, resourceType, logicalId, void 0, cause));
18020
18090
  }
18021
18091
  }
18022
- updateRouteTable(logicalId, physicalId) {
18023
- return Promise.reject(new ResourceUpdateNotSupportedError("AWS::EC2::RouteTable", logicalId, "destroy + redeploy the RouteTable (and its associated Routes / SubnetRouteTableAssociations). VpcId is immutable."));
18024
- }
18025
18092
  async deleteRouteTable(logicalId, physicalId, resourceType, context) {
18026
18093
  this.logger.debug(`Deleting RouteTable ${logicalId}: ${physicalId}`);
18027
18094
  try {
@@ -18180,7 +18247,7 @@ var EC2Provider = class {
18180
18247
  }
18181
18248
  }
18182
18249
  updateSubnetRouteTableAssociation(logicalId, physicalId) {
18183
- return Promise.reject(new ResourceUpdateNotSupportedError("AWS::EC2::SubnetRouteTableAssociation", logicalId, "destroy + redeploy the association. (SubnetId, RouteTableId) is immutable."));
18250
+ return Promise.reject(new ResourceUpdateNotSupportedError("AWS::EC2::SubnetRouteTableAssociation", logicalId, "destroy + redeploy the association. (SubnetId, RouteTableId) is immutable"));
18184
18251
  }
18185
18252
  async deleteSubnetRouteTableAssociation(logicalId, physicalId, resourceType, context) {
18186
18253
  this.logger.debug(`Deleting SubnetRouteTableAssociation ${logicalId}: ${physicalId}`);
@@ -18902,9 +18969,12 @@ var EC2Provider = class {
18902
18969
  this.logger.debug(`Updating EC2 Instance ${logicalId}: ${physicalId}`);
18903
18970
  refuseMalformedDesiredTags(properties["Tags"], resourceType, logicalId, physicalId);
18904
18971
  this.guardTerminationProtectionRemoval(logicalId, physicalId, resourceType, properties, previousProperties, context);
18972
+ const memberPlan = this.planInstanceMemberUpdates(logicalId, physicalId, resourceType, properties, previousProperties, context);
18905
18973
  try {
18974
+ await this.prepareInstanceMemberUpdates(logicalId, physicalId, resourceType, memberPlan);
18906
18975
  await this.applyTagDiff(physicalId, resourceType, logicalId, previousProperties["Tags"], properties["Tags"], maskerOrIdentity(context?.maskSecrets));
18907
18976
  await this.updateInstanceSecurityProps(physicalId, properties, previousProperties);
18977
+ await this.applyInstanceMemberUpdates(logicalId, physicalId, resourceType, memberPlan);
18908
18978
  const instance = (await this.ec2Client.send(new DescribeInstancesCommand({ InstanceIds: [physicalId] }))).Reservations?.[0]?.Instances?.[0];
18909
18979
  return {
18910
18980
  physicalId,
@@ -18912,6 +18982,7 @@ var EC2Provider = class {
18912
18982
  attributes: describedInstanceAttributes(physicalId, instance)
18913
18983
  };
18914
18984
  } catch (error) {
18985
+ if (error instanceof CdkdError || isInterruptedWaitError(error)) throw error;
18915
18986
  const cause = error instanceof Error ? error : void 0;
18916
18987
  throw this.wrapCaughtError(maskerOrIdentity(context?.maskSecrets), error, (text) => new ProvisioningError(`Failed to update EC2 Instance ${logicalId}: ${text}`, resourceType, logicalId, physicalId, cause));
18917
18988
  }
@@ -18950,6 +19021,286 @@ var EC2Provider = class {
18950
19021
  CpuCredits: newCpuCredits
18951
19022
  }] }));
18952
19023
  }
19024
+ planInstanceMemberUpdates(logicalId, physicalId, resourceType, properties, previousProperties, context) {
19025
+ const plan = {};
19026
+ const removed = (key) => context?.removedProperties !== void 0 ? context.removedProperties.has(key) : previousProperties[key] !== void 0 && properties[key] === void 0;
19027
+ const changed = (key, same) => {
19028
+ const before = previousProperties[key];
19029
+ const after = properties[key];
19030
+ if (after === void 0 && !removed(key)) return false;
19031
+ if (context?.changedProperties !== void 0 && !context.changedProperties.has(key)) return false;
19032
+ if (isDeepStrictEqual(before, after)) {
19033
+ if (context?.replayingState === true && isRecordedStandIn$1(after)) this.logger.warn(safeMsg`${logicalId} (${resourceType}): both sides of the rollback record ${key} as a stand-in (an unresolved {{resolve:...}} reference or the redaction mask), so cdkd cannot tell whether it changed; the rollback leaves ${key} at its current AWS value.`);
19034
+ return false;
19035
+ }
19036
+ return !(!isRecordedStandIn$1(before) && !isRecordedStandIn$1(after) && same(before, after));
19037
+ };
19038
+ const standInSkips = (key) => {
19039
+ if (!isRecordedStandIn$1(properties[key])) return false;
19040
+ if (context?.replayingState === true) {
19041
+ this.logger.warn(safeMsg`${logicalId} (${resourceType}): the state being restored records ${key} as a stand-in (an unresolved {{resolve:...}} reference or the redaction mask), not a value cdkd can send; the rollback leaves ${key} at its current AWS value.`);
19042
+ return true;
19043
+ }
19044
+ throw refusedBeforeApplying(new ProvisioningError(`${logicalId} (${resourceType}): ${key} holds a recorded stand-in (an unresolved {{resolve:...}} reference or the redaction mask), not a value cdkd can send. The instance was not updated; deploy from the template so the value resolves.`, resourceType, logicalId, physicalId));
19045
+ };
19046
+ if (changed("InstanceType", (a, b) => a === b)) {
19047
+ if (properties["InstanceType"] === void 0) {
19048
+ if (context?.replayingState === true) this.logger.warn(safeMsg`${logicalId} (${resourceType}): the state being restored does not declare InstanceType; the rollback leaves the instance type at its current AWS value.`);
19049
+ else throw refusedBeforeApplying(new ProvisioningError(safeMsg`${logicalId} (${resourceType}): InstanceType was removed from the template, and CloudFormation fails that update for an existing instance. Keep it declared (set it to the instance's current type to leave it unchanged). The instance was not updated.`, resourceType, logicalId, physicalId));
19050
+ } else if (!standInSkips("InstanceType")) plan.instanceType = requireConfigString(properties["InstanceType"], "", "AWS::EC2::Instance InstanceType");
19051
+ }
19052
+ if (changed("UserData", (a, b) => a === b)) {
19053
+ const userData = properties["UserData"];
19054
+ if (userData === void 0) plan.userData = /* @__PURE__ */ new Uint8Array(0);
19055
+ else if (!standInSkips("UserData")) {
19056
+ if (typeof userData !== "string") throw refusedBeforeApplying(new ProvisioningError(`${logicalId} (${resourceType}): UserData must be a base64 string (Fn::Base64), got a ${Array.isArray(userData) ? "list" : typeof userData}. The instance was not updated.`, resourceType, logicalId, physicalId));
19057
+ plan.userData = new Uint8Array(Buffer.from(userData, "base64"));
19058
+ }
19059
+ }
19060
+ if (changed("IamInstanceProfile", (a, b) => instanceProfileKey(a) === instanceProfileKey(b))) {
19061
+ if (properties["IamInstanceProfile"] === void 0) plan.profile = { kind: "remove" };
19062
+ else if (!standInSkips("IamInstanceProfile")) {
19063
+ const desired = this.normalizeIamInstanceProfile(properties["IamInstanceProfile"]);
19064
+ if (desired === void 0) throw refusedBeforeApplying(new ProvisioningError(`${logicalId} (${resourceType}): IamInstanceProfile is neither a profile name, an ARN, nor an {Arn,Name} object. The instance was not updated.`, resourceType, logicalId, physicalId));
19065
+ plan.profile = {
19066
+ kind: "set",
19067
+ ...desired
19068
+ };
19069
+ }
19070
+ }
19071
+ if (changed("SecurityGroupIds", (a, b) => sameStringSet(a, b))) {
19072
+ const groups = properties["SecurityGroupIds"];
19073
+ if (groups === void 0) plan.securityGroups = { kind: "vpc-default" };
19074
+ else {
19075
+ const ids = Array.isArray(groups) ? groups : void 0;
19076
+ if (ids === void 0 || ids.length === 0 || !ids.every((g) => typeof g === "string" && g !== "")) throw refusedBeforeApplying(new ProvisioningError(`${logicalId} (${resourceType}): SecurityGroupIds must be a non-empty list of security group ids. The instance was not updated.`, resourceType, logicalId, physicalId));
19077
+ if (!standInSkips("SecurityGroupIds")) plan.securityGroups = {
19078
+ kind: "set",
19079
+ ids
19080
+ };
19081
+ }
19082
+ }
19083
+ const beforeBdm = previousProperties["BlockDeviceMappings"];
19084
+ const afterBdm = properties["BlockDeviceMappings"];
19085
+ if (afterBdm !== void 0 && (context?.changedProperties === void 0 || context.changedProperties.has("BlockDeviceMappings")) && blockDeviceMappingsDifferOnlyInDeleteOnTermination(beforeBdm, afterBdm)) {
19086
+ const flips = [];
19087
+ afterBdm.forEach((m, i) => {
19088
+ const before = beforeBdm[i];
19089
+ const read = (x) => {
19090
+ const ebs = x?.["Ebs"];
19091
+ if (ebs === void 0 || ebs === null) return void 0;
19092
+ return this.coerceBool(ebs["DeleteOnTermination"]) ?? true;
19093
+ };
19094
+ const want = read(m);
19095
+ if (want !== void 0 && want !== read(before) && typeof m["DeviceName"] === "string") flips.push({
19096
+ DeviceName: m["DeviceName"],
19097
+ DeleteOnTermination: want
19098
+ });
19099
+ });
19100
+ if (flips.length > 0) plan.deleteOnTermination = flips;
19101
+ }
19102
+ return plan;
19103
+ }
19104
+ async prepareInstanceMemberUpdates(logicalId, physicalId, resourceType, plan) {
19105
+ const needsStop = plan.instanceType !== void 0 || plan.userData !== void 0;
19106
+ const needsDefaultGroup = plan.securityGroups?.kind === "vpc-default";
19107
+ if (!needsStop && !needsDefaultGroup) return;
19108
+ const instance = (await this.ec2Client.send(new DescribeInstancesCommand({ InstanceIds: [physicalId] }))).Reservations?.[0]?.Instances?.[0];
19109
+ if (needsStop) {
19110
+ const members = [plan.instanceType !== void 0 ? "InstanceType" : "", plan.userData !== void 0 ? "UserData" : ""].filter(Boolean).join(" and ");
19111
+ if (instance?.RootDeviceType === "instance-store") throw markRefusedBeforeApplying(new ResourceUpdateNotSupportedError(resourceType, logicalId, `${members} can change only on a stopped instance, and an instance-store-backed instance cannot be stopped; CloudFormation replaces it. Re-deploy with cdkd deploy --replace.`));
19112
+ const state = instance?.State?.Name;
19113
+ if (!STOPPABLE_INSTANCE_STATES.has(state ?? "")) throw refusedBeforeApplying(new ProvisioningError(`${logicalId} (${resourceType}): instance ${physicalId} is ${state ?? "not returned by DescribeInstances"}, so its ${members} cannot be changed. The instance was not updated.`, resourceType, logicalId, physicalId));
19114
+ }
19115
+ if (needsDefaultGroup) plan.securityGroups = {
19116
+ kind: "set",
19117
+ ids: [await this.vpcDefaultSecurityGroupId(logicalId, physicalId, resourceType, instance?.VpcId)]
19118
+ };
19119
+ }
19120
+ async applyInstanceMemberUpdates(logicalId, physicalId, resourceType, plan) {
19121
+ const applied = [];
19122
+ if (plan.securityGroups?.kind === "set") {
19123
+ await this.ec2Client.send(new ModifyInstanceAttributeCommand({
19124
+ InstanceId: physicalId,
19125
+ Groups: plan.securityGroups.ids
19126
+ }));
19127
+ applied.push("the new SecurityGroupIds");
19128
+ }
19129
+ if (plan.profile !== void 0) {
19130
+ await this.applyInstanceProfileChange(logicalId, physicalId, plan.profile);
19131
+ applied.push(plan.profile.kind === "remove" ? "the IamInstanceProfile removed" : "the new IamInstanceProfile");
19132
+ }
19133
+ if (plan.deleteOnTermination !== void 0) {
19134
+ await this.ec2Client.send(new ModifyInstanceAttributeCommand({
19135
+ InstanceId: physicalId,
19136
+ BlockDeviceMappings: plan.deleteOnTermination.map((f) => ({
19137
+ DeviceName: f.DeviceName,
19138
+ Ebs: { DeleteOnTermination: f.DeleteOnTermination }
19139
+ }))
19140
+ }));
19141
+ applied.push("the new DeleteOnTermination");
19142
+ }
19143
+ if (plan.instanceType === void 0 && plan.userData === void 0) {
19144
+ if (instancesLeftStoppedByCdkd.has(physicalId)) {
19145
+ let state = await this.readInstanceState(physicalId);
19146
+ if (state === "stopping") state = await this.waitForInstanceState(logicalId, physicalId, resourceType, "stopped");
19147
+ if (state === "stopped") await this.ec2Client.send(new StartInstancesCommand({ InstanceIds: [physicalId] }));
19148
+ instancesLeftStoppedByCdkd.delete(physicalId);
19149
+ }
19150
+ return;
19151
+ }
19152
+ let state = await this.readInstanceState(physicalId);
19153
+ if (state === "pending") state = await this.waitForInstanceState(logicalId, physicalId, resourceType, "running");
19154
+ else if (state === "stopping") state = await this.waitForInstanceState(logicalId, physicalId, resourceType, "stopped");
19155
+ if (state !== "stopped" && state !== "running") throw markNonRetryable(new ProvisioningError(`${logicalId} (${resourceType}): instance ${physicalId} became ${state ?? "not returned by DescribeInstances"} during the update, so its InstanceType / UserData were not changed`, resourceType, logicalId, physicalId));
19156
+ const startAfter = state === "running" || instancesLeftStoppedByCdkd.has(physicalId);
19157
+ let phase = "stop";
19158
+ let stopIssued = false;
19159
+ try {
19160
+ if (state === "running") {
19161
+ this.logger.info(safeMsg`Stopping EC2 Instance ${logicalId} (${physicalId}) to change its ${plan.instanceType !== void 0 ? "InstanceType" : ""}${plan.instanceType !== void 0 && plan.userData !== void 0 ? " and " : ""}${plan.userData !== void 0 ? "UserData" : ""}; it is started again afterwards`);
19162
+ await this.ec2Client.send(new StopInstancesCommand({ InstanceIds: [physicalId] }));
19163
+ stopIssued = true;
19164
+ await this.waitForInstanceState(logicalId, physicalId, resourceType, "stopped");
19165
+ }
19166
+ phase = "modify";
19167
+ if (plan.instanceType !== void 0) {
19168
+ await this.ec2Client.send(new ModifyInstanceAttributeCommand({
19169
+ InstanceId: physicalId,
19170
+ InstanceType: { Value: plan.instanceType }
19171
+ }));
19172
+ applied.push("the new InstanceType");
19173
+ }
19174
+ if (plan.userData !== void 0) {
19175
+ await this.ec2Client.send(new ModifyInstanceAttributeCommand({
19176
+ InstanceId: physicalId,
19177
+ UserData: { Value: plan.userData }
19178
+ }));
19179
+ applied.push("the new UserData");
19180
+ }
19181
+ if (!startAfter) return;
19182
+ phase = "start";
19183
+ await this.ec2Client.send(new StartInstancesCommand({ InstanceIds: [physicalId] }));
19184
+ instancesLeftStoppedByCdkd.delete(physicalId);
19185
+ if (process.env["CDKD_NO_WAIT"] === "true") {
19186
+ this.logger.debug(safeMsg`Instance ${physicalId} started (skipping running-state wait per --no-wait)`);
19187
+ return;
19188
+ }
19189
+ phase = "wait";
19190
+ await this.waitForInstanceState(logicalId, physicalId, resourceType, "running", { stoppedIsTerminal: true });
19191
+ } catch (error) {
19192
+ const carries = applied.length === 0 ? "its previous settings" : `${applied.join(" and ")} already applied`;
19193
+ const startCommand = `aws ec2 start-instances --instance-ids ${physicalId}`;
19194
+ if (phase === "stop" && !stopIssued) throw error;
19195
+ if (phase === "wait") {
19196
+ if (instanceStoppedAfterStart.has(error)) {
19197
+ instancesLeftStoppedByCdkd.add(physicalId);
19198
+ this.logger.warn(safeMsg`${logicalId}: instance ${physicalId} stopped again right after cdkd started it, with ${carries}. Start it with: ${startCommand}`);
19199
+ }
19200
+ throw error;
19201
+ }
19202
+ if (!stopIssued && !startAfter) throw error;
19203
+ if (phase !== "start" && !isInterruptedWaitError(error) && !enclosingDeadlineExpired()) {
19204
+ let startFailure;
19205
+ try {
19206
+ await this.ec2Client.send(new StartInstancesCommand({ InstanceIds: [physicalId] }));
19207
+ } catch (e) {
19208
+ startFailure = e ?? /* @__PURE__ */ new Error("StartInstances failed");
19209
+ }
19210
+ if (startFailure === void 0) {
19211
+ instancesLeftStoppedByCdkd.delete(physicalId);
19212
+ this.logger.warn(safeMsg`${logicalId}: the InstanceType / UserData change failed after instance ${physicalId} was stopped; cdkd started it again, with ${carries}.`);
19213
+ } else {
19214
+ instancesLeftStoppedByCdkd.add(physicalId);
19215
+ this.logger.warn(safeMsg`${logicalId}: instance ${physicalId} was stopped for an InstanceType / UserData change that failed, and starting it again failed too (${describeAwsFailure(startFailure).summary}); it is stopped, with ${carries}. Start it with: ${startCommand}`);
19216
+ }
19217
+ throw error;
19218
+ }
19219
+ instancesLeftStoppedByCdkd.add(physicalId);
19220
+ this.logger.warn(phase === "stop" ? safeMsg`${logicalId}: instance ${physicalId} was being stopped for an InstanceType / UserData change that did not finish. Once it is stopped, start it with: ${startCommand}` : safeMsg`${logicalId}: instance ${physicalId} is stopped, with ${carries}; cdkd did not start it again. Start it with: ${startCommand}`);
19221
+ throw error;
19222
+ }
19223
+ }
19224
+ async readInstanceState(physicalId) {
19225
+ return (await this.ec2Client.send(new DescribeInstancesCommand({ InstanceIds: [physicalId] }))).Reservations?.[0]?.Instances?.[0]?.State?.Name;
19226
+ }
19227
+ async waitForInstanceState(logicalId, physicalId, resourceType, target, opts = {}) {
19228
+ const watch = startInterruptWatch(`EC2 Instance ${logicalId} ${target} wait`);
19229
+ const capAt = Date.now() + INSTANCE_STATE_WAIT_CAP_MS;
19230
+ let last;
19231
+ let stoppedReads = 0;
19232
+ try {
19233
+ for (;;) {
19234
+ if (watch.isInterrupted()) throw watch.onInterrupted();
19235
+ if (Math.min(enclosingDeadlineRemainingMs(), capAt - Date.now()) <= 0) throw markNonRetryable(new ProvisioningError(`${logicalId} (${resourceType}): timed out waiting for instance ${physicalId} to be ${target} (last state: ${last ?? "none reported"})`, resourceType, logicalId, physicalId));
19236
+ const previous = last;
19237
+ last = await this.readInstanceState(physicalId);
19238
+ if (last === target) return last;
19239
+ stoppedReads = last === "stopped" ? stoppedReads + 1 : 0;
19240
+ if (opts.stoppedIsTerminal === true && last === "stopped" && (previous === "pending" || stoppedReads >= STOPPED_AFTER_START_READS)) {
19241
+ const stopped = markNonRetryable(new ProvisioningError(`${logicalId} (${resourceType}): instance ${physicalId} stopped again right after it was started; run \`aws ec2 describe-instances --instance-ids ${physicalId}\` and read StateReason for AWS's cause`, resourceType, logicalId, physicalId));
19242
+ instanceStoppedAfterStart.add(stopped);
19243
+ throw stopped;
19244
+ }
19245
+ if (last === "terminated" || last === "shutting-down" || last === void 0) throw markNonRetryable(new ProvisioningError(`${logicalId} (${resourceType}): instance ${physicalId} is ${last ?? "no longer returned by DescribeInstances"} while cdkd waited for it to be ${target}`, resourceType, logicalId, physicalId));
19246
+ if (watch.isInterrupted()) throw watch.onInterrupted();
19247
+ await this.sleep(Math.max(0, Math.min(INSTANCE_STATE_POLL_MS, enclosingDeadlineRemainingMs())));
19248
+ }
19249
+ } finally {
19250
+ watch.dispose();
19251
+ }
19252
+ }
19253
+ async vpcDefaultSecurityGroupId(logicalId, physicalId, resourceType, vpcId) {
19254
+ const id = (vpcId === void 0 ? void 0 : await this.ec2Client.send(new DescribeSecurityGroupsCommand({ Filters: [{
19255
+ Name: "vpc-id",
19256
+ Values: [vpcId]
19257
+ }, {
19258
+ Name: "group-name",
19259
+ Values: ["default"]
19260
+ }] })))?.SecurityGroups?.[0]?.GroupId;
19261
+ if (id === void 0) throw refusedBeforeApplying(new ProvisioningError(`${logicalId} (${resourceType}): SecurityGroupIds was removed, and the default security group of instance ${physicalId}'s VPC (${vpcId ?? "unknown"}) could not be found to put in its place. The instance was not updated.`, resourceType, logicalId, physicalId));
19262
+ return id;
19263
+ }
19264
+ async applyInstanceProfileChange(logicalId, physicalId, change) {
19265
+ let assoc = await this.ec2Client.send(new DescribeIamInstanceProfileAssociationsCommand({ Filters: [{
19266
+ Name: "instance-id",
19267
+ Values: [physicalId]
19268
+ }] }));
19269
+ for (let poll = 1; poll <= PROFILE_DISASSOCIATING_POLLS && (assoc.IamInstanceProfileAssociations ?? []).some((a) => a.State === "disassociating"); poll++) {
19270
+ await this.sleep(PROFILE_DISASSOCIATING_DELAY_MS);
19271
+ assoc = await this.ec2Client.send(new DescribeIamInstanceProfileAssociationsCommand({ Filters: [{
19272
+ Name: "instance-id",
19273
+ Values: [physicalId]
19274
+ }] }));
19275
+ }
19276
+ const current = assoc.IamInstanceProfileAssociations?.find((a) => a.State === "associated" || a.State === "associating");
19277
+ if (change.kind === "remove") {
19278
+ if (current?.AssociationId === void 0) return;
19279
+ await this.ec2Client.send(new DisassociateIamInstanceProfileCommand({ AssociationId: current.AssociationId }));
19280
+ return;
19281
+ }
19282
+ const spec = change.arn !== void 0 ? { Arn: change.arn } : { Name: change.name };
19283
+ const maxAttempts = 10;
19284
+ for (let attempt = 1;; attempt++) try {
19285
+ if (current?.AssociationId !== void 0) await this.ec2Client.send(new ReplaceIamInstanceProfileAssociationCommand({
19286
+ AssociationId: current.AssociationId,
19287
+ IamInstanceProfile: spec
19288
+ }));
19289
+ else await this.ec2Client.send(new AssociateIamInstanceProfileCommand({
19290
+ InstanceId: physicalId,
19291
+ IamInstanceProfile: spec
19292
+ }));
19293
+ return;
19294
+ } catch (error) {
19295
+ const msg = describeAwsFailure(error).detail;
19296
+ if (this.isInstanceProfilePropagationError(msg) && attempt < maxAttempts) {
19297
+ this.logger.debug(safeMsg`IAM instance profile not yet propagated for ${logicalId} (${physicalId}) (attempt ${attempt}/${maxAttempts}: ${msg}), retrying in ${attempt}s...`);
19298
+ await this.sleep(attempt * 1e3);
19299
+ continue;
19300
+ }
19301
+ throw error;
19302
+ }
19303
+ }
18953
19304
  shallowEqual(a, b) {
18954
19305
  if (b === void 0) return false;
18955
19306
  const ra = a;
@@ -19364,7 +19715,7 @@ var EC2Provider = class {
19364
19715
  const egress = properties["Egress"] ?? false;
19365
19716
  const parts = physicalId.split("|");
19366
19717
  if (parts.length !== 3) throw new ProvisioningError(compositeIdFormatMessage(EC2_NETWORK_ACL_ENTRY_ID_FORMAT, logicalId, physicalId), resourceType, logicalId, physicalId);
19367
- if (typeof networkAclId !== "string" || ruleNumber === void 0 || parts[0] !== networkAclId || parts[1] !== String(ruleNumber) || parts[2] !== String(egress)) throw new ResourceUpdateNotSupportedError(resourceType, logicalId, "NetworkAclId, RuleNumber and Egress identify the entry and are createOnly; a change to any of them requires a new entry. Re-deploy with cdkd deploy --replace, or destroy + redeploy.");
19718
+ if (typeof networkAclId !== "string" || ruleNumber === void 0 || parts[0] !== networkAclId || parts[1] !== String(ruleNumber) || parts[2] !== String(egress)) throw new ResourceUpdateNotSupportedError(resourceType, logicalId, "NetworkAclId, RuleNumber and Egress identify the entry and are createOnly; a change to any of them requires a new entry. Re-deploy with cdkd deploy --replace, or destroy + redeploy");
19368
19719
  if (properties["Protocol"] == null || !properties["RuleAction"]) throw new ProvisioningError(`Protocol and RuleAction are required for NetworkAclEntry ${logicalId}`, resourceType, logicalId, physicalId);
19369
19720
  const ruleParams = networkAclEntryRuleParams(properties, properties["Icmp"] !== void 0 && properties["IcmpTypeCode"] !== void 0 && JSON.stringify(properties["Icmp"]) === JSON.stringify(previousProperties["Icmp"]) && JSON.stringify(properties["IcmpTypeCode"]) !== JSON.stringify(previousProperties["IcmpTypeCode"]));
19370
19721
  if (context?.desiredFromAwsReadback === true && ruleParams.CidrBlock !== void 0 && ruleParams.Ipv6CidrBlock !== void 0) {
@@ -24558,6 +24909,8 @@ function camelToPascalCaseKeys(value, preserveKeys) {
24558
24909
 
24559
24910
  //#endregion
24560
24911
  //#region src/provisioning/providers/agentcore-runtime-provider.ts
24912
+ const CFN_MAP_KEYS = /* @__PURE__ */ new Set(["Tags", "AdvertisedScopeMapping"]);
24913
+ const SDK_MAP_KEYS = /* @__PURE__ */ new Set(["tags", "advertisedScopeMapping"]);
24561
24914
  var AgentCoreRuntimeProvider = class {
24562
24915
  client;
24563
24916
  logger = getLogger().child("AgentCoreRuntimeProvider");
@@ -24595,16 +24948,16 @@ var AgentCoreRuntimeProvider = class {
24595
24948
  agentRuntimeName,
24596
24949
  roleArn
24597
24950
  };
24598
- if (properties["AgentRuntimeArtifact"] !== void 0) input["agentRuntimeArtifact"] = pascalToCamelCaseKeys(properties["AgentRuntimeArtifact"]);
24599
- if (properties["NetworkConfiguration"] !== void 0) input["networkConfiguration"] = pascalToCamelCaseKeys(properties["NetworkConfiguration"]);
24951
+ if (properties["AgentRuntimeArtifact"] !== void 0) input["agentRuntimeArtifact"] = pascalToCamelCaseKeys(properties["AgentRuntimeArtifact"], CFN_MAP_KEYS);
24952
+ if (properties["NetworkConfiguration"] !== void 0) input["networkConfiguration"] = pascalToCamelCaseKeys(properties["NetworkConfiguration"], CFN_MAP_KEYS);
24600
24953
  if (properties["Description"] !== void 0) input["description"] = properties["Description"];
24601
- if (properties["AuthorizerConfiguration"] !== void 0) input["authorizerConfiguration"] = pascalToCamelCaseKeys(properties["AuthorizerConfiguration"]);
24954
+ if (properties["AuthorizerConfiguration"] !== void 0) input["authorizerConfiguration"] = pascalToCamelCaseKeys(properties["AuthorizerConfiguration"], CFN_MAP_KEYS);
24602
24955
  if (properties["ProtocolConfiguration"] !== void 0) {
24603
24956
  const proto = properties["ProtocolConfiguration"];
24604
24957
  if (typeof proto === "string") input["protocolConfiguration"] = { serverProtocol: proto };
24605
- else input["protocolConfiguration"] = pascalToCamelCaseKeys(proto);
24958
+ else input["protocolConfiguration"] = pascalToCamelCaseKeys(proto, CFN_MAP_KEYS);
24606
24959
  }
24607
- if (properties["LifecycleConfiguration"] !== void 0 && typeof properties["LifecycleConfiguration"] === "object" && properties["LifecycleConfiguration"] !== null && Object.keys(properties["LifecycleConfiguration"]).length > 0) input["lifecycleConfiguration"] = pascalToCamelCaseKeys(properties["LifecycleConfiguration"]);
24960
+ if (properties["LifecycleConfiguration"] !== void 0 && typeof properties["LifecycleConfiguration"] === "object" && properties["LifecycleConfiguration"] !== null && Object.keys(properties["LifecycleConfiguration"]).length > 0) input["lifecycleConfiguration"] = pascalToCamelCaseKeys(properties["LifecycleConfiguration"], CFN_MAP_KEYS);
24608
24961
  if (properties["EnvironmentVariables"] !== void 0) input["environmentVariables"] = properties["EnvironmentVariables"];
24609
24962
  if (properties["ClientToken"] !== void 0) input["clientToken"] = properties["ClientToken"];
24610
24963
  const response = await this.client.send(new CreateAgentRuntimeCommand(input));
@@ -24630,16 +24983,16 @@ var AgentCoreRuntimeProvider = class {
24630
24983
  agentRuntimeId: physicalId,
24631
24984
  roleArn
24632
24985
  };
24633
- if (properties["AgentRuntimeArtifact"] !== void 0) input["agentRuntimeArtifact"] = pascalToCamelCaseKeys(properties["AgentRuntimeArtifact"]);
24634
- if (properties["NetworkConfiguration"] !== void 0) input["networkConfiguration"] = pascalToCamelCaseKeys(properties["NetworkConfiguration"]);
24986
+ if (properties["AgentRuntimeArtifact"] !== void 0) input["agentRuntimeArtifact"] = pascalToCamelCaseKeys(properties["AgentRuntimeArtifact"], CFN_MAP_KEYS);
24987
+ if (properties["NetworkConfiguration"] !== void 0) input["networkConfiguration"] = pascalToCamelCaseKeys(properties["NetworkConfiguration"], CFN_MAP_KEYS);
24635
24988
  if (properties["Description"] !== void 0) input["description"] = properties["Description"];
24636
- if (properties["AuthorizerConfiguration"] !== void 0) input["authorizerConfiguration"] = pascalToCamelCaseKeys(properties["AuthorizerConfiguration"]);
24989
+ if (properties["AuthorizerConfiguration"] !== void 0) input["authorizerConfiguration"] = pascalToCamelCaseKeys(properties["AuthorizerConfiguration"], CFN_MAP_KEYS);
24637
24990
  if (properties["ProtocolConfiguration"] !== void 0) {
24638
24991
  const proto = properties["ProtocolConfiguration"];
24639
24992
  if (typeof proto === "string") input["protocolConfiguration"] = { serverProtocol: proto };
24640
- else input["protocolConfiguration"] = pascalToCamelCaseKeys(proto);
24993
+ else input["protocolConfiguration"] = pascalToCamelCaseKeys(proto, CFN_MAP_KEYS);
24641
24994
  }
24642
- if (properties["LifecycleConfiguration"] !== void 0 && typeof properties["LifecycleConfiguration"] === "object" && properties["LifecycleConfiguration"] !== null && Object.keys(properties["LifecycleConfiguration"]).length > 0) input["lifecycleConfiguration"] = pascalToCamelCaseKeys(properties["LifecycleConfiguration"]);
24995
+ if (properties["LifecycleConfiguration"] !== void 0 && typeof properties["LifecycleConfiguration"] === "object" && properties["LifecycleConfiguration"] !== null && Object.keys(properties["LifecycleConfiguration"]).length > 0) input["lifecycleConfiguration"] = pascalToCamelCaseKeys(properties["LifecycleConfiguration"], CFN_MAP_KEYS);
24643
24996
  if (properties["EnvironmentVariables"] !== void 0) input["environmentVariables"] = properties["EnvironmentVariables"];
24644
24997
  if (properties["ClientToken"] !== void 0) input["clientToken"] = properties["ClientToken"];
24645
24998
  const response = await this.client.send(new UpdateAgentRuntimeCommand(input));
@@ -24681,7 +25034,7 @@ var AgentCoreRuntimeProvider = class {
24681
25034
  if (response.agentRuntimeVersion !== void 0) attributes["AgentRuntimeVersion"] = response.agentRuntimeVersion;
24682
25035
  if (response.status !== void 0) attributes["Status"] = response.status;
24683
25036
  if (response.createdAt !== void 0) attributes["CreatedAt"] = response.createdAt.toISOString();
24684
- if (response.workloadIdentityDetails !== void 0) attributes["WorkloadIdentityDetails"] = camelToPascalCaseKeys(response.workloadIdentityDetails);
25037
+ if (response.workloadIdentityDetails !== void 0) attributes["WorkloadIdentityDetails"] = camelToPascalCaseKeys(response.workloadIdentityDetails, SDK_MAP_KEYS);
24685
25038
  return attributes;
24686
25039
  }
24687
25040
  async getAttribute(physicalId, _resourceType, attributeName) {
@@ -24710,17 +25063,17 @@ var AgentCoreRuntimeProvider = class {
24710
25063
  const result = {};
24711
25064
  if (resp.agentRuntimeName !== void 0) result["AgentRuntimeName"] = resp.agentRuntimeName;
24712
25065
  if (resp.roleArn !== void 0) result["RoleArn"] = resp.roleArn;
24713
- if (resp.agentRuntimeArtifact !== void 0) result["AgentRuntimeArtifact"] = camelToPascalCaseKeys(resp.agentRuntimeArtifact);
24714
- if (resp.networkConfiguration !== void 0) result["NetworkConfiguration"] = camelToPascalCaseKeys(resp.networkConfiguration);
25066
+ if (resp.agentRuntimeArtifact !== void 0) result["AgentRuntimeArtifact"] = camelToPascalCaseKeys(resp.agentRuntimeArtifact, SDK_MAP_KEYS);
25067
+ if (resp.networkConfiguration !== void 0) result["NetworkConfiguration"] = camelToPascalCaseKeys(resp.networkConfiguration, SDK_MAP_KEYS);
24715
25068
  result["Description"] = resp.description ?? "";
24716
- if (resp.authorizerConfiguration !== void 0) result["AuthorizerConfiguration"] = camelToPascalCaseKeys(resp.authorizerConfiguration);
25069
+ if (resp.authorizerConfiguration !== void 0) result["AuthorizerConfiguration"] = camelToPascalCaseKeys(resp.authorizerConfiguration, SDK_MAP_KEYS);
24717
25070
  if (resp.protocolConfiguration !== void 0) {
24718
25071
  const proto = resp.protocolConfiguration;
24719
25072
  const keys = Object.keys(proto);
24720
25073
  if (keys.length === 1 && keys[0] === "serverProtocol" && typeof proto["serverProtocol"] === "string") result["ProtocolConfiguration"] = proto["serverProtocol"];
24721
- else result["ProtocolConfiguration"] = camelToPascalCaseKeys(resp.protocolConfiguration);
25074
+ else result["ProtocolConfiguration"] = camelToPascalCaseKeys(resp.protocolConfiguration, SDK_MAP_KEYS);
24722
25075
  }
24723
- if (resp.lifecycleConfiguration !== void 0) result["LifecycleConfiguration"] = camelToPascalCaseKeys(resp.lifecycleConfiguration);
25076
+ if (resp.lifecycleConfiguration !== void 0) result["LifecycleConfiguration"] = camelToPascalCaseKeys(resp.lifecycleConfiguration, SDK_MAP_KEYS);
24724
25077
  if (resp.environmentVariables !== void 0) result["EnvironmentVariables"] = resp.environmentVariables;
24725
25078
  return result;
24726
25079
  }
@@ -29871,7 +30224,7 @@ var DocDBProvider = class {
29871
30224
  createdResourceId = response.DBCluster?.DbClusterResourceId;
29872
30225
  if (!response.DBCluster) throw new Error("CreateDBCluster did not return DBCluster");
29873
30226
  this.logger.debug(`Successfully created DocDB DBCluster ${logicalId}: ${dbClusterIdentifier}`);
29874
- if (process.env["CDKD_NO_WAIT"] !== "true") await this.waitForClusterAvailable(dbClusterIdentifier);
30227
+ if (process.env["CDKD_NO_WAIT"] !== "true") await this.waitForClusterAvailable(logicalId, dbClusterIdentifier);
29875
30228
  return {
29876
30229
  physicalId: dbClusterIdentifier,
29877
30230
  attributes: clusterAttributes(await this.describeDBCluster(dbClusterIdentifier))
@@ -30026,7 +30379,7 @@ var DocDBProvider = class {
30026
30379
  createdResourceId = response.DBInstance?.DbiResourceId;
30027
30380
  if (!response.DBInstance) throw new Error("CreateDBInstance did not return DBInstance");
30028
30381
  this.logger.debug(`Successfully created DocDB DBInstance ${logicalId}: ${dbInstanceIdentifier}`);
30029
- if (process.env["CDKD_NO_WAIT"] !== "true") await this.waitForInstanceAvailable(dbInstanceIdentifier);
30382
+ if (process.env["CDKD_NO_WAIT"] !== "true") await this.waitForInstanceAvailable(logicalId, dbInstanceIdentifier);
30030
30383
  return {
30031
30384
  physicalId: dbInstanceIdentifier,
30032
30385
  attributes: instanceAttributes(await this.describeDBInstance(dbInstanceIdentifier))
@@ -30161,7 +30514,7 @@ var DocDBProvider = class {
30161
30514
  }
30162
30515
  requireClusterWhileWaiting(cluster, logicalId, change) {
30163
30516
  if (cluster === void 0) throw new Error(safeMsg`DescribeDBClusters returned no cluster for DocDB DBCluster ${logicalId} while waiting for its new ${change}`);
30164
- if (isTerminalDbStatus(cluster.Status)) throw new Error(safeMsg`DocDB DBCluster ${logicalId} entered status ${cluster.Status ?? ""} while applying its new ${change}`);
30517
+ if (isTerminalDbWaitStatus(cluster.Status)) throw new Error(safeMsg`DocDB DBCluster ${logicalId} entered status ${cluster.Status ?? ""} while applying its new ${change}`);
30165
30518
  return cluster;
30166
30519
  }
30167
30520
  async waitForClusterPortApplied(dbClusterIdentifier, logicalId, port, maxWaitMs = 18e5) {
@@ -30210,13 +30563,14 @@ var DocDBProvider = class {
30210
30563
  remainingMs: enclosingDeadlineRemainingMs()
30211
30564
  });
30212
30565
  }
30213
- async waitForClusterAvailable(dbClusterIdentifier, maxWaitMs = 18e5) {
30566
+ async waitForClusterAvailable(logicalId, dbClusterIdentifier, maxWaitMs = 18e5) {
30214
30567
  const startTime = Date.now();
30215
30568
  let delay = 5e3;
30216
30569
  while (Date.now() - startTime < maxWaitMs) {
30217
30570
  const status = (await this.describeDBCluster(dbClusterIdentifier))?.Status;
30218
30571
  this.logger.debug(`DocDB DBCluster ${dbClusterIdentifier} status: ${status}`);
30219
30572
  if (status === "available") return;
30573
+ if (isTerminalDbWaitStatus(status)) throw new Error(safeMsg`DocDB DBCluster ${logicalId} entered status ${status ?? ""} while being created, which it does not leave on its own`);
30220
30574
  await this.sleep(delay);
30221
30575
  delay = Math.min(delay * 2, 1e4);
30222
30576
  }
@@ -30240,13 +30594,14 @@ var DocDBProvider = class {
30240
30594
  }
30241
30595
  throw new Error(`Timed out waiting for DocDB DBCluster ${logicalId} to be deleted`);
30242
30596
  }
30243
- async waitForInstanceAvailable(dbInstanceIdentifier, maxWaitMs = 18e5) {
30597
+ async waitForInstanceAvailable(logicalId, dbInstanceIdentifier, maxWaitMs = 18e5) {
30244
30598
  const startTime = Date.now();
30245
30599
  let delay = 1e4;
30246
30600
  while (Date.now() - startTime < maxWaitMs) {
30247
30601
  const status = (await this.describeDBInstance(dbInstanceIdentifier))?.DBInstanceStatus;
30248
30602
  this.logger.debug(`DocDB DBInstance ${dbInstanceIdentifier} status: ${status}`);
30249
30603
  if (status === "available") return;
30604
+ if (isTerminalDbWaitStatus(status)) throw new Error(safeMsg`DocDB DBInstance ${logicalId} entered status ${status ?? ""} while being created, which it does not leave on its own`);
30250
30605
  await this.sleep(delay);
30251
30606
  delay = Math.min(delay * 2, 1e4);
30252
30607
  }
@@ -33179,7 +33534,7 @@ var CognitoUserPoolProvider = class {
33179
33534
  //#region src/provisioning/providers/elasticache-provider.ts
33180
33535
  const CACHE_DELETE_WAIT_MS = Math.max(6e5, slowCcOperationTimeoutMs("AWS::ElastiCache::CacheCluster", "DELETE"));
33181
33536
  const NODE_TYPE_MODIFY_WAIT_MS = Math.max(36e5, slowCcOperationTimeoutMs("AWS::ElastiCache::CacheCluster", "UPDATE"));
33182
- const NODE_TYPE_DROPPED_AFTER_MS = 12e4;
33537
+ const MODIFY_DROPPED_AFTER_MS = 12e4;
33183
33538
  function availabilityZonesNotCovered(a, b) {
33184
33539
  const remaining = [...b];
33185
33540
  const out = [];
@@ -33190,6 +33545,27 @@ function availabilityZonesNotCovered(a, b) {
33190
33545
  }
33191
33546
  return out;
33192
33547
  }
33548
+ function nodesToRemove(nodes, desiredCount, desiredZones) {
33549
+ const remainingZones = desiredZones === void 0 ? void 0 : [...desiredZones];
33550
+ const named = nodes.filter((n) => n.id !== void 0);
33551
+ const keep = /* @__PURE__ */ new Set();
33552
+ const unnamed = nodes.length - named.length;
33553
+ const byIdDesc = [...named].sort((a, b) => a.id < b.id ? 1 : a.id > b.id ? -1 : 0);
33554
+ for (const node of byIdDesc) {
33555
+ if (keep.size + unnamed >= desiredCount) break;
33556
+ if (remainingZones === void 0) {
33557
+ keep.add(node.id);
33558
+ continue;
33559
+ }
33560
+ const i = node.zone === void 0 ? -1 : remainingZones.indexOf(node.zone);
33561
+ if (i >= 0) {
33562
+ remainingZones.splice(i, 1);
33563
+ keep.add(node.id);
33564
+ }
33565
+ }
33566
+ if (keep.size + unnamed < desiredCount) return void 0;
33567
+ return named.map((n) => n.id).filter((id) => !keep.has(id)).sort();
33568
+ }
33193
33569
  var ElastiCacheProvider = class {
33194
33570
  client;
33195
33571
  createClient;
@@ -33407,7 +33783,8 @@ var ElastiCacheProvider = class {
33407
33783
  const sgIds = rawSgIds && rawSgIds.length > 0 ? rawSgIds : void 0;
33408
33784
  const notificationTopicArn = properties["NotificationTopicArn"];
33409
33785
  const desiredNodeType = properties["CacheNodeType"];
33410
- const placement = await this.newNodePlacement(physicalId, properties, previousProperties);
33786
+ const nodeChanges = await this.planNodeChanges(logicalId, physicalId, resourceType, properties, previousProperties);
33787
+ const placement = nodeChanges.placement;
33411
33788
  this.warnNotAppliedInPlace(logicalId, properties, previousProperties, placement);
33412
33789
  await this.getClient().send(new ModifyCacheClusterCommand({
33413
33790
  CacheClusterId: physicalId,
@@ -33417,6 +33794,7 @@ var ElastiCacheProvider = class {
33417
33794
  NewAvailabilityZones: placement.newAvailabilityZones,
33418
33795
  ...placement.azMode !== void 0 && { AZMode: placement.azMode }
33419
33796
  },
33797
+ ...nodeChanges.removeIds.length > 0 && { CacheNodeIdsToRemove: nodeChanges.removeIds },
33420
33798
  SecurityGroupIds: sgIds,
33421
33799
  CacheParameterGroupName: properties["CacheParameterGroupName"],
33422
33800
  EngineVersion: properties["EngineVersion"],
@@ -33431,7 +33809,7 @@ var ElastiCacheProvider = class {
33431
33809
  ApplyImmediately: true
33432
33810
  }));
33433
33811
  this.logger.debug(`Successfully updated CacheCluster ${logicalId}`);
33434
- if (desiredNodeType !== void 0) await this.waitForClusterAvailable(physicalId, NODE_TYPE_MODIFY_WAIT_MS, desiredNodeType);
33812
+ if (desiredNodeType !== void 0 || nodeChanges.removeIds.length > 0) await this.waitForClusterAvailable(physicalId, NODE_TYPE_MODIFY_WAIT_MS, desiredNodeType, nodeChanges.removeIds);
33435
33813
  else await this.waitForClusterAvailable(physicalId);
33436
33814
  const described = await this.describeCacheCluster(physicalId);
33437
33815
  this.warnTransitEncryptionNotApplied(logicalId, properties, previousProperties, described?.TransitEncryptionEnabled);
@@ -33495,15 +33873,41 @@ var ElastiCacheProvider = class {
33495
33873
  const state = current === true ? "ENABLED" : "DISABLED";
33496
33874
  this.logger.warn(safeMsg`CacheCluster ${logicalId}: the cluster still has encryption in transit ${state} ` + safeMsg`(the template now says TransitEncryptionEnabled: ${String(next)}). ` + "ModifyCacheCluster cannot change it, and CloudFormation leaves it unchanged too; to change it, replace the cluster, for example by changing its logical ID.");
33497
33875
  }
33498
- async newNodePlacement(physicalId, properties, previousProperties) {
33499
- const desired = properties["PreferredAvailabilityZones"];
33500
- if (!Array.isArray(desired) || desired.length === 0) return void 0;
33501
- if (isDeepStrictEqual(desired, previousProperties["PreferredAvailabilityZones"]) && String(properties["NumCacheNodes"]) === String(previousProperties["NumCacheNodes"])) return;
33502
- const newAvailabilityZones = availabilityZonesNotCovered(desired, ((await this.describeCacheCluster(physicalId))?.CacheNodes ?? []).map((n) => n.CustomerAvailabilityZone).filter((az) => typeof az === "string"));
33503
- if (newAvailabilityZones.length === 0) return void 0;
33876
+ async planNodeChanges(logicalId, physicalId, resourceType, properties, previousProperties) {
33877
+ const none = {
33878
+ placement: void 0,
33879
+ removeIds: []
33880
+ };
33881
+ const desiredZones = properties["PreferredAvailabilityZones"];
33882
+ const zones = Array.isArray(desiredZones) && desiredZones.length > 0 ? desiredZones : void 0;
33883
+ if (!(String(properties["NumCacheNodes"]) !== String(previousProperties["NumCacheNodes"])) && (zones === void 0 || isDeepStrictEqual(zones, previousProperties["PreferredAvailabilityZones"]))) return none;
33884
+ if (zones === void 0 && !(Number(properties["NumCacheNodes"]) < Number(previousProperties["NumCacheNodes"]))) return none;
33885
+ const liveNodes = ((await this.describeCacheCluster(physicalId))?.CacheNodes ?? []).map((n) => ({
33886
+ id: n.CacheNodeId,
33887
+ zone: n.CustomerAvailabilityZone
33888
+ }));
33889
+ const desiredCount = properties["NumCacheNodes"] != null ? Number(properties["NumCacheNodes"]) : void 0;
33890
+ const previousCount = Number(previousProperties["NumCacheNodes"]);
33891
+ const templateLowered = Number(properties["NumCacheNodes"]) < previousCount;
33892
+ let removeIds = [];
33893
+ if (templateLowered && desiredCount !== void 0 && desiredCount < liveNodes.length) {
33894
+ if (liveNodes.length !== previousCount) throw new ProvisioningError(safeMsg`Cannot update CacheCluster ${logicalId}: the template lowers NumCacheNodes from ${String(previousCount)} ` + safeMsg`to ${String(desiredCount)}, but the cluster has ${String(liveNodes.length)} nodes, so ` + "the removal would delete nodes the template change does not account for. Deploy NumCacheNodes set to the live count first, then lower it.", resourceType, logicalId, physicalId);
33895
+ const plan = nodesToRemove(liveNodes, desiredCount, zones);
33896
+ if (plan === void 0) {
33897
+ const liveZones = liveNodes.map((n) => n.zone);
33898
+ const disjoint = zones !== void 0 && !zones.some((z) => liveZones.includes(z));
33899
+ throw new ProvisioningError(safeMsg`Cannot update CacheCluster ${logicalId}: lowering NumCacheNodes to ${String(desiredCount)} ` + "with this PreferredAvailabilityZones list needs a node removed and a node added in a zone no live node occupies, in one update, which ModifyCacheCluster cannot do. " + (disjoint ? `CloudFormation replaces the cluster for a move to disjoint zones; cdkd does not yet (issue #5458). ` : "") + `Replace the cluster (for example by changing its logical ID), or list only zones the kept nodes occupy.`, resourceType, logicalId, physicalId);
33900
+ }
33901
+ removeIds = plan;
33902
+ this.logger.info(safeMsg`CacheCluster ${logicalId}: NumCacheNodes ${String(previousProperties["NumCacheNodes"])} -> ${String(desiredCount)}, removing cache nodes ${removeIds.join(", ")}`);
33903
+ }
33904
+ const newAvailabilityZones = zones === void 0 || removeIds.length > 0 ? [] : availabilityZonesNotCovered(zones, liveNodes.filter((n) => n.id === void 0 || !removeIds.includes(n.id)).map((n) => n.zone).filter((z) => typeof z === "string"));
33504
33905
  return {
33505
- newAvailabilityZones,
33506
- azMode: properties["AZMode"]
33906
+ placement: newAvailabilityZones.length > 0 ? {
33907
+ newAvailabilityZones,
33908
+ azMode: properties["AZMode"]
33909
+ } : void 0,
33910
+ removeIds
33507
33911
  };
33508
33912
  }
33509
33913
  warnNotAppliedInPlace(logicalId, properties, previousProperties, placement) {
@@ -33577,7 +33981,7 @@ var ElastiCacheProvider = class {
33577
33981
  ShowCacheNodeInfo: true
33578
33982
  }))).CacheClusters?.[0];
33579
33983
  }
33580
- async waitForClusterAvailable(cacheClusterId, maxWaitMs = 6e5, expectedNodeType) {
33984
+ async waitForClusterAvailable(cacheClusterId, maxWaitMs = 6e5, expectedNodeType, removedNodeIds = []) {
33581
33985
  const startTime = Date.now();
33582
33986
  let delay = 1e4;
33583
33987
  while (Date.now() - startTime < maxWaitMs) {
@@ -33585,12 +33989,14 @@ var ElastiCacheProvider = class {
33585
33989
  const status = cluster?.CacheClusterStatus;
33586
33990
  this.logger.debug(`CacheCluster ${cacheClusterId} status: ${status}`);
33587
33991
  const liveNodeType = cluster?.CacheNodeType;
33588
- if (status === "available" && (expectedNodeType === void 0 || liveNodeType === expectedNodeType)) return;
33589
- if (expectedNodeType !== void 0 && status === "available" && cluster?.PendingModifiedValues?.CacheNodeType === void 0 && Date.now() - startTime > NODE_TYPE_DROPPED_AFTER_MS) throw new Error(safeMsg`CacheCluster ${cacheClusterId} is available with node type ${liveNodeType} and no node-type change pending; the change to ${expectedNodeType} was not applied. Check the cluster's events (aws elasticache describe-events) for the reason, then deploy again.`);
33992
+ const removalDone = removedNodeIds.length === 0 || cluster?.CacheNodes !== void 0 && !cluster.CacheNodes.some((n) => n.CacheNodeId !== void 0 && removedNodeIds.includes(n.CacheNodeId));
33993
+ if (status === "available" && removalDone && (expectedNodeType === void 0 || liveNodeType === expectedNodeType)) return;
33994
+ if (!removalDone && status === "available" && (cluster?.PendingModifiedValues?.CacheNodeIdsToRemove ?? []).length === 0 && Date.now() - startTime > MODIFY_DROPPED_AFTER_MS) throw new Error(safeMsg`CacheCluster ${cacheClusterId} is available and still lists cache nodes ${removedNodeIds.join(", ")} with no removal pending; the removal was not applied. Check the cluster's events (aws elasticache describe-events) for the reason, then deploy again.`);
33995
+ if (expectedNodeType !== void 0 && liveNodeType !== expectedNodeType && status === "available" && cluster?.PendingModifiedValues?.CacheNodeType === void 0 && Date.now() - startTime > MODIFY_DROPPED_AFTER_MS) throw new Error(safeMsg`CacheCluster ${cacheClusterId} is available with node type ${liveNodeType} and no node-type change pending; the change to ${expectedNodeType} was not applied. Check the cluster's events (aws elasticache describe-events) for the reason, then deploy again.`);
33590
33996
  await this.sleep(delay);
33591
33997
  delay = Math.min(delay * 2, 1e4);
33592
33998
  }
33593
- throw new Error(expectedNodeType === void 0 ? `Timed out waiting for CacheCluster ${cacheClusterId} to become available` : safeMsg`Timed out waiting for CacheCluster ${cacheClusterId} to become available with node type ${expectedNodeType}`);
33999
+ throw new Error(expectedNodeType === void 0 && removedNodeIds.length === 0 ? `Timed out waiting for CacheCluster ${cacheClusterId} to become available` : safeMsg`Timed out waiting for CacheCluster ${cacheClusterId} to become available` + (expectedNodeType === void 0 ? "" : safeMsg` with node type ${expectedNodeType}`) + (removedNodeIds.length === 0 ? "" : safeMsg` without cache nodes ${removedNodeIds.join(", ")}`));
33594
34000
  }
33595
34001
  async waitForClusterDeleted(logicalId, cacheClusterId, maxWaitMs = 6e5) {
33596
34002
  const startTime = Date.now();
@@ -40052,6 +40458,7 @@ function previousMetricNames(value) {
40052
40458
  const expanded = expandShardLevelMetrics(value);
40053
40459
  return isUsableMetricsList(expanded) ? expanded : [];
40054
40460
  }
40461
+ const DEFAULT_MAX_RECORD_SIZE_KIB = 1024;
40055
40462
  function readMaxRecordSize(value, mask) {
40056
40463
  if (value == null) return { kind: "absent" };
40057
40464
  if (typeof value === "number" && Number.isFinite(value)) return {
@@ -40317,10 +40724,10 @@ var KinesisStreamProvider = class {
40317
40724
  }
40318
40725
  const desiredSizeRead = readMaxRecordSize(properties["MaxRecordSizeInKiB"], mask);
40319
40726
  if (desiredSizeRead.kind === "unusable") warn(`${desiredSizeRead.reason}. Leaving the maximum record size on ${physicalId} unchanged; the same value is REFUSED on a template-path create`);
40320
- const newMaxRecordSize = comparableRecordSize(properties["MaxRecordSizeInKiB"], mask);
40321
- const oldMaxRecordSize = comparableRecordSize(previousProperties["MaxRecordSizeInKiB"], mask);
40322
- if (newMaxRecordSize !== void 0 && newMaxRecordSize !== oldMaxRecordSize) {
40323
- this.logger.debug(`Updating max record size for ${physicalId}: from ${oldMaxRecordSize ?? "no value"} to ${newMaxRecordSize}`);
40727
+ const newMaxRecordSize = desiredSizeRead.kind === "absent" ? DEFAULT_MAX_RECORD_SIZE_KIB : comparableRecordSize(properties["MaxRecordSizeInKiB"], mask);
40728
+ const recordedMaxRecordSize = comparableRecordSize(previousProperties["MaxRecordSizeInKiB"], mask);
40729
+ if (newMaxRecordSize !== void 0 && newMaxRecordSize !== (recordedMaxRecordSize ?? DEFAULT_MAX_RECORD_SIZE_KIB)) {
40730
+ this.logger.debug(`Updating max record size for ${physicalId}: from ${recordedMaxRecordSize ?? "no value"} to ${newMaxRecordSize}`);
40324
40731
  await this.getClient().send(new UpdateMaxRecordSizeCommand({
40325
40732
  StreamARN: await this.resolveStreamArn(physicalId),
40326
40733
  MaxRecordSizeInKiB: newMaxRecordSize
@@ -43227,6 +43634,7 @@ var FSxFileSystemProvider = class {
43227
43634
  const nextVal = next[key];
43228
43635
  const prevVal = prev[key];
43229
43636
  if (JSON.stringify(nextVal) === JSON.stringify(prevVal)) continue;
43637
+ if (configKey === "OpenZFSConfiguration" && key === "Options") continue;
43230
43638
  if (!mutable.has(key)) throw new ResourceUpdateNotSupportedError(resourceType, logicalId, `AWS FSx FileSystem ${configKey}.${key} is immutable on AWS — UpdateFileSystem cannot change it after creation. Re-deploy with cdkd deploy --replace --force-stateful-recreation (the type is in cdkd's stateful-recreate guard set, so a bare --replace is refused a second time with STATEFUL_REPLACE_BLOCKED), or destroy + redeploy the stack.`);
43231
43639
  if (nextVal === void 0 && key !== "RouteTableIds") {
43232
43640
  leftInPlace.push(key);
@@ -43394,10 +43802,14 @@ var FSxFileSystemProvider = class {
43394
43802
  TagKeys: toRemove
43395
43803
  }));
43396
43804
  }
43397
- async delete(logicalId, physicalId, resourceType, _properties, context) {
43805
+ async delete(logicalId, physicalId, resourceType, properties, context) {
43398
43806
  this.logger.debug(`Deleting FSx FileSystem ${logicalId}: ${physicalId}`);
43399
43807
  try {
43400
- await this.getClient().send(new DeleteFileSystemCommand$1({ FileSystemId: physicalId }));
43808
+ const openZfsOptions = this.toDeleteOpenZFSOptions(properties);
43809
+ await this.getClient().send(new DeleteFileSystemCommand$1({
43810
+ FileSystemId: physicalId,
43811
+ ...openZfsOptions && { OpenZFSConfiguration: { Options: openZfsOptions } }
43812
+ }));
43401
43813
  } catch (error) {
43402
43814
  if (error instanceof FileSystemNotFound$1) {
43403
43815
  const clientRegion = await this.getClient().config.region();
@@ -43413,6 +43825,14 @@ var FSxFileSystemProvider = class {
43413
43825
  await this.waitForFileSystemDeleted(physicalId, logicalId, resourceType, context?.maskSecrets);
43414
43826
  this.logger.debug(`Successfully deleted FSx FileSystem ${logicalId}`);
43415
43827
  }
43828
+ toDeleteOpenZFSOptions(properties) {
43829
+ if (properties?.["FileSystemType"] !== "OPENZFS") return void 0;
43830
+ const config = properties["OpenZFSConfiguration"];
43831
+ if (typeof config !== "object" || config === null || Array.isArray(config)) return void 0;
43832
+ const options = config["Options"];
43833
+ if (!Array.isArray(options) || options.length === 0) return void 0;
43834
+ return options.map((o) => String(o));
43835
+ }
43416
43836
  async isSameResource(journaledPhysicalId, record, resourceType, context) {
43417
43837
  if (resourceType !== "AWS::FSx::FileSystem") return "unknown";
43418
43838
  if (!FILE_SYSTEM_ID_PATTERN.test(journaledPhysicalId) || !FILE_SYSTEM_ID_PATTERN.test(record.physicalId)) return "unknown";
@@ -43675,7 +44095,8 @@ var FSxFileSystemProvider = class {
43675
44095
  "BackupId",
43676
44096
  "WindowsConfiguration.SelfManagedActiveDirectoryConfiguration.Password",
43677
44097
  "OntapConfiguration.FsxAdminPassword",
43678
- "OpenZFSConfiguration.RootVolumeConfiguration"
44098
+ "OpenZFSConfiguration.RootVolumeConfiguration",
44099
+ "OpenZFSConfiguration.Options"
43679
44100
  ];
43680
44101
  }
43681
44102
  getDriftUnorderedPaths(resourceType) {
@@ -46916,6 +47337,7 @@ var CloudTrailProvider = class {
46916
47337
  //#endregion
46917
47338
  //#region src/provisioning/providers/codebuild-provider.ts
46918
47339
  const DEFAULT_PROJECT_VISIBILITY = "PRIVATE";
47340
+ const DEFAULT_ENCRYPTION_KEY = "alias/aws/s3";
46919
47341
  function readVisibility(properties, mask) {
46920
47342
  const visibility = properties["Visibility"];
46921
47343
  const role = properties["ResourceAccessRole"];
@@ -47194,6 +47616,9 @@ var CodeBuildProvider = class {
47194
47616
  const input = this.mapProperties(() => physicalId, properties);
47195
47617
  input.name = physicalId;
47196
47618
  if (properties["BuildBatchConfig"] == null && previousProperties["BuildBatchConfig"] != null) input.buildBatchConfig = {};
47619
+ const declaredKey = (value) => value != null && value !== "";
47620
+ if (!declaredKey(properties["EncryptionKey"]) && declaredKey(previousProperties["EncryptionKey"])) input.encryptionKey = DEFAULT_ENCRYPTION_KEY;
47621
+ if (properties["Tags"] == null && previousProperties["Tags"] != null) input.tags = [];
47197
47622
  const updated = await this.getClient().send(new UpdateProjectCommand(input));
47198
47623
  const desiredVisibility = readVisibility(properties, mask);
47199
47624
  const recorded = readVisibility(previousProperties, mask);
@@ -50595,4 +51020,4 @@ var ACMCertificateProvider = class {
50595
51020
 
50596
51021
  //#endregion
50597
51022
  export { ACMCertificateProvider, ASGProvider, AgentCoreBrowserProvider, AgentCoreCodeInterpreterProvider, AgentCoreEvaluatorProvider, AgentCoreRuntimeProvider, ApiGatewayProvider, ApiGatewayV2Provider, AppSyncProvider, BudgetsBudgetProvider, CloudFrontDistributionProvider, CloudFrontOACProvider, CloudFrontOAIProvider, CloudTrailProvider, CloudWatchAlarmProvider, CloudWatchAnomalyDetectorProvider, CodeBuildProvider, CodeCommitRepositoryProvider, CognitoUserPoolProvider, DLMLifecyclePolicyProvider, DocDBProvider, DocDBSubnetGroupProvider, DynamoDBGlobalTableProvider, DynamoDBTableProvider, EC2Provider, ECRProvider, ECSProvider, EFSProvider, ELBv2Provider, EMRClusterProvider, EMRInstanceFleetConfigProvider, EMRInstanceGroupConfigProvider, ElastiCacheProvider, EventBridgeBusProvider, EventBridgeRuleProvider, FSxFileSystemProvider, FirehoseProvider, GlueConnectionProvider, GlueCrawlerProvider, GlueJobProvider, GlueProvider, GlueSecurityConfigurationProvider, GlueTriggerProvider, GlueWorkflowProvider, IAMAccessKeyProvider, IAMInstanceProfileProvider, IAMManagedPolicyProvider, IAMPolicyProvider, IAMRoleProvider, IAMUserGroupProvider, KMSProvider, KinesisStreamConsumerProvider, KinesisStreamProvider, LambdaEventInvokeConfigProvider, LambdaEventSourceMappingProvider, LambdaFunctionProvider, LambdaLayerVersionProvider, LambdaMicrovmImageProvider, LambdaNetworkConnectorProvider, LambdaPermissionProvider, LambdaUrlProvider, LambdaWebFunctionEndpointProvider, LambdaWebFunctionRevisionProvider, LogsLogGroupProvider, NeptuneProvider, NestedStackProvider, PipesPipeProvider, RDSDBProxyEndpointProvider, RDSDBProxyProvider, RDSDBProxyTargetGroupProvider, RDSProvider, Route53Provider, S3BucketPolicyProvider, S3BucketProvider, S3DirectoryBucketProvider, S3TablesProvider, S3VectorsProvider, SNSSubscriptionProvider, SNSTopicPolicyProvider, SNSTopicProvider, SQSQueuePolicyProvider, SQSQueueProvider, SSMParameterProvider, SchedulerScheduleProvider, SecretsManagerSecretProvider, ServiceDiscoveryProvider, StepFunctionsProvider, WAFv2WebACLProvider, WaitConditionHandleProvider };
50598
- //# sourceMappingURL=provider-classes-d9K3vBVh.js.map
51023
+ //# sourceMappingURL=provider-classes-BxfIHcea.js.map