使用 Lambda Layers 在 lambda 之间共享 node_modules 文件夹云的形成

发布于 2025-01-09 10:44:37 字数 2598 浏览 1 评论 0原文

我有一个项目,使用serverless-frameworkthis)来定义AWS要使用的资源。我有各种 .yml 文件,它们描述了项目运行所需的每个资源。

最近,我不得不为我的 lambda 安装几个 NPM 包,它们已经变得非常大,以兆字节计 (> 3MB),因此无法再从控制台查看代码。

由于在每个 lambda 中包含 node_modules 并不是最佳实践,而且这种方式非常繁重,因此我想知道是否使用 Lambda Layer 在 lambda 之间共享 node_modules。

作为 .yml,我在它们之间有一个共享结构,称为 provider.yml,类似于:

name: aws
runtime: nodejs14.x
lambdaHashingVersion: 20201221
region: ${opt:region, "eu-central-1"}
stage: ${opt:stage, "dev"}
profile: ${self:custom.profiles.${self:provider.stage}}
deploymentBucket:
 name: avatar-${self:provider.stage}-deploymentbucket
 versioning: true
 blockPublicAccess: true
environment:
 EXAMPLE_ENV_VAR: ${self:custom.baseResource}-envvar
USERPOOL:
 'Fn::ImportValue': ${self:custom.baseResource}-userPoolId
APP_CLIENT_ID:
 'Fn::ImportValue': ${self:custom.baseResource}-userPoolClientId
iamRoleStatements:
 - Effect: Allow
 Action:
  - dynamodb:Query
  - ...
Resource: "*"

然后我有一个包含provider.yml 和所有 lambda 的文件(称为 serverless.yml ),这是我用来部署的文件:

service: listOfLambdas
app: appname
frameworkVersion: '2'
projectDir: ../../

provider: ${file(../../resources/serverless-shared-config/provider.yml)}

package:
 individually: true
 exclude:
  - "**/*"

functions:
 - ${file(./serverless-functions.yml)}

最后,我有包含 Lambdas 结构的 serverless-functions.yml:

lambdaName:
handler: src/handlers/auth/example.run
name: ${self:custom.base}lambdaName
description: Lambda description
events:
 - httpApi:
     method: POST
     path: /api/v1/example
package:
 include:
   - ../../node_modules/**

这包括 Lambda 中的 node_modules 文件夹。

如何使用 Cloud Formation 管理的 YML 模板创建资源,以创建 Lambda 层,我可以将所有 lambda 分配给该层,以便它们共享 node_modules 文件夹。我希望必须使用 CloudFormation YML 模板 在资源文件夹内创建一个新的serveless.yml,以便以某种方式绑定到我的 lambda。

我需要它由 CloudFormation 管理,这样我就可以拥有一个包含项目使用的所有资源的公共堆栈,这样我就可以在启动时部署它。

那么,node_modules 应该文件夹在项目中的哪里?现在的项目是这样的:

Root
|_ lib
|_ node_modules
|_ resources
   |_serverless-shared-config
     |_provider.yml
   |_s3
     |_serverless.yml
   |_apigateay 
   |_ ... 
|_ services
   |_ lambda
      |_ src
         |_ index.js
         |_ ...
      |_ serverless.yml
      |_ serverless-functions.yml

我在哪里可以找到一个模板来解决这个问题?或者在 Lambda 之间共享 node_modules 的最佳实践是什么?

I have a project that uses serverless-framework (this) to define the AWS resources to be used. I have the various .yml files that describe each resource that the project needs to run.

Recently, I've had to install several NPM packages for my lambdas and they've become very large in megabytes (>3MB), so the code is no longer viewable from the console.

Since including node_modules in each lambda is not a best practice and they are very heavy this way, I was wondering about using a Lambda Layer to share node_modules between lambdas.

As .yml I have a shared structure between all of them called provider.yml, something like:

name: aws
runtime: nodejs14.x
lambdaHashingVersion: 20201221
region: ${opt:region, "eu-central-1"}
stage: ${opt:stage, "dev"}
profile: ${self:custom.profiles.${self:provider.stage}}
deploymentBucket:
 name: avatar-${self:provider.stage}-deploymentbucket
 versioning: true
 blockPublicAccess: true
environment:
 EXAMPLE_ENV_VAR: ${self:custom.baseResource}-envvar
USERPOOL:
 'Fn::ImportValue': ${self:custom.baseResource}-userPoolId
APP_CLIENT_ID:
 'Fn::ImportValue': ${self:custom.baseResource}-userPoolClientId
iamRoleStatements:
 - Effect: Allow
 Action:
  - dynamodb:Query
  - ...
Resource: "*"

Then I have a file that includes the provider.yml and all the lambdas (called serverless.yml) and is the file that I use to deploy:

service: listOfLambdas
app: appname
frameworkVersion: '2'
projectDir: ../../

provider: ${file(../../resources/serverless-shared-config/provider.yml)}

package:
 individually: true
 exclude:
  - "**/*"

functions:
 - ${file(./serverless-functions.yml)}

Finally, I have the serverless-functions.yml that contains the Lambdas structure:

lambdaName:
handler: src/handlers/auth/example.run
name: ${self:custom.base}lambdaName
description: Lambda description
events:
 - httpApi:
     method: POST
     path: /api/v1/example
package:
 include:
   - ../../node_modules/**

This includes the node_modules folder in the Lambda.

How can I create a resource with a YML template managed by Cloud Formation to create a Lambda Layer to which I can assign all my lambdas so that they share the node_modules folder. I expect to have to create a new serveless.yml inside the resources folder with the CloudFormation YML template to bind I guess somehow to my lambdas.

I need it to be managed by CloudFormation, so I can have a common stack with all the resources used by the project and so I can deploy it at start-up.

Where should the node_modules then be foldered in the project? Now the project is something like:

Root
|_ lib
|_ node_modules
|_ resources
   |_serverless-shared-config
     |_provider.yml
   |_s3
     |_serverless.yml
   |_apigateay 
   |_ ... 
|_ services
   |_ lambda
      |_ src
         |_ index.js
         |_ ...
      |_ serverless.yml
      |_ serverless-functions.yml

Where can I find a template in order to solve this problem? Or what is the best practice in order to share the node_modules between Lambdas?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

春风十里 2025-01-16 10:44:37

一般来说,使用 Lambda Layers 是存储共享代码的好方法,因为您可以减少冗余并保持部署包的大小较小。
也可以使用 Serverless 框架创建层,因此您可以将它们包含到现有模板中并由 Serverless/CloudFormation 管理。以下是文档的链接,其中包含配置示例和说明。以下是如何向 serverless.yaml 文件添加一层的示例:

layers:
  NodeModules:
    path: layer
    package:
      artifact: layer.zip
    name: layer
    compatibleRuntimes:
      - nodejs12.x
      - nodejs14.x

functions:
 - ${file(./serverless-functions.yml)}

然后,您可以从 serverless-functions.yaml 文件中的每个 Lambda 函数中参考层如下:

lambdaName:
  handler: src/handlers/auth/example.run
  name: ${self:custom.base}lambdaName
  layers:
    - { Ref: NodeModulesLambdaLayer }

Generally speaking, using Lambda Layers is a good approach to store shared code as you can reduce redundancy and keep the size of deployment packages small.
Layers can be created using the Serverless framework as well, so you can include them into your existing templates and have them managed by Serverless/CloudFormation. Here is a link to the documentation with configuration examples and explanations. Here is one example of how to add a layer to your serverless.yaml file:

layers:
  NodeModules:
    path: layer
    package:
      artifact: layer.zip
    name: layer
    compatibleRuntimes:
      - nodejs12.x
      - nodejs14.x

functions:
 - ${file(./serverless-functions.yml)}

And then from each Lambda function in your serverless-functions.yaml file, you can refer to the layer as follows:

lambdaName:
  handler: src/handlers/auth/example.run
  name: ${self:custom.base}lambdaName
  layers:
    - { Ref: NodeModulesLambdaLayer }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文