Skip to content

Fix: deploy layers when hot reload enabled #222

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

Merged
merged 3 commits into from
May 17, 2023

Conversation

joe4dev
Copy link
Member

@joe4dev joe4dev commented May 17, 2023

Layers are not deployed if hot reloading is enabled through mountCode: true. In the Serverless AWS provider, Lambda functions and layers are deployed together (uploadFunctionsAndLayers) but serverless-localstack has currently many limitations with hot reloading (e.g., global config, no layer support). This PR provides a workaround to unblock customers who want to hot-reload functions and regularly deploy layers.

Root cause

Hot reloading (i.e., mountCode) in serverless-localstack breaks any Lambda layers with the new Lambda provider:

custom:
  localstack:
    lambda:
      mountCode: true

When trying to deploy a Lambda function with a layer, it fails with an OperationalError:

OperationalError: ENOENT: no such file or directory, open '/Users/joe/Projects/LocalStack/issues/support_aaporomu_u04ba3n4bam/serverless-lambda-layers-minimal/.serverless/layerOne.zip'

When mountCode is enabled, layers do not get packaged and deployed:
Skip plugin function Package.packageService (lambda.mountCode flag is enabled)

Therefore, the deployment fails.

Challenges

  • mountCode: true is a global option but currently does not support hot-reloading of layers (new feature in LocalStack 2.0).
  • Hot reloading (currently) only works with at most one layer per function. Hence, if we intend to apply mountCode to layers as well, it fails if there is any function with more than one layer in the serverless.yml
  • mountCode is bad terminology because the current implementation does not do any mounting anymore but rather copies ZIP files (https://docs.localstack.cloud/user-guide/tools/lambda-tools/hot-reloading/). hotReload would be a better name
  • We need to consider the scope of hot reloading because not everyone wants to enable hot reloading globally. Selectively enabling hot reloading for single functions or layers under development would be helpful.
  • mountCode: true uses the current directory (assumed to be project directory) as default hot reload path or accepts relative paths (e.g., ./functions). This might lead to many unnecessary reloads.

Background

Workaround

Removing the skipIfMountLambda circumvents the issue at the expense of slower initial deployment (with potential other deployment-related side-effects):

  • this.skipIfMountLambda('Package', 'packageService');
  • this.skipIfMountLambda('AwsDeploy', 'uploadFunctionsAndLayers');

Testing

  • Works against customer sample layer_problem (shared in Pro support)
  • Works against Serverless v3 tested with Python layer (just function code support hot reloading)
  • Works with serverless-python-requirements plugin where dependencies are packaged as layer (but slow due to default root directory)

Side-effects

  • Initial deployment takes longer because packaging and deployment are now done even for Lambda functions that are hot reloaded (that's unnecessary).

To fix this issue, we need to think about a new fine-grained API for hot reloading and handle selective deployments of all layers and functions that are not hot reloading.

Questions

  1. Is there a dependency of AwsCompileFunctions.downloadPackageArtifacts ⇒ package (i.e., can we safely skip packaging without downloadPackageArtifacts?
  2. Any other dependencies or implicit compatibility issues (e.g., related to other serverless plugins)?

@joe4dev joe4dev requested a review from whummer May 17, 2023 10:02
Copy link
Member

@whummer whummer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks for jumping on this one @joe4dev ! 🚀

Fully agree with the points you've mentioned, including the non-ideal naming of mountCode, etc. We can tackle those points in future iterations. 👍 Also, would be great if we extend the integration tests in this repo a bit over time, to also cover advanced use cases (like Lambda layers).

@joe4dev joe4dev merged commit 203a9c9 into master May 17, 2023
@joe4dev joe4dev deleted the fix/deploy-layers-when-hot-reload-enabled branch May 17, 2023 11:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants