Skip to content

Maintenance: refactor AWS SDK client check in Parameters and Idempotency #1707

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
1 of 2 tasks
dreamorosi opened this issue Sep 24, 2023 · 2 comments · Fixed by #1708
Closed
1 of 2 tasks

Maintenance: refactor AWS SDK client check in Parameters and Idempotency #1707

dreamorosi opened this issue Sep 24, 2023 · 2 comments · Fixed by #1708
Assignees
Labels
completed This item is complete and has been merged/shipped internal PRs that introduce changes in governance, tech debt and chores (linting setup, baseline, etc.) layers Items related to the Lambda Layers pipeline

Comments

@dreamorosi
Copy link
Contributor

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):

  1. The Lambda runtime
  2. The Lambda Layer (/opt/nodejs/node_modules/@aws-sdk/)
  3. The customer provided zip archive (/var/task/node_modules/@aws-sdk/)
  4. 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

Future readers

Please react with 👍 and your use case to help us understand customer demand.

@dreamorosi 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
@dreamorosi dreamorosi self-assigned this Sep 24, 2023
@dreamorosi dreamorosi linked a pull request Sep 24, 2023 that will close this issue
9 tasks
@github-project-automation github-project-automation bot moved this from Working on it to Coming soon in Powertools for AWS Lambda (TypeScript) Sep 25, 2023
@github-actions
Copy link
Contributor

⚠️ COMMENT VISIBILITY WARNING ⚠️

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.

@github-actions github-actions bot added pending-release This item has been merged and will be released soon and removed confirmed The scope is clear, ready for implementation labels Sep 25, 2023
@github-actions
Copy link
Contributor

This is now released under v1.14.0 version!

@github-actions github-actions bot added completed This item is complete and has been merged/shipped and removed pending-release This item has been merged and will be released soon labels Sep 29, 2023
@dreamorosi dreamorosi moved this from Coming soon to Shipped in Powertools for AWS Lambda (TypeScript) Feb 10, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
completed This item is complete and has been merged/shipped internal PRs that introduce changes in governance, tech debt and chores (linting setup, baseline, etc.) layers Items related to the Lambda Layers pipeline
Projects
Development

Successfully merging a pull request may close this issue.

1 participant