feat(aws): storage slice prereqs — SecretRotation (SAR) unblock, storage.rds scaffolding, CaCertificate - #142
Open
so0k wants to merge 5 commits into
Open
feat(aws): storage slice prereqs — SecretRotation (SAR) unblock, storage.rds scaffolding, CaCertificate#142so0k wants to merge 5 commits into
so0k wants to merge 5 commits into
Conversation
…rage.rds scaffolding + CaCertificate
Storage slice PR 1 (reference tag v2.263.0):
- encryption.SecretRotation: the 'no serverlessrepo resource' HARD BLOCKER
was incorrect -- implement on aws_serverlessapplicationrepository_cloudformation_stack,
mirroring upstream aws-secretsmanager/lib/secret-rotation.ts.
- escapeTerraformTemplateLiteral (src/aws/util.ts): escape ${ / %{ in free-text
values (SAR excludeCharacters parameter, Secret.generateSecretString).
- moveEdgeWhitespaceInward: CloudFormation trims edge whitespace from stack
parameter values (perpetual drift; upstream RDS default exclude set starts
with a space) -- relocate edge whitespace inward (character set, order-free).
- RotationSchedule marks the owning Secret so its initial
aws_secretsmanager_secret_version gets lifecycle.ignore_changes
[secret_string, version_stages]: rotation replaces AWSCURRENT out-of-band;
without this the next apply clobbers rotated credentials and every plan drifts.
- storage.rds sub-namespace (compute.batch idiom) with ca-certificate.ts ported
byte-close from upstream -- decouples the DocDB port from the RDS PRs.
- Live integ (make secret-rotation): real Postgres db.t3.micro in an isolated
VPC + Secrets Manager interface endpoint; a REAL rotation via
SecretsManagerRDSPostgreSQLRotationSingleUser@1.1.618 completes, the rotated
password honors all 15 excluded characters (incl. ${ / %{ payload), zero-drift
plan, full destroy. PASS 1583s.
Contributor
Author
Live apply/verify/destroy receipts —
|
The default local backend embeds a machine-dependent absolute tfstate path in synth output (conventions.md rule from PR #118) -- CI test shard 4/5 failed on the path mismatch.
Repo pattern: snapshotted test stacks pass gridBackendConfig to the AwsStack constructor (secret.test.ts et al.); direct HttpBackend attachment is the tech-debt variant.
…tion encryption.Secret's generateSecretString path uses the aws_secretsmanager_random_password DATA source, which generates a new password on every plan/refresh -- every plan drifted and every apply REPLACED the live password. CloudFormation generates once server-side at create; parity requires lifecycle.ignore_changes [secret_string] on the version when the value is construct-generated (rotation additionally ignores version_stages, as before). Caught by the RDS foundations integ drift oracle (TestRdsGroups).
so0k
commented
Aug 6, 2026
Comment on lines
+85
to
+92
| new dataAwsSecretsmanagerRandomPassword.DataAwsSecretsmanagerRandomPassword( | ||
| stack, | ||
| "MasterPassword", | ||
| { | ||
| passwordLength: 20, | ||
| excludePunctuation: true, | ||
| }, | ||
| ); |
Contributor
Author
There was a problem hiding this comment.
should use aws.encryption to generate secrets? or wait for CDKTN 0.24 and updated terraform-provider-aws bindings with function and ephemeral resources support
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Storage slice PR 1/N — prerequisites: SecretRotation (SAR) unblock,
storage.rdsscaffolding, CaCertificateFirst PR of the storage-services stack (aws-rds → docdb → elasticache → neptune → redshift, reference tag v2.263.0). This PR lands the shared prerequisites so the RDS PRs can stack cleanly on top.
1.
encryption.SecretRotationre-enabled (SAR-backed rotation)The previous "HARD BLOCKER" (construct always threw, claiming Terraform has no
serverlessreporesource) was incorrect:@cdktn/provider-awsshipsaws_serverlessapplicationrepository_cloudformation_stack.SecretRotationnow mirrors upstreamaws-secretsmanager/lib/secret-rotation.ts(v2.263.0) with the SAR app deployed through that resource (CAPABILITY_IAM+CAPABILITY_RESOURCE_POLICY, rotation Lambda ARN from the stack'sRotationLambdaARNoutput). Documented deviations: explicit CFN stackname(required by the Terraform resource; reuses the deterministic rotation function name), 'aws'-partition semantic-version pin,ImportedRotationLambdaARN-only wrapper.Hardening that fell out of live testing (all drift-oracle-verified, see below):
escapeTerraformTemplateLiteral(src/aws/util.ts):excludeCharactersis free text that legitimately contains${/%{— escaped to$${/%%{in every Terraform string-template context (SecretRotationSAR parameter +Secret.generateSecretString).excludeCharacters(upstream's default RDS exclude set starts with one) drifts forever. Since the value is a character set, edge whitespace is deterministically moved inward (moveEdgeWhitespaceInward).AWSCURRENTout-of-band — withoutlifecycle.ignore_changeson theaws_secretsmanager_secret_version, the nextterraform applywould clobber the rotated credentials with the stale initial value (and every plan reports drift).RotationSchedulenow marks the owningSecret(duck-typed throughSecretTargetAttachment), which emitsignore_changes = [secret_string, version_stages]. Upstream CloudFormation never reads the value back, so it has no equivalent problem. Unit tests cover both the rotated (ignore_changes present) and non-rotated (absent) paths.2.
storage.rdssub-namespace +CaCertificatesrc/aws/storage/rds/created (export * as rds from "./rds", same idiom ascompute.batch), starting withca-certificate.tsported byte-close from upstream (including the deprecatedRDS_CA_RDS2048_G1alias quirks). This decouples the upcoming DocDB port (whose only rds dependency isCaCertificate) from the RDS PRs.3. Live integration test (
integ/aws/encryption,make secret-rotation)End-to-end fixture: real Postgres
db.t3.microin an isolated VPC (no NAT) + Secrets Manager interface endpoint (private DNS),Secret.attach()folding connection fields, andSecretRotationwith the AWS-publishedSecretsManagerRDSPostgreSQLRotationSingleUser@1.1.618SAR app,rotateImmediatelyOnUpdateleft at its default (true) so a real rotation executes. The Go test:DescribeSecret.LastRotatedDateuntil the four-step rotation completes against the live database,${and%{, proving the escaping end-to-end through both template contexts,tofu plan -detailed-exitcode== 0),Run 1 receipt: rotation completed live; drift oracle then caught all three defects fixed above (secret-version replacement, SAR parameter whitespace trim, plus a fixture-level data-source password regeneration now under
ignore_changes = [password]). Run 2 (fixes applied): apply → real rotation → zero-drift → destroy, receipts in thread.Notes for reviewers
test/aws/encryption/secret-rotation.test.tsis the ported upstream suite (v2.263.0) + repo snapshot + the escaping/trim/ignore_changes regressions.SecretRotationApplicationcatalog retains the v2.233.0-shaped global partition fallbacks; the per-applicationadditionalSemanticVersionstable v2.263.0 introduced is TODO-linked, andisMultiUserinference matches v2.263.0.HostedRotationremains unavailable (CFN-transform-backed; no Terraform equivalent) — unchanged in this PR.