@go-to-k/cdkd 0.276.0 → 0.276.2

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.
@@ -7715,6 +7715,24 @@ var ReplacementRulesRegistry = class {
7715
7715
  "KeyName",
7716
7716
  "NetworkInterfaces"
7717
7717
  ]) });
7718
+ this.rules.set("AWS::EC2::Volume", {
7719
+ replacementProperties: /* @__PURE__ */ new Set([
7720
+ "AvailabilityZone",
7721
+ "AvailabilityZoneId",
7722
+ "Encrypted",
7723
+ "KmsKeyId",
7724
+ "OutpostArn",
7725
+ "SnapshotId"
7726
+ ]),
7727
+ updateableProperties: /* @__PURE__ */ new Set([
7728
+ "AutoEnableIO",
7729
+ "Iops",
7730
+ "Size",
7731
+ "Throughput",
7732
+ "VolumeType",
7733
+ "Tags"
7734
+ ])
7735
+ });
7718
7736
  this.rules.set("AWS::ECS::TaskDefinition", { replacementProperties: /* @__PURE__ */ new Set([
7719
7737
  "Family",
7720
7738
  "ContainerDefinitions",
@@ -12072,7 +12090,7 @@ var CloudControlProvider = class {
12072
12090
  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);
12073
12091
  if (context?.removeProtection === true && resourceType === "AWS::AutoScaling::AutoScalingGroup") {
12074
12092
  this.logger.debug(`Delegating protected AutoScalingGroup ${logicalId} delete to the SDK ASGProvider (Cloud Control cannot force-delete a protected ASG)`);
12075
- const { ASGProvider } = await import("./asg-provider-DeLTuWlm.js").then((n) => n.n);
12093
+ const { ASGProvider } = await import("./asg-provider-X-k9FXgs.js").then((n) => n.n);
12076
12094
  await new ASGProvider().delete(logicalId, physicalId, resourceType, _properties, context);
12077
12095
  return;
12078
12096
  }
@@ -16787,6 +16805,7 @@ const STATEFUL_TYPES = /* @__PURE__ */ new Set([
16787
16805
  "AWS::FSx::FileSystem",
16788
16806
  "AWS::S3::Bucket",
16789
16807
  "AWS::ECR::Repository",
16808
+ "AWS::EC2::Volume",
16790
16809
  "AWS::Kinesis::Stream",
16791
16810
  "AWS::Elasticsearch::Domain",
16792
16811
  "AWS::OpenSearchService::Domain",
@@ -17733,24 +17752,73 @@ async function withResourceDeadline(operation, opts) {
17733
17752
 
17734
17753
  //#endregion
17735
17754
  //#region src/deployment/rollback-executor.ts
17755
+ /** The `--skip-final-snapshot` flag name cited by every refusal below. */
17756
+ const SKIP_FINAL_SNAPSHOT_FLAG = "--skip-final-snapshot";
17757
+ /**
17758
+ * Which provisioning layer a delete must be judged against: the CURRENT
17759
+ * state record wins (it is what state says AWS holds right now), with the
17760
+ * journaled op's routing as the legacy-state fallback. Shared by both
17761
+ * Snapshot paths below so the cc-api test cannot drift between them.
17762
+ */
17763
+ function effectiveProvisionedBy(record, fallbackProvisionedBy) {
17764
+ return record?.provisionedBy ?? fallbackProvisionedBy;
17765
+ }
17736
17766
  /**
17737
17767
  * `UpdateReplacePolicy: Snapshot` on a rollback's delete-of-the-NEW-resource
17738
17768
  * (issue #1354): honor it where it costs nothing — an atomic-final-snapshot
17739
17769
  * type on the SDK route gets a generated identifier threaded into the delete
17740
17770
  * context. Every other Snapshot shape (pre-delete types, cc-api routing)
17741
17771
  * keeps the plain delete DELIBERATELY: the rollback executor's delete-new is
17742
- * load-bearing for same-name re-creation (orphaning would break the revert),
17743
- * it has no snapshot-client plumbing by design (registry + region only), and
17744
- * the new resource was created by the deploy being reverted. Recorded as a
17745
- * scope decision on issue #1354.
17772
+ * load-bearing for same-name re-creation (refusing it would strand the
17773
+ * revert half-done), and the new resource was created by the very deploy
17774
+ * being reverted. Recorded as a scope decision on issue #1354.
17775
+ *
17776
+ * NOT the same call as the rolled-back-CREATE path
17777
+ * ({@link prepareCreateRollbackFinalSnapshot}, issue #1358): there the
17778
+ * resource is being deleted under `DeletionPolicy` and a shape cdkd cannot
17779
+ * snapshot is REFUSED rather than plain-deleted, because the user is losing
17780
+ * a resource that existed before this op — nothing downstream depends on
17781
+ * that delete succeeding.
17746
17782
  */
17747
17783
  function rollbackFinalSnapshotId(resourceType, record, fallbackProvisionedBy) {
17748
17784
  if (record.updateReplacePolicy !== "Snapshot") return void 0;
17749
17785
  if (!ATOMIC_FINAL_SNAPSHOT_TYPES.has(resourceType)) return void 0;
17750
- if ((record.provisionedBy ?? fallbackProvisionedBy) === "cc-api") return void 0;
17786
+ if (effectiveProvisionedBy(record, fallbackProvisionedBy) === "cc-api") return void 0;
17751
17787
  return buildFinalSnapshotIdentifier(record.physicalId, resourceType);
17752
17788
  }
17753
17789
  /**
17790
+ * `DeletionPolicy: Snapshot` on a rolled-back CREATE (issue #1358) — the
17791
+ * executor's copy of the deploy engine's `prepareFinalSnapshotForDelete`
17792
+ * mechanism matrix, run BEFORE the delete:
17793
+ *
17794
+ * - atomic type, SDK-routed → returns the generated identifier for the
17795
+ * provider's atomic final-snapshot delete parameter.
17796
+ * - atomic type, cc-api-routed → refuses (Cloud Control's DeleteResource
17797
+ * has no final-snapshot parameter; `CloudControlProvider.delete` also
17798
+ * fail-closes on the context field as defense-in-depth).
17799
+ * - `PRE_DELETE_SNAPSHOT_TYPES` → creates the snapshot and waits for it
17800
+ * here, then returns undefined (the subsequent delete is plain).
17801
+ * - anything else Snapshot-tagged → refuses.
17802
+ *
17803
+ * Refusals are plain throws so `replaySingle`'s per-op catch counts them as
17804
+ * a failure (which blocks the segment pop and keeps the journal for a
17805
+ * re-run) — deliberately NOT a silent fall-back to orphaning, which is the
17806
+ * very leak #1358 fixes.
17807
+ */
17808
+ async function prepareCreateRollbackFinalSnapshot(op, provisionedBy, ctx) {
17809
+ const { logicalId, resourceType } = op;
17810
+ const physicalId = op.physicalId;
17811
+ if (ATOMIC_FINAL_SNAPSHOT_TYPES.has(resourceType)) {
17812
+ if (provisionedBy === "cc-api") throw ccRoutedFinalSnapshotError(logicalId, resourceType, SKIP_FINAL_SNAPSHOT_FLAG);
17813
+ return buildFinalSnapshotIdentifier(physicalId, resourceType);
17814
+ }
17815
+ if (PRE_DELETE_SNAPSHOT_TYPES.has(resourceType)) {
17816
+ await createPreDeleteFinalSnapshot(resourceType, physicalId, logicalId, ctx.finalSnapshotClients ?? getAwsClients(), ctx.logger);
17817
+ return;
17818
+ }
17819
+ throw unsupportedFinalSnapshotError(logicalId, resourceType, SKIP_FINAL_SNAPSHOT_FLAG);
17820
+ }
17821
+ /**
17754
17822
  * Retry schedule for a re-create that must wait out a name-release delay:
17755
17823
  * an async delete's late name release ("already exists") or the SQS 60s
17756
17824
  * same-name cooldown (issue #1206). 2s/4s/8s then capped at 10s over 8
@@ -17803,7 +17871,8 @@ function classifyRollbackOp(op, stateResources, orphanLogicalIds) {
17803
17871
  if (!current) return "skip-already-done";
17804
17872
  if (op.physicalId !== void 0 && current.physicalId !== op.physicalId) return "skip-mismatch";
17805
17873
  const policy = current.deletionPolicy;
17806
- if (policy === "Retain" || policy === "Snapshot") return "orphan-retain";
17874
+ if (policy === "Retain") return "orphan-retain";
17875
+ if (policy === "Snapshot") return "delete-with-final-snapshot";
17807
17876
  return "delete";
17808
17877
  }
17809
17878
  const current = stateResources[op.logicalId];
@@ -17957,7 +18026,7 @@ async function replaySingle(op, stateResources, stackName, ctx, orphanLogicalIds
17957
18026
  return;
17958
18027
  case "orphan-retain":
17959
18028
  delete stateResources[op.logicalId];
17960
- logger.info(` Rollback: Leaving ${op.logicalId} (${op.resourceType}) in AWS (DeletionPolicy: ${stateResourcesPolicyLabel(op, stateResources)}) — removed from state`);
18029
+ logger.info(` Rollback: Leaving ${op.logicalId} (${op.resourceType}) in AWS (DeletionPolicy: Retain) — removed from state`);
17961
18030
  await afterOp?.(op.logicalId);
17962
18031
  ctx.recordEvent?.({
17963
18032
  eventType: "ROLLBACK_RESOURCE_SUCCEEDED",
@@ -17968,18 +18037,27 @@ async function replaySingle(op, stateResources, stackName, ctx, orphanLogicalIds
17968
18037
  ...op.provisionedBy && { provisionedBy: op.provisionedBy }
17969
18038
  });
17970
18039
  return;
17971
- case "delete": {
18040
+ case "delete":
18041
+ case "delete-with-final-snapshot": {
17972
18042
  if (!op.physicalId) {
17973
18043
  logger.warn(` Rollback: Cannot delete ${op.logicalId} — no physical ID recorded`);
17974
18044
  result.warnings++;
17975
18045
  return;
17976
18046
  }
17977
- logger.info(` Rollback: Deleting created resource ${op.logicalId} (${op.resourceType})`);
18047
+ const deleteProvisionedBy = effectiveProvisionedBy(stateResources[op.logicalId], op.provisionedBy);
18048
+ const snapshotPolicy = action === "delete-with-final-snapshot";
18049
+ const takeFinalSnapshot = snapshotPolicy && ctx.skipFinalSnapshot !== true;
18050
+ let finalSnapshotIdentifier;
18051
+ if (takeFinalSnapshot) finalSnapshotIdentifier = await prepareCreateRollbackFinalSnapshot(op, deleteProvisionedBy, ctx);
18052
+ logger.info(` Rollback: Deleting created resource ${op.logicalId} (${op.resourceType})` + (takeFinalSnapshot ? " — DeletionPolicy: Snapshot" : "") + (snapshotPolicy && !takeFinalSnapshot ? " — DeletionPolicy: Snapshot NOT taken (--skip-final-snapshot)" : ""));
17978
18053
  const { provider } = ctx.providerRegistry.getProviderFor({
17979
18054
  resourceType: op.resourceType,
17980
- provisionedBy: op.provisionedBy
18055
+ provisionedBy: deleteProvisionedBy
18056
+ });
18057
+ await provider.delete(op.logicalId, op.physicalId, op.resourceType, op.properties, {
18058
+ expectedRegion: ctx.region,
18059
+ ...finalSnapshotIdentifier !== void 0 && { finalSnapshotIdentifier }
17981
18060
  });
17982
- await provider.delete(op.logicalId, op.physicalId, op.resourceType, op.properties, { expectedRegion: ctx.region });
17983
18061
  delete stateResources[op.logicalId];
17984
18062
  logger.info(` Rollback: ${op.logicalId} deleted successfully`);
17985
18063
  await afterOp?.(op.logicalId);
@@ -18262,9 +18340,6 @@ async function replayFailedOperations(failedOps, stateResources, stackName, ctx,
18262
18340
  result.remainingFailedOps = failedOps.filter((op) => pending.has(op));
18263
18341
  return result;
18264
18342
  }
18265
- function stateResourcesPolicyLabel(op, stateResources) {
18266
- return stateResources[op.logicalId]?.deletionPolicy ?? "Retain";
18267
- }
18268
18343
  /**
18269
18344
  * Sort CREATE rollback operations so that resources depending on others are
18270
18345
  * deleted first (reverse dependency order), using state dependencies. Same
@@ -18354,7 +18429,7 @@ const FLUSH_INTERVAL_MS = 2e3;
18354
18429
  const FLUSH_EVENT_THRESHOLD = 50;
18355
18430
  /** Build-time cdkd version, with a dev fallback for non-built contexts. */
18356
18431
  function getCdkdVersion() {
18357
- return "0.276.0";
18432
+ return "0.276.2";
18358
18433
  }
18359
18434
  /**
18360
18435
  * Generate a time-sortable unique run id, e.g.
@@ -19746,7 +19821,9 @@ var DeployEngine = class {
19746
19821
  providerRegistry: this.providerRegistry,
19747
19822
  region: this.stackRegion,
19748
19823
  logger: this.logger,
19749
- recordEvent: (event) => this.recordEvent(event)
19824
+ recordEvent: (event) => this.recordEvent(event),
19825
+ finalSnapshotClients: this.options.finalSnapshotClients,
19826
+ skipFinalSnapshot: this.options.skipFinalSnapshot
19750
19827
  };
19751
19828
  }
19752
19829
  /**
@@ -20464,4 +20541,4 @@ var DeployEngine = class {
20464
20541
 
20465
20542
  //#endregion
20466
20543
  export { TemplateParser as $, CdkdError as $t, yellow as A, resolveAutoAssetStorage as At, IntrinsicFunctionResolver as B, MIGRATE_TMP_PREFIX as Bt, renderStatefulReason as C, AssetManifestLoader as Ct, gray as D, getDefaultStateBucketName as Dt, cyan as E, synthesisStatusMessage as Et, findActionableSilentDrops as F, resolveUseCdkBootstrapAssets as Ft, resolveExplicitPhysicalId as G, processStackMessages as Gt, refStateLookupFromResource as H, uploadCfnTemplate as Ht, CloudControlProvider as I, stateBucketExistenceConfirmed as It, DiffCalculator as J, AwsClients as Jt, assertRegionMatch as K, clearBucketRegionCache as Kt, slowCcOperationTimeoutMs as L, warnDeprecatedNoPrefixCliFlag as Lt, collectInlinePolicyNamesManagedBySiblings as M, resolveSkipPrefix as Mt, clearOnUpdateRemoval as N, resolveStateBucketWithDefault as Nt, green as O, getLegacyStateBucketName as Ot, ProviderRegistry as P, resolveStateBucketWithDefaultAndSource as Pt, DagBuilder as Q, AssetError as Qt, disableInstanceApiTermination as R, CFN_TEMPLATE_BODY_LIMIT as Rt, isStatefulRecreateTargetSync as S, runDockerStreaming as St, bold as T, Synthesizer as Tt, WAFv2WebACLProvider as U, expectedOwnerParam as Ut, cfnRefValueFromPhysicalId as V, findLargeInlineResources as Vt, normalizeAwsTagsToCfn as W, AssemblyReader as Wt, withRetry as X, resetAwsClients as Xt, describeTypeWithThrottleRetry as Y, getAwsClients as Yt, isRetryableTransientError as Z, setAwsClients as Zt, createPreDeleteFinalSnapshot as _, formatError as _n, validateContainerRepoName as _t, DeploymentEventsStore as a, LocalStartServiceError as an, stringifyValue as at, extractDeploymentEventError as b, withErrorHandling as bn, getDockerCmd as bt, replayFailedOperations as c, NestedStackChildDirectDestroyError as cn, createAssetRedirectResolver as ct, IMPLICIT_DELETE_DEPENDENCIES as d, ResourceTimeoutError as dn, AssetModeResolver as dt, ConfigError as en, LockManager as et, computeImplicitDeleteEdges as f, ResourceUpdateNotSupportedError as fn, BOOTSTRAP_MARKER_PREFIX as ft, ccRoutedFinalSnapshotError as g, SynthesisError as gn, validateAssetBucketName as gt, buildFinalSnapshotIdentifier as h, StateError as hn, parseBootstrapMarker as ht, DeploymentEventsReader as i, LocalMigrateError as in, AssetPublisher as it, IAMRoleProvider as j, resolveCaptureObservedState as jt, red as k, resolveApp as kt, replayRollback as l, PartialFailureError as ln, loadPublishableAssetManifest as lt, PRE_DELETE_SNAPSHOT_TYPES as m, StackTerminationProtectionError as mn, getBootstrapMarkerKey as mt, DEFAULT_RESOURCE_WARN_AFTER_MS as n, DeployCancelledError as nn, rebuildClientForBucketRegion as nt, planFailedOps as o, LockError as on, WorkGraph as ot, ATOMIC_FINAL_SNAPSHOT_TYPES as p, StackHasActiveImportsError as pn, ensureAssetStorage as pt, applyRoleArnIfSet as q, resolveBucketRegion as qt, DeployEngine as r, LocalInvokeBuildError as rn, shouldRetainResource as rt, planRollback as s, MissingCdkCliError as sn, buildAssetRedirectMap as st, DEFAULT_RESOURCE_TIMEOUT_MS as t, DependencyError as tn, S3StateBackend as tt, withResourceDeadline as u, ProvisioningError as un, rewriteTemplateAssetReferences as ut, isFinalSnapshotError as v, isCdkdError as vn, buildDockerImage as vt, formatResourceLine as w, getDockerImageBySourceHash as wt, MULTI_REGION_RECREATE_BLOCKED_TYPES as x, __exportAll as xn, runDockerForeground as xt, unsupportedFinalSnapshotError as y, normalizeAwsError as yn, formatDockerLoginError as yt, isTerminationProtectionPropagationError as z, CFN_TEMPLATE_URL_LIMIT as zt };
20467
- //# sourceMappingURL=deploy-engine-j0TmnJYJ.js.map
20544
+ //# sourceMappingURL=deploy-engine-CwVBPKqE.js.map