@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/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-DHOpGcMS.js";
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-BKR0cF_X.js";
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` → verify via `GetParameter`.
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) try {
20757
- await this.ssmClient.send(new GetParameterCommand({ Name: explicit }));
20758
- return {
20759
- physicalId: explicit,
20760
- attributes: {}
20761
- };
20762
- } catch (err) {
20763
- if (err instanceof ParameterNotFound) return null;
20764
- throw err;
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: { DBSubnetGroupName: dbSubnetGroupName }
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: { DBSubnetGroupName: physicalId }
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.12");
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;