@go-to-k/cdkd 0.284.15 → 0.284.16

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.
@@ -16503,7 +16503,7 @@ var CloudControlProvider = class {
16503
16503
  if (context?.finalSnapshotIdentifier !== void 0) throw new ProvisioningError(`${logicalId} (${resourceType}) requires a final snapshot (DeletionPolicy: Snapshot), but the Cloud Control API delete route has no final-snapshot parameter. Re-run with --skip-final-snapshot after snapshotting manually, or retain the resource.`, resourceType, logicalId, physicalId);
16504
16504
  if (context?.removeProtection === true && resourceType === "AWS::AutoScaling::AutoScalingGroup") {
16505
16505
  this.logger.debug(`Delegating protected AutoScalingGroup ${logicalId} delete to the SDK ASGProvider (Cloud Control cannot force-delete a protected ASG)`);
16506
- const { ASGProvider } = await import("./asg-provider-BZwQzb8e.js").then((n) => n.n);
16506
+ const { ASGProvider } = await import("./asg-provider-D7DqNvVo.js").then((n) => n.n);
16507
16507
  return await new ASGProvider().delete(logicalId, physicalId, resourceType, _properties, context);
16508
16508
  }
16509
16509
  const isProtectedEc2Instance = context?.removeProtection === true && resourceType === "AWS::EC2::Instance";
@@ -24023,6 +24023,91 @@ async function updateWithRollbackRetry(provider, args, logicalId, logger, isInte
24023
24023
  });
24024
24024
  }
24025
24025
  /**
24026
+ * Both retry loops around a reverse-replacement replay-CREATE (issue
24027
+ * [#2032](https://github.com/go-to-k/cdkd/issues/2032)) — the create-side twin
24028
+ * of {@link updateWithRollbackRetry}, and the single place the two replay arms
24029
+ * get their `disableOuterRetry` guard.
24030
+ *
24031
+ * ## The nesting, and why it is required
24032
+ *
24033
+ * A caller-supplied `isRetryable` REPLACES `isRetryableTransientError`
24034
+ * outright, and ANY explicit schedule knob sets `defaultSchedule = false` in
24035
+ * `retry.ts`, which is the gate on the dense IAM-propagation path. Both
24036
+ * replay-CREATE arms pass BOTH ({@link RECREATE_RETRY_SCHEDULE} plus
24037
+ * `isNameCooldownError` / `isRecreateRetryableError`), so a propagation error
24038
+ * raised by the re-create — the old execution role was re-created moments
24039
+ * earlier in this same rollback, so `CreateFunction` answers `The role defined
24040
+ * for the function cannot be assumed by Lambda.` — was non-retryable on
24041
+ * attempt 0 and rethrown raw, leaving the resource absent from BOTH AWS and
24042
+ * state. The INNER call passes NO knobs and NO classifier, so it gets the
24043
+ * dense 26-retry / 47.75s propagation schedule while the OUTER one keeps
24044
+ * owning the name-release cadence.
24045
+ *
24046
+ * ## What the deploy engine's precedents actually are
24047
+ *
24048
+ * They are two DIFFERENT shapes, and the two rollback arms need one each —
24049
+ * this helper is deliberately the sum of both rather than a copy of either:
24050
+ *
24051
+ * - Arm 2 (post-delete-new-first) matches the delete-then-re-create sites,
24052
+ * `deploy-engine.ts`'s `--replace` delete-first fallback and its named
24053
+ * replacement, which nest `this.withRetry(...)` INSIDE an outer
24054
+ * `isRecreateRetryableError` retry. Same two loops as here.
24055
+ * - Arm 1 (create-first) has NO such twin. Its deploy-engine analogue is the
24056
+ * property-driven create-first at `deploy-engine.ts:3745`, which calls
24057
+ * `this.withRetry(...)` on its OWN — one default-schedule loop, no outer
24058
+ * custom-classifier loop at all — and whose catch then reads
24059
+ * `isNameCollisionError` to reach the delete-first fallback. Arm 1 is that
24060
+ * shape PLUS the outer SQS-cooldown loop issue #1206 added, so it is the
24061
+ * SUM of both precedents.
24062
+ *
24063
+ * ## Why the guard lives here and not in `retry.ts`
24064
+ *
24065
+ * `withRetry` never receives the provider, so it cannot honour
24066
+ * `disableOuterRetry` — re-running `CustomResourceProvider.create()` /
24067
+ * `NestedStackProvider.create()` mints a fresh pre-signed S3 URL + RequestId
24068
+ * and strands the previous attempt at a key nobody polls, and re-running
24069
+ * `NestedStackProvider.create()` re-creates child stacks and child state
24070
+ * files. That check therefore has to live next to the provider, exactly as
24071
+ * `DeployEngine.withRetry` does it.
24072
+ *
24073
+ * The guard covers BOTH loops, not just the inner one. Guarding only the inner
24074
+ * loop left the outer schedule free to re-enter, which measured at 9
24075
+ * `create()` calls for a cooldown and 10 for a collision against an opt-out
24076
+ * provider — i.e. the exact hazard the flag exists for, arriving through the
24077
+ * outer loop instead. A single-shot call still lets a name collision reach the
24078
+ * CALLER's catch on attempt 0 (that catch sits outside this helper), so the
24079
+ * delete-new-first fallback is unaffected by the opt-out.
24080
+ *
24081
+ * ## The collision arm is deliberately untouched
24082
+ *
24083
+ * `isNameCollisionError`'s signature (`already exist(s)` / `AlreadyExists`) is
24084
+ * NOT in `RETRYABLE_ERROR_MESSAGE_PATTERNS`, so the inner classifier rejects it
24085
+ * on attempt 0 and it reaches the caller's catch on the FIRST outer attempt,
24086
+ * exactly as before. The SQS cooldown IS matched by the inner classifier (the
24087
+ * generic table carries `wait 60 seconds`), which is the same division of
24088
+ * labour the deploy engine's named-replacement site documents: the inner retry
24089
+ * absorbs most of the 60s window and the outer ~64s budget covers the tail.
24090
+ */
24091
+ async function createWithRollbackRetry(provider, create, logicalId, logger, isInterrupted, secrets, outer) {
24092
+ if (provider.disableOuterRetry) return await create();
24093
+ const maskedLogger = maskingRetryLogger(logger, secrets);
24094
+ return await withRetry(() => withRetry(create, logicalId, {
24095
+ logger: maskedLogger,
24096
+ ...isInterrupted && {
24097
+ isInterrupted,
24098
+ onInterrupted: () => /* @__PURE__ */ new Error("Rollback interrupted while retrying the replay re-create")
24099
+ }
24100
+ }), logicalId, {
24101
+ ...RECREATE_RETRY_SCHEDULE,
24102
+ logger: maskedLogger,
24103
+ ...isInterrupted && {
24104
+ isInterrupted,
24105
+ onInterrupted: () => new Error(outer.interruptedMessage)
24106
+ },
24107
+ isRetryable: outer.isRetryable
24108
+ });
24109
+ }
24110
+ /**
24026
24111
  * The state record to store after a rollback UPDATE arm (issue #1644).
24027
24112
  *
24028
24113
  * The bag handed to `update()` on both arms IS `restored.properties`, so a
@@ -24222,14 +24307,9 @@ async function replaySingle(op, stateResources, stackName, ctx, resolver, orphan
24222
24307
  let deletedNewFirst = false;
24223
24308
  let createResult;
24224
24309
  try {
24225
- createResult = await withRetry(() => createProvider.create(op.logicalId, op.resourceType, { ...resolvedPrevProps }, replayingStateCreateContext(secrets)), op.logicalId, {
24226
- ...RECREATE_RETRY_SCHEDULE,
24227
- logger: maskingRetryLogger(logger, secrets),
24228
- ...isInterrupted && {
24229
- isInterrupted,
24230
- onInterrupted: () => /* @__PURE__ */ new Error("Rollback interrupted while waiting out the name cooldown")
24231
- },
24232
- isRetryable: isNameCooldownError
24310
+ createResult = await createWithRollbackRetry(createProvider, () => createProvider.create(op.logicalId, op.resourceType, { ...resolvedPrevProps }, replayingStateCreateContext(secrets)), op.logicalId, logger, isInterrupted, secrets, {
24311
+ isRetryable: isNameCooldownError,
24312
+ interruptedMessage: "Rollback interrupted while waiting out the name cooldown"
24233
24313
  });
24234
24314
  } catch (createError) {
24235
24315
  if (!isNameCollisionError(createError instanceof Error ? createError.message : String(createError))) throw createError;
@@ -24245,14 +24325,9 @@ async function replaySingle(op, stateResources, stackName, ctx, resolver, orphan
24245
24325
  delete stateResources[op.logicalId];
24246
24326
  await afterOp?.(op.logicalId);
24247
24327
  try {
24248
- createResult = await withRetry(() => createProvider.create(op.logicalId, op.resourceType, { ...resolvedPrevProps }, replayingStateCreateContext(secrets)), op.logicalId, {
24249
- ...RECREATE_RETRY_SCHEDULE,
24250
- logger: maskingRetryLogger(logger, secrets),
24251
- ...isInterrupted && {
24252
- isInterrupted,
24253
- onInterrupted: () => /* @__PURE__ */ new Error("Rollback interrupted while waiting for the old name to release")
24254
- },
24255
- isRetryable: isRecreateRetryableError
24328
+ createResult = await createWithRollbackRetry(createProvider, () => createProvider.create(op.logicalId, op.resourceType, { ...resolvedPrevProps }, replayingStateCreateContext(secrets)), op.logicalId, logger, isInterrupted, secrets, {
24329
+ isRetryable: isRecreateRetryableError,
24330
+ interruptedMessage: "Rollback interrupted while waiting for the old name to release"
24256
24331
  });
24257
24332
  } catch (recreateError) {
24258
24333
  throw new Error(maskSecretsInText(`Failed to re-create the old ${op.logicalId} after the new resource (${current.physicalId}) was already deleted: ${recreateError instanceof Error ? recreateError.message : String(recreateError)}. The resource is now absent — fix forward with 'cdkd deploy'.`, secrets));
@@ -24601,7 +24676,7 @@ const FLUSH_INTERVAL_MS = 2e3;
24601
24676
  const FLUSH_EVENT_THRESHOLD = 50;
24602
24677
  /** Build-time cdkd version, with a dev fallback for non-built contexts. */
24603
24678
  function getCdkdVersion() {
24604
- return "0.284.15";
24679
+ return "0.284.16";
24605
24680
  }
24606
24681
  /**
24607
24682
  * Generate a time-sortable unique run id, e.g.
@@ -27141,4 +27216,4 @@ var DeployEngine = class {
27141
27216
 
27142
27217
  //#endregion
27143
27218
  export { isTerminationProtectionPropagationError as $, ResourceUpdateNotSupportedError as $n, validateAssetBucketName as $t, renderStatefulReason as A, derivePartitionAndUrlSuffix as An, INTRINSIC_KEYS as At, exportAliasCollisionScrubWarning as B, CdkdError as Bn, stringifyValue as Bt, isFinalSnapshotError as C, CFN_TEMPLATE_URL_LIMIT as Cn, s3BucketArn as Ct, extractDeploymentEventError as D, expectedOwnerParam as Dn, s3BucketWebsiteUrl as Dt, makeCanonicalizePropertiesFn as E, uploadCfnTemplate as En, s3BucketRegionalDomainName as Et, green as F, AwsClients as Fn, LockManager as Ft, collectInlinePolicyNamesManagedBySiblings as G, LocalMigrateError as Gn, rewriteTemplateAssetReferences as Gt, secretBearingStateKeyWarning as H, DependencyError as Hn, buildAssetRedirectMap as Ht, red as I, getAwsClients as In, S3StateBackend as It, findActionableSilentDrops as J, MissingCdkCliError as Jn, AssetModeResolver as Jt, clearOnUpdateRemoval as K, LocalStartServiceError as Kn, escapeRegExp$1 as Kt, yellow as L, resetAwsClients as Ln, rebuildClientForBucketRegion as Lt, bold as M, processStackMessages as Mn, withRetry as Mt, cyan as N, clearBucketRegionCache as Nn, DagBuilder as Nt, MULTI_REGION_RECREATE_BLOCKED_TYPES as O, PARTITION_TABLE as On, applyRoleArnIfSet as Ot, gray as P, resolveBucketRegion as Pn, TemplateParser as Pt, disableInstanceApiTermination as Q, ResourceTimeoutError as Qn, parseBootstrapMarker as Qt, collectDeclaredOutputNames as R, setAwsClients as Rn, shouldRetainResource as Rt, createPreDeleteFinalSnapshot as S, CFN_TEMPLATE_BODY_LIMIT as Sn, scrubResourceRecord as St, unsupportedFinalSnapshotError as T, findLargeInlineResources as Tn, s3BucketDualStackDomainName as Tt, stateKeySecretExposure as U, DeployCancelledError as Un, createAssetRedirectResolver as Ut, isExportAliasCollision as V, ConfigError as Vn, WorkGraph as Vt, IAMRoleProvider as W, LocalInvokeBuildError as Wn, loadPublishableAssetManifest as Wt, CloudControlProvider as X, PartialFailureError as Xn, ensureAssetStorage as Xt, findSilentDropProperties as Y, NestedStackChildDirectDestroyError as Yn, BOOTSTRAP_MARKER_PREFIX as Yt, slowCcOperationTimeoutMs as Z, ProvisioningError as Zn, getBootstrapMarkerKey as Zt, computeImplicitDeleteEdges as _, resolveStateBucketWithDefault as _n, STATE_SOURCED_READBACK_RULES as _t, DeploymentEventsStore as a, runDockerForeground as an, isCdkdError as ar, normalizeAwsTagsToCfn as at, buildFinalSnapshotIdentifier as b, stateBucketExistenceConfirmed as bn, maskSecretsInText as bt, replayFailedOperations as c, getDockerImageBySourceHash as cn, isMarkedNonRetryable as cr, coerceCfnBoolean as ct, updatePartialReason as d, getDefaultStateBucketName as dn, markNonRetryable as dr, readConfigString as dt, validateContainerRepoName as en, StackHasActiveImportsError as er, IntrinsicFunctionResolver as et, UNSPECIFIED_SKIP_REASON as f, getLegacyStateBucketName as fn, __exportAll as fr, replayWarn as ft, IMPLICIT_DELETE_DEPENDENCIES as g, resolveSkipPrefix as gn, STATE_SOURCED_CROSS_GENERATION_RULES as gt, maskingRetryLogger as h, resolveCaptureObservedState as hn, requireConfigString as ht, DeploymentEventsReader as i, getDockerCmd as in, formatError as ir, WAFv2WebACLProvider as it, formatResourceLine as j, AssemblyReader as jn, describeTypeWithThrottleRetry as jt, isStatefulRecreateTargetSync as k, canonicalizeRegion as kn, DiffCalculator as kt, replayRollback as l, Synthesizer as ln, isRetryableTransientError as lr, configBooleanRefusal as lt, withResourceDeadline as m, resolveAutoAssetStorage as mn, requireConfigObject as mt, DEFAULT_RESOURCE_WARN_AFTER_MS as n, buildDockerImage as nn, StateError as nr, getAccountInfo as nt, planFailedOps as o, runDockerStreaming as on, normalizeAwsError as or, resolveExplicitPhysicalId as ot, deleteSkipReason as p, resolveApp as pn, requireConfigArray as pt, ProviderRegistry as q, LockError as qn, stripControlChars as qt, DeployEngine as r, formatDockerLoginError as rn, SynthesisError as rr, refStateLookupFromResource as rt, planRollback as s, AssetManifestLoader as sn, withErrorHandling as sr, assertRegionMatch as st, DEFAULT_RESOURCE_TIMEOUT_MS as t, buildDenyExternalAccessPolicy as tn, StackTerminationProtectionError as tr, cfnRefValueFromPhysicalId as tt, updatePartialMessage as u, synthesisStatusMessage as un, isThrottlingError as ur, configStringRefusal as ut, ATOMIC_FINAL_SNAPSHOT_TYPES as v, resolveStateBucketWithDefaultAndSource as vn, TEMPLATE_SOURCED_RULES as vt, refusesFinalSnapshot as w, MIGRATE_TMP_PREFIX as wn, s3BucketDomainName as wt, ccRoutedFinalSnapshotError as x, warnDeprecatedNoPrefixCliFlag as xn, redactSecretsForState as xt, PRE_DELETE_SNAPSHOT_TYPES as y, resolveUseCdkBootstrapAssets as yn, createSecretMasker as yt, collectPublishedOutputNames as z, AssetError as zn, AssetPublisher as zt };
27144
- //# sourceMappingURL=deploy-engine-BNujuzW5.js.map
27219
+ //# sourceMappingURL=deploy-engine-CI0a6yLX.js.map