@go-to-k/cdkd 0.283.12 → 0.283.13
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-BKR0cF_X.js → asg-provider-CrVgG0Pj.js} +2 -2
- package/dist/{asg-provider-BKR0cF_X.js.map → asg-provider-CrVgG0Pj.js.map} +1 -1
- package/dist/cli.js +210 -20
- package/dist/cli.js.map +1 -1
- package/dist/{deploy-engine-DHOpGcMS.js → deploy-engine-BdKa1DA4.js} +3 -3
- package/dist/{deploy-engine-DHOpGcMS.js.map → deploy-engine-BdKa1DA4.js.map} +1 -1
- package/dist/index.js +1 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { $ as coerceCfnBoolean, $t as resolveStateBucketWithDefault, A as cyan, An as MissingCdkCliError, At as AssetModeResolver, B as findSilentDropProperties, Bt as getDockerCmd, C as makeCanonicalizePropertiesFn, Ct as stringifyValue, D as renderStatefulReason, Dn as LocalMigrateError, Dt as loadPublishableAssetManifest, E as isStatefulRecreateTargetSync, En as LocalInvokeBuildError$1, Et as createAssetRedirectResolver, F as IAMRoleProvider, Fn as ResourceUpdateNotSupportedError, Ft as validateAssetBucketName, G as IntrinsicFunctionResolver, Gn as isRetryableTransientError, Gt as Synthesizer, H as slowCcOperationTimeoutMs, Hn as normalizeAwsError, Ht as runDockerStreaming, I as collectInlinePolicyNamesManagedBySiblings, In as StackHasActiveImportsError, It as validateContainerRepoName, J as refStateLookupFromResource, Jt as getLegacyStateBucketName, K as cfnRefValueFromPhysicalId, Kn as isThrottlingError, Kt as synthesisStatusMessage, L as clearOnUpdateRemoval, Ln as StackTerminationProtectionError, Lt as buildDenyExternalAccessPolicy, M as green, Mn as PartialFailureError, Mt as ensureAssetStorage, N as red, Nn as ProvisioningError, Nt as getBootstrapMarkerKey, O as formatResourceLine, On as LocalStartServiceError, Ot as rewriteTemplateAssetReferences, P as yellow, Pn as ResourceTimeoutError, Pt as parseBootstrapMarker, Q as assertRegionMatch, Qt as resolveSkipPrefix, R as ProviderRegistry, Rt as buildDockerImage, S as unsupportedFinalSnapshotError, Sn as CdkdError, St as AssetPublisher, T as MULTI_REGION_RECREATE_BLOCKED_TYPES, Tn as DeployCancelledError, Tt as buildAssetRedirectMap, U as disableInstanceApiTermination, Un as withErrorHandling, Ut as AssetManifestLoader, V as CloudControlProvider, Vt as runDockerForeground, W as isTerminationProtectionPropagationError, Wn as isMarkedNonRetryable, Wt as getDockerImageBySourceHash, X as normalizeAwsTagsToCfn, Xt as resolveAutoAssetStorage, Y as WAFv2WebACLProvider, Yt as resolveApp, Z as resolveExplicitPhysicalId, Zt as resolveCaptureObservedState, _ as buildFinalSnapshotIdentifier, _n as AwsClients, _t as TemplateParser, a as DeploymentEventsStore, an as CFN_TEMPLATE_URL_LIMIT, at as requireConfigObject, b as isFinalSnapshotError, bn as setAwsClients, bt as rebuildClientForBucketRegion, c as replayFailedOperations, cn as uploadCfnTemplate, ct as s3BucketDomainName, d as deleteSkipReason, dn as canonicalizeRegion, dt as s3BucketWebsiteUrl, en as resolveStateBucketWithDefaultAndSource, et as configBooleanRefusal, f as withResourceDeadline, fn as derivePartitionAndUrlSuffix, ft as applyRoleArnIfSet, g as PRE_DELETE_SNAPSHOT_TYPES, gn as resolveBucketRegion, gt as DagBuilder, h as ATOMIC_FINAL_SNAPSHOT_TYPES, ht as withRetry, i as DeploymentEventsReader, in as CFN_TEMPLATE_BODY_LIMIT, it as requireConfigArray, j as gray, jn as NestedStackChildDirectDestroyError, jt as BOOTSTRAP_MARKER_PREFIX, k as bold, kt as escapeRegExp, l as replayRollback, ln as expectedOwnerParam, lt as s3BucketDualStackDomainName, m as computeImplicitDeleteEdges, mn as processStackMessages, mt as describeTypeWithThrottleRetry, n as DEFAULT_RESOURCE_WARN_AFTER_MS, nn as stateBucketExistenceConfirmed, nt as readConfigString, o as planFailedOps, on as MIGRATE_TMP_PREFIX, ot as requireConfigString, p as IMPLICIT_DELETE_DEPENDENCIES, pn as AssemblyReader, pt as DiffCalculator, q as getAccountInfo, qn as markNonRetryable, qt as getDefaultStateBucketName, r as DeployEngine, rn as warnDeprecatedNoPrefixCliFlag, rt as replayWarn, s as planRollback, sn as findLargeInlineResources, st as s3BucketArn, t as DEFAULT_RESOURCE_TIMEOUT_MS, tn as resolveUseCdkBootstrapAssets, tt as configStringRefusal, u as UNSPECIFIED_SKIP_REASON, un as PARTITION_TABLE, ut as s3BucketRegionalDomainName, v as ccRoutedFinalSnapshotError, vn as getAwsClients, vt as LockManager, w as extractDeploymentEventError, wt as WorkGraph, x as refusesFinalSnapshot, xt as shouldRetainResource, y as createPreDeleteFinalSnapshot, yn as resetAwsClients, yt as S3StateBackend, z as findActionableSilentDrops, zt as formatDockerLoginError } from "./deploy-engine-
|
|
2
|
+
import { $ as coerceCfnBoolean, $t as resolveStateBucketWithDefault, A as cyan, An as MissingCdkCliError, At as AssetModeResolver, B as findSilentDropProperties, Bt as getDockerCmd, C as makeCanonicalizePropertiesFn, Ct as stringifyValue, D as renderStatefulReason, Dn as LocalMigrateError, Dt as loadPublishableAssetManifest, E as isStatefulRecreateTargetSync, En as LocalInvokeBuildError$1, Et as createAssetRedirectResolver, F as IAMRoleProvider, Fn as ResourceUpdateNotSupportedError, Ft as validateAssetBucketName, G as IntrinsicFunctionResolver, Gn as isRetryableTransientError, Gt as Synthesizer, H as slowCcOperationTimeoutMs, Hn as normalizeAwsError, Ht as runDockerStreaming, I as collectInlinePolicyNamesManagedBySiblings, In as StackHasActiveImportsError, It as validateContainerRepoName, J as refStateLookupFromResource, Jt as getLegacyStateBucketName, K as cfnRefValueFromPhysicalId, Kn as isThrottlingError, Kt as synthesisStatusMessage, L as clearOnUpdateRemoval, Ln as StackTerminationProtectionError, Lt as buildDenyExternalAccessPolicy, M as green, Mn as PartialFailureError, Mt as ensureAssetStorage, N as red, Nn as ProvisioningError, Nt as getBootstrapMarkerKey, O as formatResourceLine, On as LocalStartServiceError, Ot as rewriteTemplateAssetReferences, P as yellow, Pn as ResourceTimeoutError, Pt as parseBootstrapMarker, Q as assertRegionMatch, Qt as resolveSkipPrefix, R as ProviderRegistry, Rt as buildDockerImage, S as unsupportedFinalSnapshotError, Sn as CdkdError, St as AssetPublisher, T as MULTI_REGION_RECREATE_BLOCKED_TYPES, Tn as DeployCancelledError, Tt as buildAssetRedirectMap, U as disableInstanceApiTermination, Un as withErrorHandling, Ut as AssetManifestLoader, V as CloudControlProvider, Vt as runDockerForeground, W as isTerminationProtectionPropagationError, Wn as isMarkedNonRetryable, Wt as getDockerImageBySourceHash, X as normalizeAwsTagsToCfn, Xt as resolveAutoAssetStorage, Y as WAFv2WebACLProvider, Yt as resolveApp, Z as resolveExplicitPhysicalId, Zt as resolveCaptureObservedState, _ as buildFinalSnapshotIdentifier, _n as AwsClients, _t as TemplateParser, a as DeploymentEventsStore, an as CFN_TEMPLATE_URL_LIMIT, at as requireConfigObject, b as isFinalSnapshotError, bn as setAwsClients, bt as rebuildClientForBucketRegion, c as replayFailedOperations, cn as uploadCfnTemplate, ct as s3BucketDomainName, d as deleteSkipReason, dn as canonicalizeRegion, dt as s3BucketWebsiteUrl, en as resolveStateBucketWithDefaultAndSource, et as configBooleanRefusal, f as withResourceDeadline, fn as derivePartitionAndUrlSuffix, ft as applyRoleArnIfSet, g as PRE_DELETE_SNAPSHOT_TYPES, gn as resolveBucketRegion, gt as DagBuilder, h as ATOMIC_FINAL_SNAPSHOT_TYPES, ht as withRetry, i as DeploymentEventsReader, in as CFN_TEMPLATE_BODY_LIMIT, it as requireConfigArray, j as gray, jn as NestedStackChildDirectDestroyError, jt as BOOTSTRAP_MARKER_PREFIX, k as bold, kt as escapeRegExp, l as replayRollback, ln as expectedOwnerParam, lt as s3BucketDualStackDomainName, m as computeImplicitDeleteEdges, mn as processStackMessages, mt as describeTypeWithThrottleRetry, n as DEFAULT_RESOURCE_WARN_AFTER_MS, nn as stateBucketExistenceConfirmed, nt as readConfigString, o as planFailedOps, on as MIGRATE_TMP_PREFIX, ot as requireConfigString, p as IMPLICIT_DELETE_DEPENDENCIES, pn as AssemblyReader, pt as DiffCalculator, q as getAccountInfo, qn as markNonRetryable, qt as getDefaultStateBucketName, r as DeployEngine, rn as warnDeprecatedNoPrefixCliFlag, rt as replayWarn, s as planRollback, sn as findLargeInlineResources, st as s3BucketArn, t as DEFAULT_RESOURCE_TIMEOUT_MS, tn as resolveUseCdkBootstrapAssets, tt as configStringRefusal, u as UNSPECIFIED_SKIP_REASON, un as PARTITION_TABLE, ut as s3BucketRegionalDomainName, v as ccRoutedFinalSnapshotError, vn as getAwsClients, vt as LockManager, w as extractDeploymentEventError, wt as WorkGraph, x as refusesFinalSnapshot, xt as shouldRetainResource, y as createPreDeleteFinalSnapshot, yn as resetAwsClients, yt as S3StateBackend, z as findActionableSilentDrops, zt as formatDockerLoginError } from "./deploy-engine-BdKa1DA4.js";
|
|
3
3
|
import { a as getLiveRenderer, c as PATTERN_B_RESOURCE_TYPES, d as generateResourceNameWithFallback, h as withStackName, i as runStackBuffered, m as withSkipPrefix, n as getLogger, o as PATTERN_B_NAME_OPTIONS, s as PATTERN_B_NAME_PROPERTIES, u as generateResourceName } from "./logger-zRrlbaQt.js";
|
|
4
|
-
import { t as ASGProvider } from "./asg-provider-
|
|
4
|
+
import { t as ASGProvider } from "./asg-provider-CrVgG0Pj.js";
|
|
5
5
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
6
6
|
import { createHash, randomBytes, randomUUID } from "node:crypto";
|
|
7
7
|
import { CopyObjectCommand, 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, ListObjectVersionsCommand, ListObjectsV2Command, NoSuchBucket, PutBucketAccelerateConfigurationCommand, PutBucketAnalyticsConfigurationCommand, PutBucketCorsCommand, PutBucketEncryptionCommand, PutBucketIntelligentTieringConfigurationCommand, PutBucketInventoryConfigurationCommand, PutBucketLifecycleConfigurationCommand, PutBucketLoggingCommand, PutBucketMetricsConfigurationCommand, PutBucketNotificationConfigurationCommand, PutBucketOwnershipControlsCommand, PutBucketPolicyCommand, PutBucketReplicationCommand, PutBucketTaggingCommand, PutBucketVersioningCommand, PutBucketWebsiteCommand, PutObjectCommand, PutObjectLockConfigurationCommand, PutPublicAccessBlockCommand, S3Client, S3ServiceException } from "@aws-sdk/client-s3";
|
|
@@ -20534,6 +20534,128 @@ var SSMParameterProvider = class {
|
|
|
20534
20534
|
return out;
|
|
20535
20535
|
}
|
|
20536
20536
|
/**
|
|
20537
|
+
* Build the `Arn` attribute for an SSM parameter (issue #1824).
|
|
20538
|
+
*
|
|
20539
|
+
* WHY THIS EXISTS. An output / cross-resource `Fn::GetAtt` reads the CACHED
|
|
20540
|
+
* `resource.attributes[<CFnName>]` in
|
|
20541
|
+
* `IntrinsicFunctionResolver.constructAttribute`, which never calls a
|
|
20542
|
+
* provider's `getAttribute` — and for an `*Arn` name the resolver's shape
|
|
20543
|
+
* guard HARD-FAILS rather than degrading when the cached value is missing and
|
|
20544
|
+
* the physicalId is name-shaped (an SSM physicalId IS the parameter name). So
|
|
20545
|
+
* `new cdk.CfnOutput(this, 'ParamArn', { value: param.attrArn })` failed the
|
|
20546
|
+
* deploy until the ARN was cached under its CFn name.
|
|
20547
|
+
*
|
|
20548
|
+
* SOURCE DECISION — CONSTRUCTED, not read back. `PutParameter` returns only
|
|
20549
|
+
* `Version` / `Tier`, so there were exactly two candidate sources, and the
|
|
20550
|
+
* rejected one is recorded here so the call stays challengeable:
|
|
20551
|
+
*
|
|
20552
|
+
* - `GetParameter`'s `Parameter.ARN` is authoritative, and cdkd already
|
|
20553
|
+
* issues that call in `readCurrentState` / `import`, so it needs no new IAM
|
|
20554
|
+
* permission. It was REJECTED on COST: it would be a brand-new round trip
|
|
20555
|
+
* on EVERY parameter create AND every update, and SSM parameters are among
|
|
20556
|
+
* the most numerous resources in real CDK stacks — a 50-parameter stack
|
|
20557
|
+
* would pay 50 extra reads for a value that is a pure function of data
|
|
20558
|
+
* cdkd already holds, against a project whose whole premise is removing
|
|
20559
|
+
* round trips.
|
|
20560
|
+
* - CONSTRUCTION is deterministic. The parameter ARN is the documented
|
|
20561
|
+
* `arn:{partition}:ssm:{region}:{account}:parameter/{name}`, with the
|
|
20562
|
+
* name's leading `/` folded into the separator — the same formula
|
|
20563
|
+
* `aws-cdk-lib`'s `StringParameter.parameterArn` uses — so nothing has to
|
|
20564
|
+
* be discovered from AWS. It is also the established idiom in this repo for
|
|
20565
|
+
* "the create response carries no ARN": `AppSyncProvider.buildAppSyncArn`
|
|
20566
|
+
* and the four `CloudControlProvider` enrichment sites (KMS key, ECR
|
|
20567
|
+
* repository x2, Kinesis stream) all construct through the same
|
|
20568
|
+
* `getAccountInfo` + `derivePartitionAndUrlSuffix` + `fabricated`-refusal
|
|
20569
|
+
* pair this method reuses.
|
|
20570
|
+
*
|
|
20571
|
+
* The PARTITION is DERIVED, never hardcoded `arn:aws:` — that hardcoding is an
|
|
20572
|
+
* active bug class here (#1794 / #1815), and on a `cn-` / `us-gov-` deploy it
|
|
20573
|
+
* would record an ARN naming a partition the parameter is not in.
|
|
20574
|
+
*
|
|
20575
|
+
* The `fabricated`-account guard (#1730 / #1746) is honored by REFUSING rather
|
|
20576
|
+
* than by substituting: `getAccountInfo` catches its own STS failure and
|
|
20577
|
+
* answers the placeholder `123456789012`, which carries no wildcard and is
|
|
20578
|
+
* therefore invisible to `isPlaceholderArn`, so a fabricated id must yield NO
|
|
20579
|
+
* attribute instead of a plausible-looking wrong one. Returning `undefined`
|
|
20580
|
+
* degrades to exactly the pre-fix behavior — the resolver's shape guard fails
|
|
20581
|
+
* LOUDLY on the name-shaped physicalId — never to a silently wrong value.
|
|
20582
|
+
*
|
|
20583
|
+
* DEGRADATION ON THE UPDATE PATH is a DELIBERATE trade-off, not one this
|
|
20584
|
+
* design avoids. An update result's `attributes` REPLACE the state record's
|
|
20585
|
+
* rather than merging into it (`deploy-engine.ts`:
|
|
20586
|
+
* `result.attributes ?? (wasReplaced ? undefined : currentResource.attributes)`),
|
|
20587
|
+
* so whenever this method degrades during an `update` the returned map carries
|
|
20588
|
+
* no `Arn` and the create-time one is DROPPED. Construction does not prevent
|
|
20589
|
+
* that — it only swaps WHICH dependency can fail, STS plus the client's region
|
|
20590
|
+
* resolver instead of SSM — so read the source decision above as buying one
|
|
20591
|
+
* fewer round trip and nothing else.
|
|
20592
|
+
*
|
|
20593
|
+
* The alternative is to return NO `attributes` at all on the degraded path, so
|
|
20594
|
+
* the engine's `??` carries the previous map forward and the `Arn` survives.
|
|
20595
|
+
* That is REJECTED: the same map carries `Type` / `Value`, which are the values
|
|
20596
|
+
* THIS update just sent. Carrying the previous map forward would answer
|
|
20597
|
+
* `Fn::GetAtt [Param, Value]` with the SUPERSEDED value — silently, and to a
|
|
20598
|
+
* question cdkd can answer correctly — and would hand `cdkd drift` a baseline
|
|
20599
|
+
* AWS does not hold. Dropping the `Arn` instead degrades to the resolver's LOUD
|
|
20600
|
+
* `*Arn` shape-guard failure, which is exactly the pre-fix behavior, and the
|
|
20601
|
+
* resource's next UPDATE re-records it. A loud missing value beats a quiet
|
|
20602
|
+
* wrong one — the same reasoning the `fabricated`-account arm above applies.
|
|
20603
|
+
*
|
|
20604
|
+
* Two honest bounds on that "next update re-records it". `getAccountInfo`
|
|
20605
|
+
* caches a SUCCESSFUL identity for the process, so within one deploy only a run
|
|
20606
|
+
* whose FIRST `GetCallerIdentity` fails degrades at all — but the 10s
|
|
20607
|
+
* fabricated-answer TTL then covers every parameter created in that window
|
|
20608
|
+
* rather than a random subset. And a plain re-deploy does NOT heal it: a
|
|
20609
|
+
* resource whose resolved properties equal its state record is skipped with no
|
|
20610
|
+
* provider call, so healing needs a real property change (issue
|
|
20611
|
+
* [#1852](https://github.com/go-to-k/cdkd/issues/1852), which also covers the
|
|
20612
|
+
* resolver message that currently misattributes this to a missing enrichment).
|
|
20613
|
+
*
|
|
20614
|
+
* NEVER THROWS, and that is enforced here rather than asserted at the call
|
|
20615
|
+
* sites. `create` calls this AFTER `PutParameter` has already committed a
|
|
20616
|
+
* parameter, so a throw would surface as a failed create over a missing
|
|
20617
|
+
* ATTRIBUTE — leaving an orphan that makes the next deploy hit
|
|
20618
|
+
* `ParameterAlreadyExists` (the issue #376 class), and the cleanup that exists
|
|
20619
|
+
* for that is deliberately out of reach by then. `getAccountInfo` catches its
|
|
20620
|
+
* own STS failure, but `config.region()` is a resolver that can reject, so the
|
|
20621
|
+
* whole body is wrapped: an unexpected failure degrades to "no Arn recorded"
|
|
20622
|
+
* exactly as the fabricated-account arm does.
|
|
20623
|
+
*/
|
|
20624
|
+
async buildParameterArn(name) {
|
|
20625
|
+
try {
|
|
20626
|
+
return await this.buildParameterArnUnguarded(name);
|
|
20627
|
+
} catch (error) {
|
|
20628
|
+
this.logger.warn(`Could not build the Arn attribute for SSM parameter ${name}: ${error instanceof Error ? error.message : String(error)}. The parameter itself is unaffected; the Arn is NOT recorded, so an Fn::GetAtt on it will fail until a later deploy records it.`);
|
|
20629
|
+
return;
|
|
20630
|
+
}
|
|
20631
|
+
}
|
|
20632
|
+
/**
|
|
20633
|
+
* {@link buildParameterArn}'s body. Only that method may call it.
|
|
20634
|
+
*
|
|
20635
|
+
* `name` is always a parameter NAME, never an ARN, and that is an INVARIANT
|
|
20636
|
+
* rather than an assumption this method has to defend (issue #1824 review
|
|
20637
|
+
* round 3). Both callers pass a value SSM has just accepted as a
|
|
20638
|
+
* `PutParameter` `Name`, and that field forbids an ARN outright — "You can't
|
|
20639
|
+
* enter the Amazon Resource Name (ARN) for a parameter, only the parameter
|
|
20640
|
+
* name itself", plus a name charset of `a-zA-Z0-9_.-` and `/` that excludes
|
|
20641
|
+
* `:`. So an ARN-shaped id fails at `PutParameter` several statements ABOVE
|
|
20642
|
+
* this method on both paths, and a guard here could only ever fire against a
|
|
20643
|
+
* mock. Round 2 added exactly such a guard, believing an ARN could arrive from
|
|
20644
|
+
* `cdkd import --resource Param=arn:...`; it can, but the defect is that the
|
|
20645
|
+
* import RECORDED it, so the fix belongs at the import boundary — where
|
|
20646
|
+
* `import()` now refuses it — and not here. Do not re-add it.
|
|
20647
|
+
*/
|
|
20648
|
+
async buildParameterArnUnguarded(name) {
|
|
20649
|
+
const accountInfo = await getAccountInfo(await this.ssmClient.config.region());
|
|
20650
|
+
if (accountInfo.fabricated) {
|
|
20651
|
+
this.logger.warn(`Cannot determine the AWS account (STS is unreachable, and the resolved account id is a placeholder), so the Arn attribute for SSM parameter ${name} would be fabricated and is NOT recorded. An Fn::GetAtt on it will fail until a later deploy resolves the account.`);
|
|
20652
|
+
return;
|
|
20653
|
+
}
|
|
20654
|
+
const { partition } = derivePartitionAndUrlSuffix(accountInfo.region);
|
|
20655
|
+
const qualifiedName = name.startsWith("/") ? name.slice(1) : name;
|
|
20656
|
+
return `arn:${partition}:ssm:${canonicalizeRegion(accountInfo.region)}:${accountInfo.accountId}:parameter/${qualifiedName}`;
|
|
20657
|
+
}
|
|
20658
|
+
/**
|
|
20537
20659
|
* Create an SSM parameter
|
|
20538
20660
|
*/
|
|
20539
20661
|
async create(logicalId, resourceType, properties) {
|
|
@@ -20575,11 +20697,13 @@ var SSMParameterProvider = class {
|
|
|
20575
20697
|
throw innerError;
|
|
20576
20698
|
}
|
|
20577
20699
|
this.logger.debug(`Successfully created SSM parameter ${logicalId}: ${name}`);
|
|
20700
|
+
const arn = await this.buildParameterArn(name);
|
|
20578
20701
|
return {
|
|
20579
20702
|
physicalId: name,
|
|
20580
20703
|
attributes: {
|
|
20581
20704
|
Type: type,
|
|
20582
|
-
Value: value
|
|
20705
|
+
Value: value,
|
|
20706
|
+
...arn !== void 0 && { Arn: arn }
|
|
20583
20707
|
}
|
|
20584
20708
|
};
|
|
20585
20709
|
} catch (error) {
|
|
@@ -20626,12 +20750,14 @@ var SSMParameterProvider = class {
|
|
|
20626
20750
|
this.logger.debug(`Updated tags for SSM parameter ${physicalId}`);
|
|
20627
20751
|
}
|
|
20628
20752
|
this.logger.debug(`Successfully updated SSM parameter ${logicalId}`);
|
|
20753
|
+
const arn = await this.buildParameterArn(physicalId);
|
|
20629
20754
|
return {
|
|
20630
20755
|
physicalId,
|
|
20631
20756
|
wasReplaced: false,
|
|
20632
20757
|
attributes: {
|
|
20633
20758
|
Type: type,
|
|
20634
|
-
Value: value
|
|
20759
|
+
Value: value,
|
|
20760
|
+
...arn !== void 0 && { Arn: arn }
|
|
20635
20761
|
}
|
|
20636
20762
|
};
|
|
20637
20763
|
} catch (error) {
|
|
@@ -20742,6 +20868,57 @@ var SSMParameterProvider = class {
|
|
|
20742
20868
|
return result;
|
|
20743
20869
|
}
|
|
20744
20870
|
/**
|
|
20871
|
+
* Refuse a physical id SSM's WRITE APIs could never accept (issue #1824
|
|
20872
|
+
* review round 3).
|
|
20873
|
+
*
|
|
20874
|
+
* An SSM parameter's physicalId must always be the parameter NAME, because
|
|
20875
|
+
* that is the only thing the write APIs take. `PutParameterRequest.Name`:
|
|
20876
|
+
* "You can't enter the Amazon Resource Name (ARN) for a parameter, only the
|
|
20877
|
+
* parameter name itself", with a name charset of `a-zA-Z0-9_.-` plus `/` as
|
|
20878
|
+
* the hierarchy separator; `DeleteParameterRequest.Name` repeats the ARN
|
|
20879
|
+
* prohibition verbatim. A COLON therefore cannot appear in any writable name,
|
|
20880
|
+
* which is the single predicate used here — it covers both shapes
|
|
20881
|
+
* `GetParameter` additionally accepts and this method has to stop:
|
|
20882
|
+
*
|
|
20883
|
+
* - an ARN (`arn:aws:ssm:us-east-1:111122223333:parameter/foo`), and
|
|
20884
|
+
* - a version / label SELECTOR (`GetParameterRequest.Name`: "To query by
|
|
20885
|
+
* parameter label, use `"Name": "name:label"`. To query by parameter
|
|
20886
|
+
* version, use `"Name": "name:version"`").
|
|
20887
|
+
*
|
|
20888
|
+
* Both sail through this provider's existence check, so before this guard the
|
|
20889
|
+
* value was RECORDED as the physicalId and the damage landed later and
|
|
20890
|
+
* elsewhere: `cdkd deploy` failing at `PutParameter({Name: physicalId})` with
|
|
20891
|
+
* a `ValidationException` after a `Value` change, and `cdkd destroy` failing
|
|
20892
|
+
* identically at `DeleteParameter`. This is where the bad value ENTERS
|
|
20893
|
+
* (`--resource` / `Properties.Name`), so it is where it is stopped.
|
|
20894
|
+
*
|
|
20895
|
+
* REFUSED, NOT NORMALIZED to the name, and the ARN grammar is the reason. The
|
|
20896
|
+
* mapping back is genuinely ambiguous rather than merely awkward:
|
|
20897
|
+
*
|
|
20898
|
+
* - The leading `/` is NOT recoverable. `arn:…:parameter/foo` is the ARN of
|
|
20899
|
+
* BOTH the simple name `foo` and the one-level hierarchical name `/foo`,
|
|
20900
|
+
* since the name's leading slash IS the separator — `aws-cdk-lib`'s
|
|
20901
|
+
* `arnForParameterName` renders the two to the identical string, and that
|
|
20902
|
+
* is precisely why CDK needs an explicit `simpleName` flag whenever the
|
|
20903
|
+
* name is a token. Guessing wrong writes a physicalId naming a DIFFERENT
|
|
20904
|
+
* parameter, i.e. converts a loud failure into a silent wrong-resource
|
|
20905
|
+
* write.
|
|
20906
|
+
* - A parameter SHARED from another account has no name form at all
|
|
20907
|
+
* ("For parameters shared with you from another account, you must use the
|
|
20908
|
+
* full ARN"), so for that shape there is nothing to normalize TO.
|
|
20909
|
+
*
|
|
20910
|
+
* A refusal is a loud, fixable error, and the message names the exact command
|
|
20911
|
+
* that prints the name to pass instead.
|
|
20912
|
+
*/
|
|
20913
|
+
refuseUnwritableParameterId(input, explicit) {
|
|
20914
|
+
if (!explicit.includes(":")) return;
|
|
20915
|
+
const isArn = explicit.startsWith("arn:");
|
|
20916
|
+
const shape = isArn ? "an ARN" : "a version / label selector";
|
|
20917
|
+
const remedy = input.knownPhysicalId === explicit ? `pass the parameter NAME instead: --resource ${input.logicalId}=<parameterName>` : `set Properties.Name to the parameter NAME rather than ${shape}`;
|
|
20918
|
+
const whyNotDerived = isArn ? " cdkd deliberately does NOT derive the name from the ARN: the leading \"/\" is not recoverable (arn:...:parameter/foo is the ARN of BOTH the simple name \"foo\" and the hierarchical name \"/foo\"), and a parameter shared from another account has no name form at all — so a derived name could silently address a DIFFERENT parameter." : "";
|
|
20919
|
+
throw new ProvisioningError(`Cannot adopt SSM parameter ${input.logicalId} from ${shape} ('${explicit}'): cdkd records a parameter's NAME as its physical id, because SSM's write APIs accept only the name (PutParameter and DeleteParameter both reject an ARN, and a name cannot contain ':'), so the next cdkd deploy and cdkd destroy would fail with a ValidationException. ${remedy}.${whyNotDerived} Read the name AWS holds with: aws ssm get-parameter --name '${explicit}' --query Parameter.Name --output text`, input.resourceType, input.logicalId);
|
|
20920
|
+
}
|
|
20921
|
+
/**
|
|
20745
20922
|
* Adopt an existing SSM parameter into cdkd state.
|
|
20746
20923
|
*
|
|
20747
20924
|
* SSM physical IDs ARE the parameter names (`/foo/bar`). The CDK template
|
|
@@ -20749,19 +20926,25 @@ var SSMParameterProvider = class {
|
|
|
20749
20926
|
* covers most cases.
|
|
20750
20927
|
*
|
|
20751
20928
|
* Lookup order:
|
|
20752
|
-
* 1. `--resource` override or `Properties.Name` →
|
|
20929
|
+
* 1. `--resource` override or `Properties.Name` → refuse it outright when it
|
|
20930
|
+
* is not a writable NAME (see {@link refuseUnwritableParameterId} — note
|
|
20931
|
+
* `GetParameter` accepts an ARN and a `name:version` selector while every
|
|
20932
|
+
* write API rejects both), else verify via `GetParameter`.
|
|
20753
20933
|
*/
|
|
20754
20934
|
async import(input) {
|
|
20755
20935
|
const explicit = resolveExplicitPhysicalId(input, "Name");
|
|
20756
|
-
if (explicit)
|
|
20757
|
-
|
|
20758
|
-
|
|
20759
|
-
|
|
20760
|
-
|
|
20761
|
-
|
|
20762
|
-
|
|
20763
|
-
|
|
20764
|
-
|
|
20936
|
+
if (explicit) {
|
|
20937
|
+
this.refuseUnwritableParameterId(input, explicit);
|
|
20938
|
+
try {
|
|
20939
|
+
const arn = (await this.ssmClient.send(new GetParameterCommand({ Name: explicit }))).Parameter?.ARN;
|
|
20940
|
+
return {
|
|
20941
|
+
physicalId: explicit,
|
|
20942
|
+
attributes: { ...arn !== void 0 && { Arn: arn } }
|
|
20943
|
+
};
|
|
20944
|
+
} catch (err) {
|
|
20945
|
+
if (err instanceof ParameterNotFound) return null;
|
|
20946
|
+
throw err;
|
|
20947
|
+
}
|
|
20765
20948
|
}
|
|
20766
20949
|
return null;
|
|
20767
20950
|
}
|
|
@@ -33740,16 +33923,20 @@ var RDSProvider = class {
|
|
|
33740
33923
|
});
|
|
33741
33924
|
try {
|
|
33742
33925
|
const tags = this.buildTags(properties);
|
|
33743
|
-
await this.getClient().send(new CreateDBSubnetGroupCommand({
|
|
33926
|
+
const created = await this.getClient().send(new CreateDBSubnetGroupCommand({
|
|
33744
33927
|
DBSubnetGroupName: dbSubnetGroupName,
|
|
33745
33928
|
DBSubnetGroupDescription: properties["DBSubnetGroupDescription"] || `Subnet group for ${logicalId}`,
|
|
33746
33929
|
SubnetIds: properties["SubnetIds"],
|
|
33747
33930
|
...tags.length > 0 && { Tags: tags }
|
|
33748
33931
|
}));
|
|
33749
33932
|
this.logger.debug(`Successfully created DBSubnetGroup ${logicalId}: ${dbSubnetGroupName}`);
|
|
33933
|
+
const dbSubnetGroupArn = created.DBSubnetGroup?.DBSubnetGroupArn;
|
|
33750
33934
|
return {
|
|
33751
33935
|
physicalId: dbSubnetGroupName,
|
|
33752
|
-
attributes: {
|
|
33936
|
+
attributes: {
|
|
33937
|
+
DBSubnetGroupName: dbSubnetGroupName,
|
|
33938
|
+
...dbSubnetGroupArn !== void 0 && { DBSubnetGroupArn: dbSubnetGroupArn }
|
|
33939
|
+
}
|
|
33753
33940
|
};
|
|
33754
33941
|
} catch (error) {
|
|
33755
33942
|
const cause = error instanceof Error ? error : void 0;
|
|
@@ -33773,7 +33960,10 @@ var RDSProvider = class {
|
|
|
33773
33960
|
return {
|
|
33774
33961
|
physicalId,
|
|
33775
33962
|
wasReplaced: false,
|
|
33776
|
-
attributes: {
|
|
33963
|
+
attributes: {
|
|
33964
|
+
DBSubnetGroupName: physicalId,
|
|
33965
|
+
...arn !== void 0 && { DBSubnetGroupArn: arn }
|
|
33966
|
+
}
|
|
33777
33967
|
};
|
|
33778
33968
|
} catch (error) {
|
|
33779
33969
|
const cause = error instanceof Error ? error : void 0;
|
|
@@ -34379,10 +34569,10 @@ var RDSProvider = class {
|
|
|
34379
34569
|
async importDBSubnetGroup(input) {
|
|
34380
34570
|
const explicit = resolveExplicitPhysicalId(input, "DBSubnetGroupName");
|
|
34381
34571
|
if (explicit) try {
|
|
34382
|
-
await this.getClient().send(new DescribeDBSubnetGroupsCommand({ DBSubnetGroupName: explicit }));
|
|
34572
|
+
const arn = (await this.getClient().send(new DescribeDBSubnetGroupsCommand({ DBSubnetGroupName: explicit }))).DBSubnetGroups?.[0]?.DBSubnetGroupArn;
|
|
34383
34573
|
return {
|
|
34384
34574
|
physicalId: explicit,
|
|
34385
|
-
attributes: {}
|
|
34575
|
+
attributes: { ...arn !== void 0 && { DBSubnetGroupArn: arn } }
|
|
34386
34576
|
};
|
|
34387
34577
|
} catch (err) {
|
|
34388
34578
|
if (err.name === "DBSubnetGroupNotFoundFault") return null;
|
|
@@ -78258,7 +78448,7 @@ function createMigrateCommand() {
|
|
|
78258
78448
|
*/
|
|
78259
78449
|
function buildProgram() {
|
|
78260
78450
|
const program = new Command();
|
|
78261
|
-
program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.283.
|
|
78451
|
+
program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.283.13");
|
|
78262
78452
|
program.hook("preAction", (_thisCommand, actionCommand) => {
|
|
78263
78453
|
const { profile } = actionCommand.optsWithGlobals();
|
|
78264
78454
|
if (profile !== void 0) process.env["AWS_PROFILE"] = profile;
|