Skip to content

fix(layers): do not ship AWS SDK clients in the Lambda layer - #5512

Open
svozza wants to merge 3 commits into
mainfrom
fix/5511-remove-sdk-from-layer
Open

fix(layers): do not ship AWS SDK clients in the Lambda layer#5512
svozza wants to merge 3 commits into
mainfrom
fix/5511-remove-sdk-from-layer

Conversation

@svozza

@svozza svozza commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

Summary

The Lambda layer is mounted at /opt/nodejs/node_modules, which precedes /var/runtime/node_modules on NODE_PATH, so any SDK package we ship shadows the runtime's copy for customer code as well as our own. Because we only ever shipped a subset — notably @aws-sdk/client-dynamodb but never @aws-sdk/lib-dynamodb — functions using the DynamoDB DocumentClient resolved a layer-provided client against a runtime-provided lib, which fails at runtime when the two straddle the AWS SDK 3.928.0 boundary. This change stops shipping AWS SDK clients in the layer and relies on the complete, self-consistent SDK the Node.js runtime already provides.

Changes

  • Reduce modulesToInstall in layers/src/layer-publisher-stack.ts to ['zod'], removing @aws-sdk/client-dynamodb, @aws-sdk/util-dynamodb, @aws-sdk/client-ssm, @aws-sdk/client-secrets-manager and @aws-sdk/client-appconfigdata
  • Add a comment explaining why no @aws-sdk/* client may be shipped, so the dependency is not reintroduced
  • Remove @aws-sdk/* from the esbuild exclusion notes and snippets in docs/getting-started/lambda-layers.md (CDK, SAM and Serverless Framework). The previous wording told customers to exclude it "since the packages are already present the layer", which is no longer true — and bundling your own SDK resolves it from /var/task, which takes precedence over both the layer and the runtime and is the only configuration guaranteed to be self-consistent
  • zod stays in the layer, and @smithy/service-error-classification plus @aws-sdk/types remain as transitive dependencies of aws-xray-sdk-core — none of these are provided by the Lambda runtime
  • Layer size drops from 24 MB to 16 MB unpacked (4.3 MB to 2.9 MB zipped)

Verified with an A/B test on nodejs22.x using two layers that are identical except for the presence of the bundled SDK. The test function performs a plain DocumentClient round-trip and does not use Powertools at all:

Layer with SDK Layer without SDK
@aws-sdk/client-dynamodb resolves from /opt/nodejs @3.454.0 /var/runtime @3.1049.0
@aws-sdk/lib-dynamodb resolves from /var/runtime @3.1049.0 /var/runtime @3.1049.0
DocumentClient round-trip FAILS PASSES
Powertools still loads

Also verified that all utilities (Logger, Metrics, Tracer including captureAWSv3Client, Parameters, Idempotency, Parser, Batch) work with no @aws-sdk/* in the layer, across CJS and ESM on nodejs22.x and nodejs24.x, and that customers who bundle their own SDK are unaffected because /var/task continues to take precedence. The layer e2e suite passes (8/8).

Issue number: closes #5511


By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

Disclaimer: We value your time and bandwidth. As such, any pull requests created on non-triaged issues might not be successful.

svozza added 2 commits July 28, 2026 20:53
The layer is mounted at /opt/nodejs/node_modules, which precedes
/var/runtime/node_modules on NODE_PATH. Any SDK package shipped in the
layer therefore shadows the runtime's copy for customer code as well,
not just for Powertools.

Because the layer only ever included a subset of the SDK - notably
@aws-sdk/client-dynamodb but never @aws-sdk/lib-dynamodb - functions
using the DynamoDB DocumentClient resolved a layer-provided client
against a runtime-provided lib. When those straddle the AWS SDK 3.928.0
boundary, which moved serializerMiddleware registration from per-command
to per-client, the mismatch fails at runtime with:

  serializerMiddleware is not found when adding DocumentMarshall
  middleware before serializerMiddleware

The Node.js Lambda runtime already provides a complete, self-consistent
AWS SDK v3, so rely on that instead of exposing a partial one. zod and
@smithy/* are not provided by the runtime and remain in the layer.

Closes #5511
The layer no longer ships AWS SDK clients, so the previous wording -
that both @aws-lambda-powertools/* and @aws-sdk/* are 'already present
the layer' - is no longer accurate.

Remove @aws-sdk/* from the esbuild exclusion notes and from the CDK, SAM
and Serverless Framework snippets, so customers bundle their own SDK
rather than relying on whatever the layer happens to expose. Bundling
your own SDK resolves it from /var/task, which takes precedence over
both the layer and the runtime and is therefore the only configuration
guaranteed to be self-consistent.

Also fixes the missing 'in' in 'present the layer'.
@powertools-for-aws-oss-automation powertools-for-aws-oss-automation Bot added the size/M PR between 30-99 LOC label Jul 28, 2026
@svozza
svozza requested a review from dreamorosi July 28, 2026 20:02
Record that layer version 49 is the last to bundle AWS SDK v3 clients,
explain that /opt/nodejs/node_modules took precedence so those clients
were used by customer code too, and that only a subset ever shipped -
which is what allowed mismatched SDK packages at runtime.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/M PR between 30-99 LOC

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bug: Lambda layer ships a partial AWS SDK that shadows the runtime SDK, breaking DynamoDB DocumentClient

1 participant