Description
Summary
Customers using the Idempotency and Parameters utilities can optionally pass an AWS SDK client to be used to communicate with AWS APIs. In order to ensure that the object passed at runtime is correct we must perform some conditional logic which at the moment is based on instanceof
.
When working with Node.js based AWS Lambda functions, the AWS SDK can come from at least 4 known locations (not in order):
- The Lambda runtime
- The Lambda Layer (
/opt/nodejs/node_modules/@aws-sdk/
) - The customer provided zip archive (
/var/task/node_modules/@aws-sdk/
) - The customer provided bundled code (i.e. a single file bundled with tools like
esbuild
and placed in/var/task/index.js
)
Powertools doesn't ship with the AWS SDK, this allows the user to have control over where the AWS SDK is sourced from among the locations above.
When both Powertools and the SDK are bundled in the same file (4) then Powertools will import/require the SDK from the bundle itself since they are colocated. If both Powertools and the SDK are archived as part of the same zip archive deployed to Lambda (3), Powertools will most likely import the one and the same node_module
folder. If instead no SDK is provided, Powertools will use the one present in the Lambda runtime (1).
In all the cases above, since Powertools is always colocated with the customer code the SDK imported/required in the customer code will be the same that Powertools also requires internally. This allows the runtime instanceof
check to be successful.
If instead Powertools is shipped as part of a Lambda Layer and the customer brings their own AWS SDK (cases 3 or 4) the instanceof
check will fail. This happens because Powertools will always default to using a copy of the SDK from either the Layer itself or from the runtime.
Albeit confusing, since the AWS SDK module is imported from two different locations Node.js will consider it as two separate modules for all intense and purposes and so checks like client instanceof SdkClient
will fail because the two objects are not the same.
We should consider adopting alternative means to check whether an object passed to us is indeed the AWS SDK client that we expect so that the edge cases above will also work.
Why is this needed?
We need to work on this because we are having customer demand (#1703) for adding utilities that include this logic to our Lambda Layer. At present this strict check would prevent using our Lambda Layers in some edge cases.
Besides Lambda Layers, once we will start shipping hybrid builds with both CJS and ESM the issue might become ever more likely to happen since we won't be able to guarantee the import paths of code that we don't control.
Which area does this relate to?
Other
Solution
Since we cannot rely on prototype identity we will have to rely on the actual shape of the object and assert the presence of certain properties/methods.
Acknowledgment
- This request meets Powertools for AWS Lambda (TypeScript) Tenets
- Should this be considered in other Powertools for AWS Lambda languages? i.e. Python, Java, and .NET
Future readers
Please react with 👍 and your use case to help us understand customer demand.
Metadata
Metadata
Assignees
Labels
Type
Projects
Status