@go-to-k/cdkd 0.283.35 → 0.283.36
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{asg-provider-xC0UiCjt.js → asg-provider-BruE_3F2.js} +2 -2
- package/dist/{asg-provider-xC0UiCjt.js.map → asg-provider-BruE_3F2.js.map} +1 -1
- package/dist/cli.js +3 -3
- package/dist/cli.js.map +1 -1
- package/dist/{deploy-engine-fBYrdrmB.js → deploy-engine-Bhq_JPCc.js} +208 -36
- package/dist/deploy-engine-Bhq_JPCc.js.map +1 -0
- package/dist/index.js +1 -1
- package/package.json +1 -1
- package/dist/deploy-engine-fBYrdrmB.js.map +0 -1
|
@@ -9887,20 +9887,32 @@ const SECRET_MASK = "***";
|
|
|
9887
9887
|
* homing it here means no call site has to thread it: the four sibling writers
|
|
9888
9888
|
* #1910 fixes pass a position SOURCE and nothing else.
|
|
9889
9889
|
*
|
|
9890
|
-
* Its lifetime matches the resolver's `cachedDynamicReferences
|
|
9891
|
-
*
|
|
9892
|
-
*
|
|
9893
|
-
*
|
|
9894
|
-
*
|
|
9895
|
-
*
|
|
9896
|
-
*
|
|
9897
|
-
*
|
|
9898
|
-
*
|
|
9899
|
-
*
|
|
9900
|
-
*
|
|
9901
|
-
*
|
|
9902
|
-
*
|
|
9903
|
-
*
|
|
9890
|
+
* Its lifetime NO LONGER matches the resolver's `cachedDynamicReferences`, and
|
|
9891
|
+
* that divergence is now deliberate (issue
|
|
9892
|
+
* [#1933](https://github.com/go-to-k/cdkd/issues/1933)). The resolved VALUES
|
|
9893
|
+
* moved onto the RESOLVER INSTANCE — one per stack, each carrying its own
|
|
9894
|
+
* region — because a value is only true for the region that read it. A VERDICT
|
|
9895
|
+
* is a statement about a reference's TYPE and has to be readable with no
|
|
9896
|
+
* resolver in hand: {@link isKnownSecretExpression} is consulted from the
|
|
9897
|
+
* redaction path, whose callers thread a position SOURCE and nothing else. So
|
|
9898
|
+
* this set stays process-wide while the values do not, and
|
|
9899
|
+
* `resetAccountInfoCache` now clears only this one.
|
|
9900
|
+
*
|
|
9901
|
+
* Process-wide is therefore CHOSEN here rather than inherited, and the choice
|
|
9902
|
+
* is what makes a stale verdict correctable: a resolver whose fresh
|
|
9903
|
+
* `GetParameter` reports a public `Type` RETRACTS the entry
|
|
9904
|
+
* ({@link forgetSecretExpression}) for every later reader, which a per-region
|
|
9905
|
+
* store would scope away. It is still not strictly sound across regions or
|
|
9906
|
+
* accounts in one run — the same expression can name a `SecureString` in one
|
|
9907
|
+
* region and a plain `String` in another — but note which way the imprecision
|
|
9908
|
+
* points in EACH direction now that the two stores can disagree. An entry only
|
|
9909
|
+
* ever GRANTS "persist the source leaf verbatim", so a verdict inherited from
|
|
9910
|
+
* another region can at worst store a public reference as an expression (a
|
|
9911
|
+
* spurious UPDATE, issue #1901's class), never a secret as plaintext. And the
|
|
9912
|
+
* opposite move — another region RETRACTING a verdict this stack still needs —
|
|
9913
|
+
* cannot un-redact anything either, because each of the resolver's own cache
|
|
9914
|
+
* entries carries the verdict that produced it and re-records on a hit without
|
|
9915
|
+
* consulting this set.
|
|
9904
9916
|
*/
|
|
9905
9917
|
const recordedSecretExpressions$1 = /* @__PURE__ */ new Set();
|
|
9906
9918
|
/** Remember that `expression` resolves to a secret. Called by the resolver. */
|
|
@@ -12152,15 +12164,19 @@ let cachedAccountIdentity = null;
|
|
|
12152
12164
|
*/
|
|
12153
12165
|
const cachedAvailabilityZones = {};
|
|
12154
12166
|
/**
|
|
12155
|
-
* Cache for resolved dynamic references (secretsmanager, ssm)
|
|
12156
|
-
*/
|
|
12157
|
-
const cachedDynamicReferences = {};
|
|
12158
|
-
/**
|
|
12159
12167
|
* The `{{resolve:...}}` expressions this process has PROVEN resolve to a
|
|
12160
12168
|
* SECRET, reached through `secret-redaction.ts`'s `recordedSecretExpressions`
|
|
12161
|
-
* store.
|
|
12162
|
-
*
|
|
12163
|
-
*
|
|
12169
|
+
* store. Process-global, and cleared by `resetAccountInfoCache` so a test (or a
|
|
12170
|
+
* later phase) cannot inherit a verdict it just asked to forget.
|
|
12171
|
+
*
|
|
12172
|
+
* NOTE this store is deliberately WIDER-lived than the resolved VALUES it was
|
|
12173
|
+
* once paired with: those moved onto the resolver instance (issue #1933), while
|
|
12174
|
+
* a verdict is a statement about a reference's TYPE, which the redaction path
|
|
12175
|
+
* must be able to read with no resolver in hand. The asymmetry is safe in the
|
|
12176
|
+
* one direction that matters — a verdict inherited across regions can only make
|
|
12177
|
+
* a reference be treated AS a secret (persisted as its expression, never as
|
|
12178
|
+
* plaintext), and the reverse case re-asks AWS because the fresh response is
|
|
12179
|
+
* authoritative and the value cache no longer answers for another region.
|
|
12164
12180
|
*
|
|
12165
12181
|
* `ssm` is the kind that NEEDS the memory (issue #1901). A plain `ssm`
|
|
12166
12182
|
* reference is not a secret by SPELLING the way `secretsmanager` is — whether
|
|
@@ -12249,6 +12265,24 @@ function accountInfoFor(identity, overrideRegion) {
|
|
|
12249
12265
|
* the same deploy heal.
|
|
12250
12266
|
*/
|
|
12251
12267
|
const FABRICATED_ACCOUNT_INFO_TTL_MS = 1e4;
|
|
12268
|
+
/**
|
|
12269
|
+
* Retries after the first attempt for a dynamic-reference lookup, THROTTLE-shaped
|
|
12270
|
+
* failures only (issue #1933 review). Everything else — a missing parameter, a
|
|
12271
|
+
* denied secret — is a real answer and is thrown to the caller unchanged.
|
|
12272
|
+
*
|
|
12273
|
+
* It matters more since the cache became per-resolver AND stopped memoizing a
|
|
12274
|
+
* value whose ssm `Type` was unclassifiable: both raise the call COUNT for the
|
|
12275
|
+
* same template (one lookup per resolver rather than per process; one per
|
|
12276
|
+
* occurrence for the anomalous type), and a bare `send` turned the resulting
|
|
12277
|
+
* throttle into an aborted deploy. At the default backoff (1s -> 2s -> 4s -> 8s)
|
|
12278
|
+
* this adds at most ~15s of sleep, against re-running the whole deploy.
|
|
12279
|
+
*/
|
|
12280
|
+
const MAX_DYNAMIC_REFERENCE_THROTTLE_RETRIES = 4;
|
|
12281
|
+
/**
|
|
12282
|
+
* Test seam: overriding `sleep` lets unit tests drive the backoff schedule
|
|
12283
|
+
* without real waits (mirrors `describeTypeRetryDelays`).
|
|
12284
|
+
*/
|
|
12285
|
+
const dynamicReferenceRetryDelays = {};
|
|
12252
12286
|
/** Test seam for {@link FABRICATED_ACCOUNT_INFO_TTL_MS} expiry. */
|
|
12253
12287
|
const accountInfoClock = { now: () => Date.now() };
|
|
12254
12288
|
let fabricatedAccountIdentity = null;
|
|
@@ -12435,6 +12469,89 @@ var IntrinsicFunctionResolver = class {
|
|
|
12435
12469
|
* deploy summary.
|
|
12436
12470
|
*/
|
|
12437
12471
|
physicalIdFallbackCount = 0;
|
|
12472
|
+
/**
|
|
12473
|
+
* Resolved `{{resolve:secretsmanager:...}}` / `{{resolve:ssm:...}}` values,
|
|
12474
|
+
* keyed by the full expression — INSTANCE-scoped, which closes the CACHE half
|
|
12475
|
+
* of issue [#1933](https://github.com/go-to-k/cdkd/issues/1933). The issue is
|
|
12476
|
+
* only PARTIALLY addressed by this field: see "what this does NOT settle"
|
|
12477
|
+
* below.
|
|
12478
|
+
*
|
|
12479
|
+
* It used to be a module-global map keyed by the expression ALONE, and both
|
|
12480
|
+
* halves of that were wrong for the same reason: the key and the lifetime
|
|
12481
|
+
* were narrower than the value they stood for.
|
|
12482
|
+
*
|
|
12483
|
+
* - REGION. Secrets Manager secrets and SSM parameters are regional and
|
|
12484
|
+
* independent — the same NAME in `us-east-1` and `ap-northeast-1` is two
|
|
12485
|
+
* different values, routinely two different credentials — so the first
|
|
12486
|
+
* region to resolve an expression won it for the whole process, and every
|
|
12487
|
+
* later stack in every other region silently reused that value.
|
|
12488
|
+
* - STACK. Nothing reset the map between stacks, so a second stack's
|
|
12489
|
+
* resolution cache-HIT and skipped the lookup that re-records the value as
|
|
12490
|
+
* a secret. `cdkd scrub --all` then found an empty secrets map for that
|
|
12491
|
+
* stack and reported it clean.
|
|
12492
|
+
*
|
|
12493
|
+
* Instance scope settles both at once because a region boundary and a stack
|
|
12494
|
+
* boundary are BOTH resolver boundaries in cdkd: {@link resolverRegion} is
|
|
12495
|
+
* fixed at construction, and every caller builds one resolver per stack
|
|
12496
|
+
* (`DeployEngine` per deploy, `scrub` / `import` / `diff-recursive` /
|
|
12497
|
+
* `rollback-executor` per stack). Re-keying by region alone would have left
|
|
12498
|
+
* the stack half open, which is why the lifetime — not the key — is what
|
|
12499
|
+
* moved.
|
|
12500
|
+
*
|
|
12501
|
+
* ONE caller is a known EXCEPTION to that invariant, and it is written down
|
|
12502
|
+
* here because an invariant recorded without its exception is how the next
|
|
12503
|
+
* change breaks it: `cdkd export` builds a single `paramResolver`
|
|
12504
|
+
* (`src/cli/commands/export.ts`, the `buildResolvedParametersPerStack`
|
|
12505
|
+
* pre-pass) and shares it across every node of a nested-stack tree, while the
|
|
12506
|
+
* nodes carry a per-node `region`. It is safe TODAY for two independent
|
|
12507
|
+
* reasons — the resolver is constructed with the tree's single `rootRegion`
|
|
12508
|
+
* and nested children do not yet diverge from it, and that pre-pass passes no
|
|
12509
|
+
* `recordedSecretValues` bag, so neither the region nor the secrets-recording
|
|
12510
|
+
* dimension has anything to cross. Both stop holding the moment cross-region
|
|
12511
|
+
* nested stacks ship or that pass starts recording secrets; a resolver per
|
|
12512
|
+
* node is the fix then, not a wider key here.
|
|
12513
|
+
*
|
|
12514
|
+
* What this does NOT settle — issue
|
|
12515
|
+
* [#1957](https://github.com/go-to-k/cdkd/issues/1957) owns it: the lookups
|
|
12516
|
+
* themselves still go through the process-ambient `getAwsClients()` singleton
|
|
12517
|
+
* (see `resolveSecretsManagerReference` / `resolveSSMReference`), whose region
|
|
12518
|
+
* is whichever the process installed last. So a resolver constructed for
|
|
12519
|
+
* region B while the ambient clients point at region A still reads A on its
|
|
12520
|
+
* FIRST resolution — no cache involved, so nothing here can prevent it.
|
|
12521
|
+
* `cdkd deploy` re-pins the singleton per stack, which makes a SERIAL
|
|
12522
|
+
* multi-region deploy correct end to end, but the default
|
|
12523
|
+
* `--stack-concurrency 4` races for it (a hazard `deploy.ts` already
|
|
12524
|
+
* documents) and `cdkd scrub` installs its clients once while resolving
|
|
12525
|
+
* stacks in several regions. The split of ownership is therefore: THIS field
|
|
12526
|
+
* closes the cache as a cross-region / cross-stack carrier, while #1957 owns
|
|
12527
|
+
* the wrong-region READ — which is the outcome #1933's title names, so #1933
|
|
12528
|
+
* is not fully resolved until #1957 lands. Pinning the lookup to
|
|
12529
|
+
* {@link resolverRegion} means constructing region-scoped clients, which is a
|
|
12530
|
+
* credentials decision (a bare `new SSMClient({ region })` drops the ambient
|
|
12531
|
+
* profile / assume-role config) and belongs to #1957 rather than here.
|
|
12532
|
+
*/
|
|
12533
|
+
cachedDynamicReferences = /* @__PURE__ */ new Map();
|
|
12534
|
+
/**
|
|
12535
|
+
* `<parameter name>\u0000<reported Type>` pairs this resolver has already
|
|
12536
|
+
* warned about (issue #1933 review).
|
|
12537
|
+
*
|
|
12538
|
+
* Keyed on the PAIR rather than the name alone: two different anomalous types
|
|
12539
|
+
* for one parameter are two different facts — the line REPORTS the type, so
|
|
12540
|
+
* suppressing the second would hide a `Type` nobody has seen yet behind one
|
|
12541
|
+
* that was already explained. The volume problem this set exists for is N
|
|
12542
|
+
* IDENTICAL lines for N occurrences of one reference, which the pair still
|
|
12543
|
+
* bounds, because the type is a property of the parameter rather than of the
|
|
12544
|
+
* occurrence.
|
|
12545
|
+
*
|
|
12546
|
+
* The warning is per LOOKUP, and a parameter with an anomalous `Type` is
|
|
12547
|
+
* deliberately never cached (see `cacheable` in `resolveDynamicReferences`),
|
|
12548
|
+
* so it is re-looked-up for every occurrence of the reference in the stack —
|
|
12549
|
+
* which without this set means one identical warn line per occurrence per
|
|
12550
|
+
* pass, on the exact template that most needs the line to be READ. Scoped to
|
|
12551
|
+
* the resolver, like the value cache: a different stack genuinely deserves
|
|
12552
|
+
* its own warning, since the parameter it names may be a different region's.
|
|
12553
|
+
*/
|
|
12554
|
+
warnedUnrecognizedSsmTypes = /* @__PURE__ */ new Set();
|
|
12438
12555
|
constructor(region, options) {
|
|
12439
12556
|
this.resolverRegion = region || process.env["AWS_REGION"] || "us-east-1";
|
|
12440
12557
|
this.strictGetAtt = options?.strictGetAtt ?? false;
|
|
@@ -14014,21 +14131,35 @@ var IntrinsicFunctionResolver = class {
|
|
|
14014
14131
|
const service = inner.split(":")[0];
|
|
14015
14132
|
const isKnownSecret = service === "secretsmanager" || recordedSecretExpressions.has(fullMatch);
|
|
14016
14133
|
if (isKnownSecret && context?.skipDynamicReferences) continue;
|
|
14017
|
-
|
|
14018
|
-
|
|
14019
|
-
if (
|
|
14020
|
-
result = result.replace(fullMatch, () => cached);
|
|
14134
|
+
const cached = this.cachedDynamicReferences.get(fullMatch);
|
|
14135
|
+
if (cached) {
|
|
14136
|
+
if (cached.secret && cached.value) context?.recordedSecretValues?.set(cached.value, fullMatch);
|
|
14137
|
+
result = result.replace(fullMatch, () => cached.value);
|
|
14021
14138
|
continue;
|
|
14022
14139
|
}
|
|
14023
14140
|
const parts = inner.split(":");
|
|
14024
14141
|
let resolved;
|
|
14025
14142
|
let isSecret = isKnownSecret;
|
|
14143
|
+
/**
|
|
14144
|
+
* May the resolved value be REMEMBERED, or must the next pass re-ask?
|
|
14145
|
+
*
|
|
14146
|
+
* Cleared for exactly the answers the verdict store refuses to pin — an
|
|
14147
|
+
* ssm parameter judged secret from a `Type` that is not a definitive
|
|
14148
|
+
* `SecureString` (issue #1901's fail-closed arm). Caching one would pin
|
|
14149
|
+
* the transient answer for the whole resolver anyway, which is what the
|
|
14150
|
+
* refusal to memoize exists to prevent: before the value cache became
|
|
14151
|
+
* instance-scoped this was already true process-wide, and the
|
|
14152
|
+
* "next pass re-asks" property only ever held on the comparison path,
|
|
14153
|
+
* which caches nothing (issue #1933).
|
|
14154
|
+
*/
|
|
14155
|
+
let cacheable = true;
|
|
14026
14156
|
if (service === "secretsmanager") resolved = await this.resolveSecretsManagerReference(inner);
|
|
14027
14157
|
else if (service === "ssm") {
|
|
14028
14158
|
const decrypt = context?.skipDynamicReferences !== true;
|
|
14029
14159
|
const param = await this.resolveSSMReference(parts, decrypt);
|
|
14030
14160
|
if (param.type === "SecureString") recordedSecretExpressions.add(fullMatch);
|
|
14031
14161
|
else if (!param.secure) recordedSecretExpressions.delete(fullMatch);
|
|
14162
|
+
else cacheable = false;
|
|
14032
14163
|
isSecret = param.secure;
|
|
14033
14164
|
if (param.secure) {
|
|
14034
14165
|
if (!decrypt) continue;
|
|
@@ -14038,7 +14169,10 @@ var IntrinsicFunctionResolver = class {
|
|
|
14038
14169
|
this.logger.warn(`Unsupported dynamic reference service: ${service}`);
|
|
14039
14170
|
continue;
|
|
14040
14171
|
}
|
|
14041
|
-
cachedDynamicReferences
|
|
14172
|
+
if (cacheable) this.cachedDynamicReferences.set(fullMatch, {
|
|
14173
|
+
value: resolved,
|
|
14174
|
+
secret: isSecret
|
|
14175
|
+
});
|
|
14042
14176
|
if (isSecret && resolved) {
|
|
14043
14177
|
context?.recordedSecretValues?.set(resolved, fullMatch);
|
|
14044
14178
|
if (service === "secretsmanager") recordedSecretExpressions.add(fullMatch);
|
|
@@ -14098,7 +14232,7 @@ var IntrinsicFunctionResolver = class {
|
|
|
14098
14232
|
...versionStage && versionStage !== "" && { VersionStage: versionStage },
|
|
14099
14233
|
...versionId && versionId !== "" && { VersionId: versionId }
|
|
14100
14234
|
});
|
|
14101
|
-
const secretString = (await client.send(command)).SecretString;
|
|
14235
|
+
const secretString = (await this.sendWithThrottleRetry(() => client.send(command), `secretsmanager:${secretId}`)).SecretString;
|
|
14102
14236
|
if (!secretString) throw new Error(`Dynamic reference: secret '${secretId}' does not contain a SecretString value`);
|
|
14103
14237
|
if (jsonKey) try {
|
|
14104
14238
|
const keyValue = JSON.parse(secretString)[jsonKey];
|
|
@@ -14197,6 +14331,43 @@ var IntrinsicFunctionResolver = class {
|
|
|
14197
14331
|
return parts.join(":");
|
|
14198
14332
|
}
|
|
14199
14333
|
/**
|
|
14334
|
+
* Run one dynamic-reference lookup, retrying THROTTLE-shaped failures only
|
|
14335
|
+
* (issue #1933 review).
|
|
14336
|
+
*
|
|
14337
|
+
* Both lookups behind `{{resolve:...}}` were bare `send` calls, so a single
|
|
14338
|
+
* `Rate exceeded` aborted the deploy. That was already the wrong trade for a
|
|
14339
|
+
* read, and this PR raises the call count on both paths: the resolved-value
|
|
14340
|
+
* cache is per-resolver now (one lookup per stack rather than one per
|
|
14341
|
+
* process), and a value whose ssm `Type` came back unclassifiable is
|
|
14342
|
+
* deliberately not cached at all (one lookup per OCCURRENCE, so it re-asks
|
|
14343
|
+
* AWS rather than inheriting a transient verdict). Retrying only the throttle
|
|
14344
|
+
* shape keeps every real answer — `ParameterNotFound`, `AccessDenied`, a
|
|
14345
|
+
* malformed reference — failing fast and unchanged.
|
|
14346
|
+
*
|
|
14347
|
+
* Two bounds, both NAMED rather than fixed here:
|
|
14348
|
+
*
|
|
14349
|
+
* - No `isInterrupted` is threaded, so a Ctrl-C landing inside the backoff is
|
|
14350
|
+
* only noticed when that sleep ends — worst case ~8s, ~15s across the whole
|
|
14351
|
+
* schedule. `withRetry` supports the hook, but the only interrupt state in
|
|
14352
|
+
* the tree is `DeployEngine.interrupted`, which reaches nothing here;
|
|
14353
|
+
* wiring it means a resolver option threaded from that engine.
|
|
14354
|
+
* - It says NOTHING about concurrency. The client is captured before the
|
|
14355
|
+
* first attempt, so a sibling stack's teardown (`stackAwsClients.destroy()`
|
|
14356
|
+
* in `deploy.ts`) during a backoff surfaces as a raw, non-throttle-shaped
|
|
14357
|
+
* failure on the next attempt. That is a property of the ambient-singleton
|
|
14358
|
+
* design this PR deliberately does not touch (issue
|
|
14359
|
+
* [#1957](https://github.com/go-to-k/cdkd/issues/1957)), not something the
|
|
14360
|
+
* retry makes safe.
|
|
14361
|
+
*/
|
|
14362
|
+
sendWithThrottleRetry(operation, label) {
|
|
14363
|
+
return withRetry(operation, label, {
|
|
14364
|
+
maxRetries: MAX_DYNAMIC_REFERENCE_THROTTLE_RETRIES,
|
|
14365
|
+
isRetryable: (_message, error) => isThrottlingError(error),
|
|
14366
|
+
logger: this.logger,
|
|
14367
|
+
...dynamicReferenceRetryDelays.sleep ? { sleep: dynamicReferenceRetryDelays.sleep } : {}
|
|
14368
|
+
});
|
|
14369
|
+
}
|
|
14370
|
+
/**
|
|
14200
14371
|
* Resolve an `{{resolve:ssm:...}}` dynamic reference, reporting whether the
|
|
14201
14372
|
* parameter is a `SecureString` (issue #1901).
|
|
14202
14373
|
*
|
|
@@ -14220,12 +14391,13 @@ var IntrinsicFunctionResolver = class {
|
|
|
14220
14391
|
Name: parameterName,
|
|
14221
14392
|
WithDecryption: decrypt
|
|
14222
14393
|
});
|
|
14223
|
-
const response = await client.send(command);
|
|
14394
|
+
const response = await this.sendWithThrottleRetry(() => client.send(command), `ssm:${parameterName}`);
|
|
14224
14395
|
const paramValue = response.Parameter?.Value;
|
|
14225
14396
|
if (paramValue === void 0 || paramValue === null) throw new Error(`Dynamic reference: SSM parameter '${parameterName}' not found or has no value`);
|
|
14226
14397
|
const paramType = response.Parameter?.Type;
|
|
14227
14398
|
const secure = paramType !== "String" && paramType !== "StringList";
|
|
14228
|
-
if (secure && paramType !== "SecureString") {
|
|
14399
|
+
if (secure && paramType !== "SecureString" && !this.warnedUnrecognizedSsmTypes.has(`${parameterName}\u0000${String(paramType)}`)) {
|
|
14400
|
+
this.warnedUnrecognizedSsmTypes.add(`${parameterName}\u0000${String(paramType)}`);
|
|
14229
14401
|
const reported = paramType === void 0 ? "(absent)" : `'${String(paramType)}'`;
|
|
14230
14402
|
this.logger.warn(`SSM parameter '${parameterName}' reported an unrecognized Type ${reported} — treating its value as a secret, so cdkd will persist the {{resolve:ssm:...}} expression rather than the resolved value. Declare the parameter as String / StringList if it is public config.`);
|
|
14231
14403
|
}
|
|
@@ -15097,7 +15269,7 @@ var CloudControlProvider = class {
|
|
|
15097
15269
|
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);
|
|
15098
15270
|
if (context?.removeProtection === true && resourceType === "AWS::AutoScaling::AutoScalingGroup") {
|
|
15099
15271
|
this.logger.debug(`Delegating protected AutoScalingGroup ${logicalId} delete to the SDK ASGProvider (Cloud Control cannot force-delete a protected ASG)`);
|
|
15100
|
-
const { ASGProvider } = await import("./asg-provider-
|
|
15272
|
+
const { ASGProvider } = await import("./asg-provider-BruE_3F2.js").then((n) => n.n);
|
|
15101
15273
|
return await new ASGProvider().delete(logicalId, physicalId, resourceType, _properties, context);
|
|
15102
15274
|
}
|
|
15103
15275
|
const isProtectedEc2Instance = context?.removeProtection === true && resourceType === "AWS::EC2::Instance";
|
|
@@ -21869,13 +22041,14 @@ async function replayRollback(operations, stateResources, stackName, ctx, option
|
|
|
21869
22041
|
eventType: "ROLLBACK_STARTED",
|
|
21870
22042
|
stackName
|
|
21871
22043
|
});
|
|
22044
|
+
const resolver = new IntrinsicFunctionResolver(ctx.region);
|
|
21872
22045
|
const { createOps, otherOps } = partitionOps(operations);
|
|
21873
22046
|
for (let i = otherOps.length - 1; i >= 0; i--) {
|
|
21874
22047
|
if (options.isInterrupted?.()) {
|
|
21875
22048
|
result.interrupted = true;
|
|
21876
22049
|
break;
|
|
21877
22050
|
}
|
|
21878
|
-
await replaySingle(otherOps[i], stateResources, stackName, ctx, orphanLogicalIds, result, options.afterOp, options.isInterrupted);
|
|
22051
|
+
await replaySingle(otherOps[i], stateResources, stackName, ctx, resolver, orphanLogicalIds, result, options.afterOp, options.isInterrupted);
|
|
21879
22052
|
}
|
|
21880
22053
|
if (!result.interrupted && createOps.length > 0) {
|
|
21881
22054
|
const sorted = sortRollbackCreates(createOps, stateResources);
|
|
@@ -21884,7 +22057,7 @@ async function replayRollback(operations, stateResources, stackName, ctx, option
|
|
|
21884
22057
|
result.interrupted = true;
|
|
21885
22058
|
break;
|
|
21886
22059
|
}
|
|
21887
|
-
await replaySingle(op, stateResources, stackName, ctx, orphanLogicalIds, result, options.afterOp, options.isInterrupted);
|
|
22060
|
+
await replaySingle(op, stateResources, stackName, ctx, resolver, orphanLogicalIds, result, options.afterOp, options.isInterrupted);
|
|
21888
22061
|
}
|
|
21889
22062
|
}
|
|
21890
22063
|
ctx.logger.info("Rollback completed. Some resources may remain if deletion failed.");
|
|
@@ -22064,10 +22237,9 @@ function recordAfterRollbackUpdate(restored, result) {
|
|
|
22064
22237
|
function recordedPropertiesAfterReplayCreate(restored, result) {
|
|
22065
22238
|
return result.effectiveProperties === void 0 ? restored.properties : { ...result.effectiveProperties };
|
|
22066
22239
|
}
|
|
22067
|
-
async function replaySingle(op, stateResources, stackName, ctx, orphanLogicalIds, result, afterOp, isInterrupted) {
|
|
22240
|
+
async function replaySingle(op, stateResources, stackName, ctx, resolver, orphanLogicalIds, result, afterOp, isInterrupted) {
|
|
22068
22241
|
const action = classifyRollbackOp(op, stateResources, orphanLogicalIds);
|
|
22069
22242
|
const { logger } = ctx;
|
|
22070
|
-
const resolver = new IntrinsicFunctionResolver(ctx.region);
|
|
22071
22243
|
/**
|
|
22072
22244
|
* The route a CREATE-rollback arm resolved for this op (issue #1366) —
|
|
22073
22245
|
* hoisted so the shared catch's ROLLBACK_RESOURCE_FAILED reports the route
|
|
@@ -22571,7 +22743,7 @@ const FLUSH_INTERVAL_MS = 2e3;
|
|
|
22571
22743
|
const FLUSH_EVENT_THRESHOLD = 50;
|
|
22572
22744
|
/** Build-time cdkd version, with a dev fallback for non-built contexts. */
|
|
22573
22745
|
function getCdkdVersion() {
|
|
22574
|
-
return "0.283.
|
|
22746
|
+
return "0.283.36";
|
|
22575
22747
|
}
|
|
22576
22748
|
/**
|
|
22577
22749
|
* Generate a time-sortable unique run id, e.g.
|
|
@@ -25013,4 +25185,4 @@ var DeployEngine = class {
|
|
|
25013
25185
|
|
|
25014
25186
|
//#endregion
|
|
25015
25187
|
export { getAccountInfo as $, SynthesisError as $n, formatDockerLoginError as $t, cyan as A, resolveBucketRegion as An, TemplateParser as At, stateKeySecretExposure as B, LocalInvokeBuildError as Bn, loadPublishableAssetManifest as Bt, makeCanonicalizePropertiesFn as C, expectedOwnerParam as Cn, s3BucketWebsiteUrl as Ct, renderStatefulReason as D, AssemblyReader as Dn, describeTypeWithThrottleRetry as Dt, isStatefulRecreateTargetSync as E, derivePartitionAndUrlSuffix as En, INTRINSIC_KEYS as Et, collectDeclaredOutputNames as F, AssetError as Fn, AssetPublisher as Ft, findActionableSilentDrops as G, NestedStackChildDirectDestroyError as Gn, BOOTSTRAP_MARKER_PREFIX as Gt, collectInlinePolicyNamesManagedBySiblings as H, LocalStartServiceError as Hn, escapeRegExp$1 as Ht, collectPublishedOutputNames as I, CdkdError as In, stringifyValue as It, slowCcOperationTimeoutMs as J, ResourceTimeoutError as Jn, parseBootstrapMarker as Jt, findSilentDropProperties as K, PartialFailureError as Kn, ensureAssetStorage as Kt, exportAliasCollisionScrubWarning as L, ConfigError as Ln, WorkGraph as Lt, green as M, getAwsClients as Mn, S3StateBackend as Mt, red as N, resetAwsClients as Nn, rebuildClientForBucketRegion as Nt, formatResourceLine as O, processStackMessages as On, withRetry as Ot, yellow as P, setAwsClients as Pn, shouldRetainResource as Pt, cfnRefValueFromPhysicalId as Q, StateError as Qn, buildDockerImage as Qt, isExportAliasCollision as R, DependencyError as Rn, buildAssetRedirectMap as Rt, unsupportedFinalSnapshotError as S, uploadCfnTemplate as Sn, s3BucketRegionalDomainName as St, MULTI_REGION_RECREATE_BLOCKED_TYPES as T, canonicalizeRegion as Tn, DiffCalculator as Tt, clearOnUpdateRemoval as U, LockError as Un, stripControlChars as Ut, IAMRoleProvider as V, LocalMigrateError as Vn, rewriteTemplateAssetReferences as Vt, ProviderRegistry as W, MissingCdkCliError as Wn, AssetModeResolver as Wt, isTerminationProtectionPropagationError as X, StackHasActiveImportsError as Xn, validateContainerRepoName as Xt, disableInstanceApiTermination as Y, ResourceUpdateNotSupportedError as Yn, validateAssetBucketName as Yt, IntrinsicFunctionResolver as Z, StackTerminationProtectionError as Zn, buildDenyExternalAccessPolicy as Zt, buildFinalSnapshotIdentifier as _, warnDeprecatedNoPrefixCliFlag as _n, redactSecretsForState as _t, DeploymentEventsStore as a, Synthesizer as an, isRetryableTransientError as ar, coerceCfnBoolean as at, isFinalSnapshotError as b, MIGRATE_TMP_PREFIX as bn, s3BucketDomainName as bt, replayFailedOperations as c, getLegacyStateBucketName as cn, __exportAll as cr, readConfigString as ct, deleteSkipReason as d, resolveCaptureObservedState as dn, requireConfigObject as dt, getDockerCmd as en, formatError as er, refStateLookupFromResource as et, withResourceDeadline as f, resolveSkipPrefix as fn, requireConfigString as ft, PRE_DELETE_SNAPSHOT_TYPES as g, stateBucketExistenceConfirmed as gn, maskSecretsInText as gt, ATOMIC_FINAL_SNAPSHOT_TYPES as h, resolveUseCdkBootstrapAssets as hn, TEMPLATE_SOURCED_RULES as ht, DeploymentEventsReader as i, getDockerImageBySourceHash as in, isMarkedNonRetryable as ir, assertRegionMatch as it, gray as j, AwsClients as jn, LockManager as jt, bold as k, clearBucketRegionCache as kn, DagBuilder as kt, replayRollback as l, resolveApp as ln, replayWarn as lt, computeImplicitDeleteEdges as m, resolveStateBucketWithDefaultAndSource as mn, STATE_SOURCED_READBACK_RULES as mt, DEFAULT_RESOURCE_WARN_AFTER_MS as n, runDockerStreaming as nn, normalizeAwsError as nr, normalizeAwsTagsToCfn as nt, planFailedOps as o, synthesisStatusMessage as on, isThrottlingError as or, configBooleanRefusal as ot, IMPLICIT_DELETE_DEPENDENCIES as p, resolveStateBucketWithDefault as pn, STATE_SOURCED_CROSS_GENERATION_RULES as pt, CloudControlProvider as q, ProvisioningError as qn, getBootstrapMarkerKey as qt, DeployEngine as r, AssetManifestLoader as rn, withErrorHandling as rr, resolveExplicitPhysicalId as rt, planRollback as s, getDefaultStateBucketName as sn, markNonRetryable as sr, configStringRefusal as st, DEFAULT_RESOURCE_TIMEOUT_MS as t, runDockerForeground as tn, isCdkdError as tr, WAFv2WebACLProvider as tt, UNSPECIFIED_SKIP_REASON as u, resolveAutoAssetStorage as un, requireConfigArray as ut, ccRoutedFinalSnapshotError as v, CFN_TEMPLATE_BODY_LIMIT as vn, scrubResourceRecord as vt, extractDeploymentEventError as w, PARTITION_TABLE as wn, applyRoleArnIfSet as wt, refusesFinalSnapshot as x, findLargeInlineResources as xn, s3BucketDualStackDomainName as xt, createPreDeleteFinalSnapshot as y, CFN_TEMPLATE_URL_LIMIT as yn, s3BucketArn as yt, secretBearingStateKeyWarning as z, DeployCancelledError as zn, createAssetRedirectResolver as zt };
|
|
25016
|
-
//# sourceMappingURL=deploy-engine-
|
|
25188
|
+
//# sourceMappingURL=deploy-engine-Bhq_JPCc.js.map
|