使用Serverless Framework在Lambda中创建Layer

首先

这篇文章是《开放流媒体Advent Calendar 2018》的第14天内容。虽然是根据直觉选择的日期,但无意中与去年的同一天重合了。

最近在re:Invent上宣布和实施的AWS Lambda的Layer功能,由于Serverless Framework已经与之兼容,所以我立刻尝试了一下。执行环境是在VirtualBox上安装的CentOS7,但只要能使用Node.js(npm),环境差异应该并不大。

引入

确认 Node.js 版本是 6.5.0 或以上。

node --version

如果是旧版本,可以使用nvm或yum进行安装。

请确认您正在使用的 Serverless Framework 版本是 1.34.0 或更高版本。

sls --version

如果是旧版本(包括未安装的情况),则执行相同的命令。

npm i -g serverless

使用aws-nodejs模板创建服务。

sls create --template aws-nodejs --path my-service

确认AWS凭据已设置

aws configure list

Layer的实现

我们已经成功地按照上述步骤部署了一个简单的Lambda函数。现在我们要添加一个Layer。

模块的源代码

根据第一份文档的指示,我们创建一个模块,它是一个简单的将参数平方的函数,并且命名为pow。

.
├── handler.js
├── my-layer  ← 任意の名称のディレクトリ(serverless.ymlに記述する)
│   └── nodejs
│       └── node_modules
│           └── pow
│               └── index.js
└── serverless.yml

我-层/寿辰/节点_模块/效能/索引.js是一个普通函数,没有什么值得特别注意的。

module.exports = i => i * i;

设定文件的描述

在serverless.yml文件中编写定义Layer的内容。

service:
provider:
  name: aws
  runtime: nodejs8.10

functions:
  hello:
    handler: handler.hello
# ここから↓を追加
layers:
  mylayer:
    path: my-layer

关于将Layer的名称更改为“mylayer”而不是“my-layer”的原因将在后文中提到。

部署

部署的程序与以往一样。

sls deploy

我会确认 Layer 是否已经创建。

aws lambda list-layers
{
    "Layers": [
        {
            "LayerName": "mylayer", 
            "LayerArn": "arn:aws:lambda:ap-northeast-1:123456789012:layer:mylayer", 
            "LatestMatchingVersion": {
                "LayerVersionArn": "arn:aws:lambda:ap-northeast-1:123456789012:layer:mylayer:1", 
                "Version": 1, 
                "CreatedDate": "2018-12-13T23:59:59.999+0000"
            }
        }
    ]
}

使用Layer

目前的情况下,已创建了 Layer,但它是一个孤独的存在,无法从任何地方调用。
接下来,我们将添加调用 Lambda 函数的 Layer 处理过程。

設置檔案的描述

在函数的定义中添加一个名为layers的参数。

service:
provider:
  name: aws
  runtime: nodejs8.10

functions:
  hello:
    handler: handler.hello
# ここから
    layers:
      - {Ref: MylayerLambdaLayer}
# ここまで追加
layers:
  mylayer:
    path: my-layer

以下は、チャイニーズ語での同義表現です:

這裡出現了將其稱為「mylayer」的原因。文件2包含了這個原因。

你在CloudFormation模板中的层名称将是你的层名称(首字母大写,去除空格)并在末尾添加LambdaLayer。

有件事需要说一下,但是并没有进行预期的转换。

    • my-layer → MyDashlayerLambdaLayer

 

    my_layer → MyUnderscorelayerLambdaLayer

我觉得可以根据个人喜好和政策来决定命名规则,如果称为「MyLayer」,就变成了「MyLayerLambdaLayer」。

修改Lambda函数

将使用由模板生成的Lambda函数(handler.js)更改为使用在Layer中定义的模块(pow)。

'use strict';
const pow = require('pow');
module.exports.hello = async (event, context) => {
  return pow(event.value);
};

我决定不使用REST API,改为一个简单的函数只返回值。

重新部署

修改已经完成。请再次部署。步骤不变。

sls deploy

一旦部署完成后,我们将检查Lambda函数的定义。

aws lambda get-function-configuration --function-name my-service-dev-hello

可以看出,在Layers中注册了创建的Layer。

{
    "Layers": [
        {
            "CodeSize": 206, 
            "Arn": "arn:aws:lambda:ap-northeast-1:123456789012:layer:mylayer:2"
        }
    ], 
    "FunctionName": "my-service-dev-hello", 
    "LastModified": "2018-12-13T23:59:59.999+0000", 
    "RevisionId": "00000000-1111-2222-3333-444444444444", 
    "MemorySize": 1024, 
    "Version": "$LATEST", 
    "Role": "arn:aws:iam::123456789012:role/my-service-dev-ap-northeast-1-lambdaRole", 
    "Timeout": 6, 
    "Runtime": "nodejs8.10", 
    "TracingConfig": {
        "Mode": "PassThrough"
    }, 
    "CodeSha256": "XXXXXXXXXXXXXXXXXXXXX/YYYYYYYYYYYYYYYYYYYYY=", 
    "Description": "", 
    "VpcConfig": {
        "SubnetIds": [], 
        "VpcId": "", 
        "SecurityGroupIds": []
    }, 
    "CodeSize": 387, 
    "FunctionArn": "arn:aws:lambda:ap-northeast-1:123456789012:function:my-service-dev-hello", 
    "Handler": "handler.hello"
}

每个Layer的ARN末尾的数字代表版本号,每次部署时会进行递增。

执行

现在环境已经准备好了。让我们执行一个使用Layer的Lambda函数试试看。

sls invoke --function hello --data '{"value": 2}'
4

返回了乘以自身的数值。pow函数可以正常使用。

总结

最近,AWS SAM有一种压迫感,对Serverless Framework形成竞争压力,但是能省去创建Layer存档的麻烦,我觉得还是有使用场景的。无论何事都应该恰当地使用合适的工具和方法。

额外物品

当我按下述方式放置package.json文件时,期望自动安装其中的dependencies模块,但是结果却不如期望。

.
├── handler.js
├── my-layer
│   └── nodejs
│       ├── node_modules
│       │   └── pow
│       │       └── index.js
│       └── package.json
└── serverless.yml
以下是原文的中文翻译:
https://docs.aws.amazon.com/lambda/latest/dg/configuration-layers.html#configuration-layers-pathhttps://serverless.com/framework/docs/providers/aws/guide/layers#using-your-layers主观的。

广告
将在 10 秒后关闭
bannerAds