You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
dreamorosi opened this issue
Sep 24, 2023
· 2 comments
· Fixed by #1708
Assignees
Labels
completedThis item is complete and has been merged/shippedinternalPRs that introduce changes in governance, tech debt and chores (linting setup, baseline, etc.)layersItems related to the Lambda Layers pipeline
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.
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.
The text was updated successfully, but these errors were encountered:
dreamorosi
added
layers
Items related to the Lambda Layers pipeline
confirmed
The scope is clear, ready for implementation
internal
PRs that introduce changes in governance, tech debt and chores (linting setup, baseline, etc.)
labels
Sep 24, 2023
Comments on closed issues are hard for our team to see.
If you need more assistance, please either tag a team member or open a new issue that references this one.
If you wish to keep having a conversation with other community members under this issue feel free to do so.
completedThis item is complete and has been merged/shippedinternalPRs that introduce changes in governance, tech debt and chores (linting setup, baseline, etc.)layersItems related to the Lambda Layers pipeline
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):
/opt/nodejs/node_modules/@aws-sdk/
)/var/task/node_modules/@aws-sdk/
)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
Future readers
Please react with 👍 and your use case to help us understand customer demand.
The text was updated successfully, but these errors were encountered: