使用 Lambda Layers 在 lambda 之间共享 node_modules 文件夹云的形成
我有一个项目,使用serverless-framework(this)来定义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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
一般来说,使用 Lambda Layers 是存储共享代码的好方法,因为您可以减少冗余并保持部署包的大小较小。
也可以使用 Serverless 框架创建层,因此您可以将它们包含到现有模板中并由 Serverless/CloudFormation 管理。以下是文档的链接,其中包含配置示例和说明。以下是如何向 serverless.yaml 文件添加一层的示例:
然后,您可以从 serverless-functions.yaml 文件中的每个 Lambda 函数中参考层如下:
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:
And then from each Lambda function in your serverless-functions.yaml file, you can refer to the layer as follows: