@go-to-k/cdkd 0.230.27 → 0.230.29
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +3 -3
- package/dist/{deploy-engine-BERaDgMo.js → deploy-engine-pdCBIFCK.js} +164 -20
- package/dist/deploy-engine-pdCBIFCK.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/package.json +1 -1
- package/dist/deploy-engine-BERaDgMo.js.map +0 -1
package/dist/cli.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { A as withErrorHandling, B as generateResourceName, C as StackHasActiveImportsError, F as getLiveRenderer, H as withSkipPrefix, I as PATTERN_B_NAME_OPTIONS, L as PATTERN_B_NAME_PROPERTIES, M as getLogger, P as runStackBuffered, R as PATTERN_B_RESOURCE_TYPES, S as ResourceUpdateNotSupportedError, U as withStackName, V as generateResourceNameWithFallback, _ as MissingCdkCliError, a as assertRegionMatch, b as ProvisioningError, f as LocalInvokeBuildError$1, i as resolveExplicitPhysicalId, k as normalizeAwsError, l as CdkdError, m as LocalStartServiceError, n as matchesCdkPath, o as disableInstanceApiTermination, p as LocalMigrateError, r as normalizeAwsTagsToCfn, s as isTerminationProtectionPropagationError, t as CDK_PATH_TAG, v as NestedStackChildDirectDestroyError, w as StackTerminationProtectionError, x as ResourceTimeoutError, y as PartialFailureError } from "./import-helpers-DayvBD4T.js";
|
|
3
3
|
import { a as setAwsClients, i as resetAwsClients, r as getAwsClients, t as AwsClients } from "./aws-clients-pjPwZz1r.js";
|
|
4
|
-
import { $ as resolveStateBucketWithDefaultAndSource, A as TemplateParser, B as getDockerCmd, C as findActionableSilentDrops, D as applyRoleArnIfSet, E as cfnRefValueFromPhysicalId, F as AssetPublisher, G as Synthesizer, H as runDockerStreaming, I as stringifyValue, J as getLegacyStateBucketName, K as synthesisStatusMessage, L as WorkGraph, M as S3StateBackend, N as rebuildClientForBucketRegion, O as DiffCalculator, P as shouldRetainResource, Q as resolveStateBucketWithDefault, R as buildDockerImage, S as ProviderRegistry, T as IntrinsicFunctionResolver, U as AssetManifestLoader, V as runDockerForeground, W as getDockerImageBySourceHash, X as resolveCaptureObservedState, Y as resolveApp, Z as resolveSkipPrefix, _ as green, a as withRetry, at as uploadCfnTemplate, b as IAMRoleProvider, c as computeImplicitDeleteEdges, ct as resolveBucketRegion, d as isStatefulRecreateTargetSync, et as warnDeprecatedNoPrefixCliFlag, f as renderStatefulReason, g as gray, h as cyan, i as withResourceDeadline, it as findLargeInlineResources, j as LockManager, k as DagBuilder, l as extractDeploymentEventError, m as bold, n as DEFAULT_RESOURCE_WARN_AFTER_MS, nt as CFN_TEMPLATE_URL_LIMIT, o as isRetryableTransientError, ot as AssemblyReader, p as formatResourceLine, q as getDefaultStateBucketName, r as DeployEngine, rt as MIGRATE_TMP_PREFIX, s as IMPLICIT_DELETE_DEPENDENCIES, t as DEFAULT_RESOURCE_TIMEOUT_MS, tt as CFN_TEMPLATE_BODY_LIMIT, u as MULTI_REGION_RECREATE_BLOCKED_TYPES, v as red, w as CloudControlProvider, x as collectInlinePolicyNamesManagedBySiblings, y as yellow, z as formatDockerLoginError } from "./deploy-engine-
|
|
4
|
+
import { $ as resolveStateBucketWithDefaultAndSource, A as TemplateParser, B as getDockerCmd, C as findActionableSilentDrops, D as applyRoleArnIfSet, E as cfnRefValueFromPhysicalId, F as AssetPublisher, G as Synthesizer, H as runDockerStreaming, I as stringifyValue, J as getLegacyStateBucketName, K as synthesisStatusMessage, L as WorkGraph, M as S3StateBackend, N as rebuildClientForBucketRegion, O as DiffCalculator, P as shouldRetainResource, Q as resolveStateBucketWithDefault, R as buildDockerImage, S as ProviderRegistry, T as IntrinsicFunctionResolver, U as AssetManifestLoader, V as runDockerForeground, W as getDockerImageBySourceHash, X as resolveCaptureObservedState, Y as resolveApp, Z as resolveSkipPrefix, _ as green, a as withRetry, at as uploadCfnTemplate, b as IAMRoleProvider, c as computeImplicitDeleteEdges, ct as resolveBucketRegion, d as isStatefulRecreateTargetSync, et as warnDeprecatedNoPrefixCliFlag, f as renderStatefulReason, g as gray, h as cyan, i as withResourceDeadline, it as findLargeInlineResources, j as LockManager, k as DagBuilder, l as extractDeploymentEventError, m as bold, n as DEFAULT_RESOURCE_WARN_AFTER_MS, nt as CFN_TEMPLATE_URL_LIMIT, o as isRetryableTransientError, ot as AssemblyReader, p as formatResourceLine, q as getDefaultStateBucketName, r as DeployEngine, rt as MIGRATE_TMP_PREFIX, s as IMPLICIT_DELETE_DEPENDENCIES, t as DEFAULT_RESOURCE_TIMEOUT_MS, tt as CFN_TEMPLATE_BODY_LIMIT, u as MULTI_REGION_RECREATE_BLOCKED_TYPES, v as red, w as CloudControlProvider, x as collectInlinePolicyNamesManagedBySiblings, y as yellow, z as formatDockerLoginError } from "./deploy-engine-pdCBIFCK.js";
|
|
5
5
|
import { t as ASGProvider } from "./asg-provider-Dgj3loIG.js";
|
|
6
6
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
7
7
|
import { createHash, randomBytes, randomUUID } from "node:crypto";
|
|
@@ -1445,7 +1445,7 @@ const FLUSH_INTERVAL_MS = 2e3;
|
|
|
1445
1445
|
const FLUSH_EVENT_THRESHOLD = 50;
|
|
1446
1446
|
/** Build-time cdkd version, with a dev fallback for non-built contexts. */
|
|
1447
1447
|
function getCdkdVersion() {
|
|
1448
|
-
return "0.230.
|
|
1448
|
+
return "0.230.29";
|
|
1449
1449
|
}
|
|
1450
1450
|
/**
|
|
1451
1451
|
* Generate a time-sortable unique run id, e.g.
|
|
@@ -55430,7 +55430,7 @@ function reorderArgs(argv) {
|
|
|
55430
55430
|
async function main() {
|
|
55431
55431
|
installPipeCloseHandler();
|
|
55432
55432
|
const program = new Command();
|
|
55433
|
-
program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.230.
|
|
55433
|
+
program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.230.29");
|
|
55434
55434
|
program.addCommand(createBootstrapCommand());
|
|
55435
55435
|
program.addCommand(createSynthCommand());
|
|
55436
55436
|
program.addCommand(createListCommand());
|
|
@@ -5203,48 +5203,126 @@ var ReplacementRulesRegistry = class {
|
|
|
5203
5203
|
*/
|
|
5204
5204
|
const createOnlyPropertiesCache = /* @__PURE__ */ new Map();
|
|
5205
5205
|
/**
|
|
5206
|
-
* Resolve the
|
|
5207
|
-
*
|
|
5206
|
+
* Resolve the create-only (immutable) property PATHS for a resource type,
|
|
5207
|
+
* each as the segment array after `/properties/` (e.g.
|
|
5208
|
+
* `['Name']`, `['SourceParameters', 'KinesisStreamParameters',
|
|
5209
|
+
* 'StartingPosition']`).
|
|
5210
|
+
*
|
|
5211
|
+
* Full paths — not top-level reductions — because reducing a NESTED
|
|
5212
|
+
* createOnly entry to its top-level container over-approximates: for
|
|
5213
|
+
* `AWS::Pipes::Pipe`, `SourceParameters` itself is mutable and only
|
|
5214
|
+
* stream-source sub-paths under it are createOnly, so an SQS pipe's
|
|
5215
|
+
* `SourceParameters.SqsQueueParameters.BatchSize` change (CFn: "No
|
|
5216
|
+
* interruption") was mis-classified as a replacement (issue #960). The diff
|
|
5217
|
+
* consults {@link createOnlyChangeRequiresReplacement} to compare at the
|
|
5218
|
+
* schema's actual path granularity.
|
|
5208
5219
|
*
|
|
5209
5220
|
* Never throws: a DescribeType failure logs a warning and resolves to an empty
|
|
5210
|
-
*
|
|
5221
|
+
* list (graceful fallback to the registry-only classification). Only SUCCESSFUL
|
|
5211
5222
|
* lookups are cached per resource type for the process lifetime; a failed
|
|
5212
5223
|
* lookup is NOT cached, so a later call for the same type retries DescribeType
|
|
5213
5224
|
* (a transient throttle must not poison the deploy's replacement detection).
|
|
5214
5225
|
*/
|
|
5215
|
-
function
|
|
5226
|
+
function getCreateOnlyPropertyPaths(resourceType) {
|
|
5216
5227
|
const cached = createOnlyPropertiesCache.get(resourceType);
|
|
5217
5228
|
if (cached) return cached;
|
|
5218
|
-
const entry =
|
|
5229
|
+
const entry = fetchCreateOnlyPropertyPaths(resourceType).catch((error) => {
|
|
5219
5230
|
createOnlyPropertiesCache.delete(resourceType);
|
|
5220
5231
|
const message = error instanceof Error ? error.message : String(error);
|
|
5221
5232
|
getLogger().child("CreateOnlyProperties").warn(`Failed to resolve create-only properties for ${resourceType} via cloudformation:DescribeType (${message}). Falling back to the registry-only replacement classification for this resource — an immutable-property change may be mis-classified as an in-place update. Grant cloudformation:DescribeType to enable schema-driven replacement detection.`);
|
|
5222
|
-
return
|
|
5233
|
+
return [];
|
|
5223
5234
|
});
|
|
5224
5235
|
createOnlyPropertiesCache.set(resourceType, entry);
|
|
5225
5236
|
return entry;
|
|
5226
5237
|
}
|
|
5227
5238
|
/**
|
|
5228
|
-
*
|
|
5229
|
-
*
|
|
5230
|
-
*
|
|
5239
|
+
* Decide whether a change to top-level property `topLevelKey` requires
|
|
5240
|
+
* replacement per the schema's createOnly paths.
|
|
5241
|
+
*
|
|
5242
|
+
* - A length-1 path (`['Name']`) marks the whole property createOnly — any
|
|
5243
|
+
* change replaces (the pre-#960 behavior).
|
|
5244
|
+
* - A nested path (`['SourceParameters', ..., 'StartingPosition']`) replaces
|
|
5245
|
+
* ONLY when the value AT that nested path differs between old and new —
|
|
5246
|
+
* sibling sub-properties stay in-place-updatable, matching CloudFormation's
|
|
5247
|
+
* per-path "Update requires: Replacement" annotations.
|
|
5248
|
+
* - A path that cannot be resolved against the values (an array or scalar
|
|
5249
|
+
* where an object was expected, or a `*` wildcard segment) is treated
|
|
5250
|
+
* conservatively as changed — replacement — since we cannot prove the
|
|
5251
|
+
* immutable part stayed equal.
|
|
5252
|
+
*
|
|
5253
|
+
* Pure and synchronous so it is unit-testable without the DescribeType
|
|
5254
|
+
* plumbing; `valuesEqual` is injected by the diff calculator so nested
|
|
5255
|
+
* comparisons use the same equality as the top-level diff.
|
|
5256
|
+
*/
|
|
5257
|
+
function createOnlyChangeRequiresReplacement(createOnlyPaths, topLevelKey, oldValue, newValue, valuesEqual) {
|
|
5258
|
+
for (const path of createOnlyPaths) {
|
|
5259
|
+
if (path[0] !== topLevelKey) continue;
|
|
5260
|
+
if (path.length === 1) return true;
|
|
5261
|
+
const oldSub = valueAtPath(oldValue, path.slice(1));
|
|
5262
|
+
const newSub = valueAtPath(newValue, path.slice(1));
|
|
5263
|
+
if (!oldSub.resolved || !newSub.resolved) return true;
|
|
5264
|
+
if (!valuesEqual(oldSub.value, newSub.value)) return true;
|
|
5265
|
+
}
|
|
5266
|
+
return false;
|
|
5267
|
+
}
|
|
5268
|
+
/**
|
|
5269
|
+
* Walk `value` along `segments` of plain-object keys.
|
|
5270
|
+
*
|
|
5271
|
+
* An absent container (`undefined` / `null`) RESOLVES to `undefined` — that
|
|
5272
|
+
* is the load-bearing case: an SQS pipe has no `DynamoDBStreamParameters`
|
|
5273
|
+
* subtree on either side, so its stream-source createOnly paths compare
|
|
5274
|
+
* `undefined === undefined` and do not force a replacement. Only shapes we
|
|
5275
|
+
* cannot meaningfully traverse (arrays / scalars where an object is
|
|
5276
|
+
* expected, `*` wildcard segments) report unresolved, which the caller
|
|
5277
|
+
* treats conservatively.
|
|
5278
|
+
*/
|
|
5279
|
+
function valueAtPath(value, segments) {
|
|
5280
|
+
let current = value;
|
|
5281
|
+
for (const segment of segments) {
|
|
5282
|
+
if (segment === "*") return { resolved: false };
|
|
5283
|
+
if (current === void 0 || current === null) return {
|
|
5284
|
+
resolved: true,
|
|
5285
|
+
value: void 0
|
|
5286
|
+
};
|
|
5287
|
+
if (typeof current !== "object" || Array.isArray(current)) return { resolved: false };
|
|
5288
|
+
if (isIntrinsicShaped(current)) return { resolved: false };
|
|
5289
|
+
current = current[segment];
|
|
5290
|
+
}
|
|
5291
|
+
return {
|
|
5292
|
+
resolved: true,
|
|
5293
|
+
value: current
|
|
5294
|
+
};
|
|
5295
|
+
}
|
|
5296
|
+
/**
|
|
5297
|
+
* True for a single-key object whose key is `Ref` or `Fn::*` — the shape of
|
|
5298
|
+
* an unresolved CloudFormation intrinsic.
|
|
5299
|
+
*/
|
|
5300
|
+
function isIntrinsicShaped(value) {
|
|
5301
|
+
const keys = Object.keys(value);
|
|
5302
|
+
return keys.length === 1 && (keys[0] === "Ref" || keys[0].startsWith("Fn::"));
|
|
5303
|
+
}
|
|
5304
|
+
/**
|
|
5305
|
+
* Fetch + parse the type's create-only property paths. THROWS on a
|
|
5306
|
+
* DescribeType failure — the caller ({@link getCreateOnlyPropertyPaths})
|
|
5307
|
+
* catches, warns, and declines to cache so the lookup can be retried later.
|
|
5231
5308
|
*/
|
|
5232
|
-
async function
|
|
5309
|
+
async function fetchCreateOnlyPropertyPaths(resourceType) {
|
|
5233
5310
|
const logger = getLogger().child("CreateOnlyProperties");
|
|
5234
5311
|
const response = await getAwsClients().cloudFormation.send(new DescribeTypeCommand({
|
|
5235
5312
|
Type: "RESOURCE",
|
|
5236
5313
|
TypeName: resourceType
|
|
5237
5314
|
}));
|
|
5238
|
-
const result =
|
|
5315
|
+
const result = [];
|
|
5239
5316
|
if (response.Schema) {
|
|
5240
5317
|
const createOnly = JSON.parse(response.Schema).createOnlyProperties;
|
|
5241
5318
|
if (Array.isArray(createOnly)) for (const path of createOnly) {
|
|
5242
5319
|
if (typeof path !== "string") continue;
|
|
5243
|
-
|
|
5244
|
-
|
|
5320
|
+
if (!path.startsWith("/properties/")) continue;
|
|
5321
|
+
const segments = path.slice(12).split("/").map(unescapeJsonPointerSegment$1).filter((segment) => segment.length > 0);
|
|
5322
|
+
if (segments.length > 0) result.push(segments);
|
|
5245
5323
|
}
|
|
5246
5324
|
}
|
|
5247
|
-
logger.debug(`Resolved ${result.
|
|
5325
|
+
logger.debug(`Resolved ${result.length} create-only property paths for ${resourceType}` + (result.length > 0 ? `: ${result.map((p) => p.join(".")).join(", ")}` : ""));
|
|
5248
5326
|
return result;
|
|
5249
5327
|
}
|
|
5250
5328
|
/**
|
|
@@ -5639,7 +5717,7 @@ var DiffCalculator = class DiffCalculator {
|
|
|
5639
5717
|
const allKeys = new Set([...Object.keys(currentProperties), ...Object.keys(desiredProperties)]);
|
|
5640
5718
|
const ignoredProperties = /* @__PURE__ */ new Set();
|
|
5641
5719
|
if (resourceType === "AWS::CloudFormation::CustomResource" || resourceType.startsWith("Custom::")) ignoredProperties.add("Timestamp");
|
|
5642
|
-
let
|
|
5720
|
+
let createOnlyPaths;
|
|
5643
5721
|
for (const key of allKeys) {
|
|
5644
5722
|
if (ignoredProperties.has(key)) continue;
|
|
5645
5723
|
const oldValue = currentProperties[key];
|
|
@@ -5647,10 +5725,10 @@ var DiffCalculator = class DiffCalculator {
|
|
|
5647
5725
|
if (!this.valuesEqual(oldValue, newValue)) {
|
|
5648
5726
|
let requiresReplacement = this.replacementRules.requiresReplacement(resourceType, key, oldValue, newValue);
|
|
5649
5727
|
if (!requiresReplacement && !this.replacementRules.isClassified(resourceType, key)) {
|
|
5650
|
-
if (
|
|
5651
|
-
if (
|
|
5728
|
+
if (createOnlyPaths === void 0) createOnlyPaths = await getCreateOnlyPropertyPaths(resourceType);
|
|
5729
|
+
if (createOnlyChangeRequiresReplacement(createOnlyPaths, key, oldValue, newValue, (a, b) => this.valuesEqual(a, b))) {
|
|
5652
5730
|
requiresReplacement = true;
|
|
5653
|
-
this.logger.debug(`Property ${key} of ${resourceType}
|
|
5731
|
+
this.logger.debug(`Property ${key} of ${resourceType} changed a createOnly path per the CFn schema — requires replacement`);
|
|
5654
5732
|
}
|
|
5655
5733
|
}
|
|
5656
5734
|
changes.push({
|
|
@@ -7956,6 +8034,28 @@ function stripNullValues(obj) {
|
|
|
7956
8034
|
}
|
|
7957
8035
|
return obj;
|
|
7958
8036
|
}
|
|
8037
|
+
/**
|
|
8038
|
+
* Thrown when a Cloud Control operation's async progress event reports
|
|
8039
|
+
* FAILED. Carries the handler-reported `ErrorCode` and the operation kind so
|
|
8040
|
+
* the CREATE path can distinguish "our CreateResource materialized a resource
|
|
8041
|
+
* and then failed stabilization" (the remnant must be deleted or every outer
|
|
8042
|
+
* retry collides with AlreadyExists — surfaced by AWS::Synthetics::Canary,
|
|
8043
|
+
* whose create materializes the canary before the IAM-propagation race lands
|
|
8044
|
+
* it in ERROR state) from "the resource already existed before this create"
|
|
8045
|
+
* (`ErrorCode: AlreadyExists` — deleting by that identifier would destroy a
|
|
8046
|
+
* pre-existing user resource, so it is never cleaned up).
|
|
8047
|
+
*/
|
|
8048
|
+
var CloudControlOperationFailedError = class CloudControlOperationFailedError extends ProvisioningError {
|
|
8049
|
+
ccErrorCode;
|
|
8050
|
+
ccOperation;
|
|
8051
|
+
constructor(message, resourceType, logicalId, physicalId, ccErrorCode, ccOperation) {
|
|
8052
|
+
super(message, resourceType, logicalId, physicalId);
|
|
8053
|
+
this.ccErrorCode = ccErrorCode;
|
|
8054
|
+
this.ccOperation = ccOperation;
|
|
8055
|
+
this.name = "CloudControlOperationFailedError";
|
|
8056
|
+
Object.setPrototypeOf(this, CloudControlOperationFailedError.prototype);
|
|
8057
|
+
}
|
|
8058
|
+
};
|
|
7959
8059
|
var CloudControlProvider = class {
|
|
7960
8060
|
cloudControlClient;
|
|
7961
8061
|
logger = getLogger().child("CloudControlProvider");
|
|
@@ -7990,10 +8090,54 @@ var CloudControlProvider = class {
|
|
|
7990
8090
|
result.attributes = await this.enrichResourceAttributes(resourceType, progressEvent.Identifier, result.attributes || {});
|
|
7991
8091
|
return result;
|
|
7992
8092
|
} catch (error) {
|
|
8093
|
+
await this.cleanupFailedCreateRemnant(error, resourceType, logicalId);
|
|
7993
8094
|
this.handleError(error, "CREATE", resourceType, logicalId);
|
|
7994
8095
|
}
|
|
7995
8096
|
}
|
|
7996
8097
|
/**
|
|
8098
|
+
* Best-effort deletion of the physical resource a FAILED async CREATE left
|
|
8099
|
+
* behind.
|
|
8100
|
+
*
|
|
8101
|
+
* Some Cloud Control create handlers materialize the resource first and
|
|
8102
|
+
* stabilize it afterwards (e.g. `AWS::Synthetics::Canary` creates the canary
|
|
8103
|
+
* entity, then builds its backing Lambda). When stabilization fails — most
|
|
8104
|
+
* commonly the just-created-IAM-role propagation race cdkd's fast path is
|
|
8105
|
+
* prone to — the FAILED progress event carries the materialized resource's
|
|
8106
|
+
* `Identifier`, but the half-created remnant keeps occupying the name. The
|
|
8107
|
+
* deploy engine's outer `withRetry` then re-invokes `create()` (the
|
|
8108
|
+
* stabilization message matches the transient-error patterns) and every
|
|
8109
|
+
* retry fails with `AlreadyExists` instead of recovering, and the remnant is
|
|
8110
|
+
* ALSO invisible to rollback (the create never returned, so it is not in
|
|
8111
|
+
* state) — an orphan CloudFormation would have deleted on rollback.
|
|
8112
|
+
*
|
|
8113
|
+
* Deleting the remnant here restores both behaviors: the next retry starts
|
|
8114
|
+
* with a free name (and succeeds once AWS stabilizes), and a final failure
|
|
8115
|
+
* leaves nothing behind.
|
|
8116
|
+
*
|
|
8117
|
+
* Safety: never fires when the handler reported `ErrorCode: AlreadyExists`
|
|
8118
|
+
* — there the identifier names a resource that pre-dates this create (our
|
|
8119
|
+
* CreateCanary repro's SECOND attempt reported exactly that shape), and
|
|
8120
|
+
* deleting it would destroy a user's pre-existing resource. Handlers may
|
|
8121
|
+
* also stuff a speculative identifier into a FAILED event without having
|
|
8122
|
+
* materialized anything (observed on `AWS::CodeDeploy::DeploymentGroup`);
|
|
8123
|
+
* the delete then no-ops via the NotFound-idempotent path. Cleanup failures
|
|
8124
|
+
* are warned, not thrown — the original create error must surface.
|
|
8125
|
+
*/
|
|
8126
|
+
async cleanupFailedCreateRemnant(error, resourceType, logicalId) {
|
|
8127
|
+
if (!(error instanceof CloudControlOperationFailedError)) return;
|
|
8128
|
+
if (error.ccOperation !== "CREATE" || !error.physicalId) return;
|
|
8129
|
+
if (error.ccErrorCode === "AlreadyExists") return;
|
|
8130
|
+
if (error.ccErrorCode === "ResourceConflict") return;
|
|
8131
|
+
this.logger.info(`CREATE of ${logicalId} failed after materializing ${error.physicalId}; deleting the remnant so a retry can re-create it`);
|
|
8132
|
+
try {
|
|
8133
|
+
await this.delete(logicalId, error.physicalId, resourceType);
|
|
8134
|
+
this.logger.debug(`Removed failed-create remnant ${error.physicalId} for ${logicalId}`);
|
|
8135
|
+
} catch (cleanupError) {
|
|
8136
|
+
const message = cleanupError instanceof Error ? cleanupError.message : String(cleanupError);
|
|
8137
|
+
this.logger.warn(`Failed to delete the remnant ${error.physicalId} left by the failed CREATE of ${logicalId}: ${message} — a retry may fail with AlreadyExists until it is removed manually`);
|
|
8138
|
+
}
|
|
8139
|
+
}
|
|
8140
|
+
/**
|
|
7997
8141
|
* Update a resource using Cloud Control API
|
|
7998
8142
|
*/
|
|
7999
8143
|
async update(logicalId, physicalId, resourceType, properties, previousProperties) {
|
|
@@ -8113,7 +8257,7 @@ var CloudControlProvider = class {
|
|
|
8113
8257
|
this.logger.debug(`${operation} ${logicalId}: ${progressEvent.OperationStatus} (attempt ${attempts}, next poll ${pollInterval}ms)`);
|
|
8114
8258
|
switch (progressEvent.OperationStatus) {
|
|
8115
8259
|
case "SUCCESS": return progressEvent;
|
|
8116
|
-
case "FAILED": throw new
|
|
8260
|
+
case "FAILED": throw new CloudControlOperationFailedError(`${operation} failed for ${logicalId}: ${progressEvent.StatusMessage || "Unknown error"}`, progressEvent.TypeName || "Unknown", logicalId, progressEvent.Identifier, progressEvent.ErrorCode, operation);
|
|
8117
8261
|
case "CANCEL_COMPLETE": throw new ProvisioningError(`${operation} cancelled for ${logicalId}`, progressEvent.TypeName || "Unknown", logicalId, progressEvent.Identifier);
|
|
8118
8262
|
case "IN_PROGRESS":
|
|
8119
8263
|
case "PENDING":
|
|
@@ -14221,4 +14365,4 @@ var DeployEngine = class {
|
|
|
14221
14365
|
|
|
14222
14366
|
//#endregion
|
|
14223
14367
|
export { resolveStateBucketWithDefaultAndSource as $, TemplateParser as A, getDockerCmd as B, findActionableSilentDrops as C, applyRoleArnIfSet as D, cfnRefValueFromPhysicalId as E, AssetPublisher as F, Synthesizer as G, runDockerStreaming as H, stringifyValue as I, getLegacyStateBucketName as J, synthesisStatusMessage as K, WorkGraph as L, S3StateBackend as M, rebuildClientForBucketRegion as N, DiffCalculator as O, shouldRetainResource as P, resolveStateBucketWithDefault as Q, buildDockerImage as R, ProviderRegistry as S, IntrinsicFunctionResolver as T, AssetManifestLoader as U, runDockerForeground as V, getDockerImageBySourceHash as W, resolveCaptureObservedState as X, resolveApp as Y, resolveSkipPrefix as Z, green as _, withRetry as a, uploadCfnTemplate as at, IAMRoleProvider as b, computeImplicitDeleteEdges as c, resolveBucketRegion as ct, isStatefulRecreateTargetSync as d, warnDeprecatedNoPrefixCliFlag as et, renderStatefulReason as f, gray as g, cyan as h, withResourceDeadline as i, findLargeInlineResources as it, LockManager as j, DagBuilder as k, extractDeploymentEventError as l, bold as m, DEFAULT_RESOURCE_WARN_AFTER_MS as n, CFN_TEMPLATE_URL_LIMIT as nt, isRetryableTransientError as o, AssemblyReader as ot, formatResourceLine as p, getDefaultStateBucketName as q, DeployEngine as r, MIGRATE_TMP_PREFIX as rt, IMPLICIT_DELETE_DEPENDENCIES as s, clearBucketRegionCache as st, DEFAULT_RESOURCE_TIMEOUT_MS as t, CFN_TEMPLATE_BODY_LIMIT as tt, MULTI_REGION_RECREATE_BLOCKED_TYPES as u, red as v, CloudControlProvider as w, collectInlinePolicyNamesManagedBySiblings as x, yellow as y, formatDockerLoginError as z };
|
|
14224
|
-
//# sourceMappingURL=deploy-engine-
|
|
14368
|
+
//# sourceMappingURL=deploy-engine-pdCBIFCK.js.map
|