在 nodejs 中,我可以有子文件夹,每个子文件夹都承载一个 AWS lambda 函数吗?

In nodejs, can I have sub-folders that each sub-folder host a AWS lambda function?

我正在尝试在 AWS 上实施无服务器应用程序。我想知道一种组织代码的好方法。比方说,我想在 git 存储库下组织多个 lambda 函数,每个 lambda 函数及其关联代码都在其自己的子文件夹中。

这是我尝试过的,为每个 lambda 函数单独的​​子文件夹:

(venv367) dummy@dummy-VirtualBox:~/workspace/serverless-apps/DEVOPS-dailybackup-ebs$ ls -l
total 28
-rw-rw-r-- 1 dummy dummy 4061 Jan 13 19:23 index.js
drwxrwxr-x 3 dummy dummy 4096 Jan 13 19:23 node_modules
-rw-rw-r-- 1 dummy dummy  352 Jan 13 19:23 package.json
-rw-rw-r-- 1 dummy dummy  392 Jan 13 19:23 package-lock.json
-rw-rw-r-- 1 dummy dummy 1220 Jan 14 00:10 README.md

(venv367) dummy@dummy-VirtualBox:~/workspace/serverless-apps/DEVOPS-dailybackup-s3$ ls -l
total 28
-rw-rw-r-- 1 dummy dummy 4061 Jan 13 19:23 index.js
drwxrwxr-x 3 dummy dummy 4096 Jan 13 19:23 node_modules
-rw-rw-r-- 1 dummy dummy  352 Jan 13 19:23 package.json
-rw-rw-r-- 1 dummy dummy  392 Jan 13 19:23 package-lock.json
-rw-rw-r-- 1 dummy dummy 1220 Jan 14 00:10 README.md

在顶级项目中,我有 SAM template.yaml 如下

(venv367) dummy@dummy-VirtualBox:~/workspace/serverless-apps$ ls -l
total 16
drwxrwxr-x 3 dummy dummy 4096 Jan 14 05:14 00_DEVOPS-dailybackup-ebs
drwxrwxr-x 3 dummy dummy 4096 Jan 14 05:14 00_DEVOPS-dailybackup-s3
-rw-rw-r-- 1 dummy dummy  702 Jan 14 05:15 packaged.yaml
-rw-rw-r-- 1 dummy dummy 1402 Jan 13 23:45 README.md
-rw-rw-r-- 1 dummy dummy  939 Jan 14 05:15 template.yaml

在 template.yaml 中,我通过指定 Handler 及其父目录来部署 Lambda 函数

Resources:
    EbsBackupFunction:
        Type: AWS::Serverless::Function 
        Properties:
            Handler: DEVOPS-dailybackup-ebs/index.handler
            Runtime: nodejs8.10
            FunctionName: DEVOPS-dailybackup-ebs

    S3BackupFunction:
        Type: AWS::Serverless::Function 
        Properties:
            Handler: DEVOPS-dailybackup-s3/index.handler
            Runtime: nodejs8.10
            FunctionName: DEVOPS-dailybackup-s3

(1) 不过,我还没有详细研究无服务器框架。使用 AWS SAM 管理无服务器应用程序有更好的方法吗?

(2) 有没有办法在每个子文件夹下为 nodejs 代码做 npm 安装,而不是写一个脚本来做 'cd ${dir} && npm install'

(3)如果上面的想法很糟糕,你能告诉我你会怎么做吗?

如有任何帮助,请提前致谢。

  1. 你处理多个函数的方法是currently suggested方法。

  2. 可以根据您的 CI/CD 工具采取不同的方法。这是我当前用于 AWS CodeBuild 的 buildspec.yml

version: 0.2
phases:
  pre_build:
    commands:
      - for d in lambdas/*/; do npm --prefix $d install $d; done
  build:
    commands:
      - |
        aws cloudformation package \
          --template-file template.yml \
          --s3-bucket "<bucket name>" \
          --s3-prefix sam \
          --output-template-file packaged.yml
  post_build:
    commands:
      - |
        aws cloudformation deploy \
          --template-file packaged.yml \
          --stack-name "<stack name>" \
          --capabilities CAPABILITY_NAMED_IAM

这允许我通过 .gitignore 保持我的本地 directory/code 存储库干净(没有 node_modules 文件夹),但在部署之前安装依赖项。请注意,包含您的 package-lock.json 文件对于避免不同包版本的错误是必要的。

  1. 如上所述,这与我当前使用的设置相同。到目前为止,我看到的唯一缺点是无法在不更新所有功能的情况下更新单个功能,但是由于我的环境设置方式(所有功能共享相同的版本号),对一个功能的更改无论如何都需要对其他人进行更改。

了解您正在使用 SAM,但如果您愿意考虑 serverless framework 那么这就是您可以通过一个命令在 CI/CD 管道中管理它的方式。所有 Lambda 都将单独部署,并且每个函数都将在 node_modules 中具有函数

所需的依赖项

您需要在 package.json devDependencies 中添加以下内容。

"devDependencies": {
    "serverless-plugin-optimize": "^4.0.2-rc.1"
 }

serverless-plugin-optimize用于优化Lambda代码及其依赖。

注意:使用 serverless-plugin-optimize 时,您必须确保所有 require(..) 都放在处理程序中的 module.exports 上方。

你还需要serverless framework,你可以全局安装它。

npm install -g serverless

存储库结构:

devops-backup/
 - node_modules/
 - package.json
 - serverless.yml
 - handlers/
   - s3.js
   - ebs.js

serverless.yml配置:

service: DevOpsBackup
frameworkVersion: '>=1.2.1 <2.0.0'
provider:
  name: aws
  runtime: nodejs8.10
  region: eu-west-1
  stage: ${opt:stage} # Stage that you define when deploy using `serverless deploy --stage`
  deploymentBucket: ${env:SLS_BUCKET} # Your deployment bucket name. CI must have access to this bucket.

iamRoleStatements:
  - Effect: Allow
    Action:
      - s3:"*"
    Resource: arn:aws:s3:::<bucket_name>
  # Add more permissions as required by the functions

plugins:
  - serverless-plugin-optimize

package:
  individually: true

functions:
  backupEbs:
    handler: handlers/s3.handler
    description: Create user
  backupS3:
    handler: handlers/ebs.handler
    description: Update user

示例s3.js

module.exports.handler = async (event) => {
 // ... your code
}

部署

您可以使用一个命令部署所有 Lambda,运行 从存储库根目录。

serverless deploy --stage prod -v # prod 是 stage/env

的名字

如果构建成功,您将能够在 Lambda 控制台中找到您的函数。

  • DevOpsBackup-prod-backupS3
  • DevOpsBackup-prod-backupEbs