fix(custom-resource-handlers): deterministic asset hashes for generated lambdas#37634
fix(custom-resource-handlers): deterministic asset hashes for generated lambdas#37634mergify[bot] merged 6 commits intoaws:mainaws/aws-cdk:mainfrom clayrosenthal:fix-custom-resource-handlers-deterministic-asset-hashesclayrosenthal/aws-cdk:fix-custom-resource-handlers-deterministic-asset-hashesCopy head branch name to clipboard
Conversation
|
|
|
|
…ed lambdas
Custom-resource handler Lambdas generated by the handler framework previously
staged their code via `lambda.Code.fromAsset(path)` with no explicit asset hash,
so `AssetStaging` fingerprinted the bundled directory at synth time. Because
that fingerprint depends on filesystem metadata (mtime, mode), the resulting
S3 object key differed between machines even when the bundled bytes were
identical — causing `cdk diff` to show spurious Lambda asset updates when
comparing a local synth to what was previously uploaded to S3.
Compute a content-only SHA-256 of each bundled handler directory at generation
time (in `scripts/generate.ts`) and bake it into the generated framework class
as `Code.fromAsset(path, { assetHash })`. The value depends only on file
names and bytes, so the S3 object key is now stable across machines.
The new `sourceHash` option on `HandlerFrameworkClassProps` is optional and
only emitted for `FUNCTION` and `SINGLETON_FUNCTION` components.
`CUSTOM_RESOURCE_PROVIDER` components are left untouched because
`CustomResourceProviderBase` mixes `__entrypoint__.js` into the staged
directory at synth time, so a hash pinned at generate time would drift from
the final bundle.
Closes aws#34307
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
e51c338 to
178b111
Compare
The deterministic asset hashes emitted by the generated custom-resource handler classes produce new S3 object keys, so every integ snapshot that exercises an affected handler needs its asset directory renamed and its JSON manifests rewritten to reference the new hash. Updated by renaming the asset directories and replacing the old hash with the new hash in the snapshot JSON files. No other snapshot content is changed.
178b111 to
0a98f55
Compare
…s-framework/classes.ts Co-authored-by: Otavio Macedo <288203+otaviomacedo@users.noreply.github.com>
…generation Pass the source hash through expr.lit so expr.object receives an Expression instead of a raw string, and apply the same expr.object form to the SingletonFunction call site for consistency. Update the two framework tests to match the multi-line rendering that expr.object produces. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
This PR has been in the CHANGES REQUESTED state for 3 weeks, and looks abandoned. Note that PRs with failing linting check or builds are not reviewed, please ensure your build is passing To prevent automatic closure:
This PR will automatically close in 14 days if no action is taken. |
|
I've made loads of changes since the changes were requested, the bot never re-reviewed. @aws-cdk-automation I've added integ tests now! |
|
@otaviomacedo do these security guardian results need to be fixed or not? Most are not changes I made |
… snapshots Security Guardian flagged pre-existing findings in integ snapshots that this PR's deterministic-asset-hash change brought into scope (the asset hash field changed, so Security Guardian re-scanned the templates). Fixes the three findings that are addressable in test code: - aws-events-targets integ.log-group: enable SQS-managed encryption on the integ test's DLQ. - aws-logs-destinations integ.lambda: enable SQS-managed encryption on the integ test's destination queue. - custom-resources integ.aws-custom-resource: replace ssm:* with the specific actions the test exercises (GetParameter, GetParameters, GetParametersByPath, DescribeParameters). The four remaining Security Guardian findings come from CDK framework defaults (DynamoDB replication policy, ALB internet-facing ingress, CodePipeline cross-account action role trust) and are pre-existing on main. Addressing them requires feature-flagged framework changes and belongs in separate PRs. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
✅ Updated pull request passes all PRLinter validations. Dismissing previous PRLinter review.
|
Thank you for contributing! Your pull request will be updated from main and then merged automatically (do not update manually, and be sure to allow changes to be pushed to your fork). |
Merge Queue Status
This pull request spent 31 minutes 40 seconds in the queue, with no time running CI. ReasonThe pull request can't be updated
HintYou should update or rebase your pull request manually. If you do, this pull request will automatically be requeued once the queue conditions match again. |
Pull request has been modified.
|
Thank you for contributing! Your pull request will be updated from main and then merged automatically (do not update manually, and be sure to allow changes to be pushed to your fork). |
Merge Queue Status
This pull request spent 26 seconds in the queue, including 4 seconds running CI. Required conditions to merge
|
|
Comments on closed issues and PRs are hard for our team to see. |
Issue # (if applicable)
Closes #34307
Reason for this change
Custom-resource handler Lambdas generated by the handler framework (e.g.,
aws-sesdrop-spam,aws-logslog-retention, many others) stage their code via:Because no explicit
assetHashis provided,AssetStagingfingerprints the bundled directory at synth time and the fingerprint includes filesystem metadata (mtime, mode). Two synths of identical source on different machines therefore produce different S3 object keys, socdk diffshows spurious Lambda asset updates against the cloud — even when the bundled bytes are byte-for-byte identical.Description of changes
calculateDirectoryHashtopackages/@aws-cdk/custom-resource-handlers/scripts/generate.ts. It walks the bundled handler directory deterministically (sorted entries, SHA-256 over relative paths + file content bytes) and computes a content-only hash.HandlerFrameworkModule.build → HandlerFrameworkClassvia a new optionalsourceHashfield onHandlerFrameworkClassProps.sourceHashis supplied, the code generator emitsCode.fromAsset(path, { assetHash: '<hash>' })—AssetStagingthen uses it as theCUSTOMfingerprint so the S3 object key depends only on the bundled bytes.FUNCTIONandSINGLETON_FUNCTIONcomponents.CUSTOM_RESOURCE_PROVIDERis intentionally skipped becauseCustomResourceProviderBasemixes__entrypoint__.jsinto the staged directory at synth time, which would cause a generate-time hash to drift from the final bundle.Description of how you validated changes
packages/@aws-cdk/custom-resource-handlers/test/custom-resources-framework/framework.test.tsasserting that the generated TypeScript contains the expectedassetHashfor bothFUNCTIONandSINGLETON_FUNCTIONcomponents. All 11 tests in the file pass.s3.Bucket { autoDeleteObjects: true }(CRP-based, unchanged) andses.ReceiptRuleSet { dropSpam: true }(singleton-based, hash-pinned). Confirmed:drop-spam-provider.generated.tsnow emits a bakedassetHash;Checklist
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license