[AWS SAM] Lambda层的定义(nodejs)
为了达到的结果或目标。
在上一篇文章中,我们使用了cfn-response模块,但它只支持内联实现,不够方便。因此,我们需要将它作为一个Layer进行实施。
文件结构
lambda-layer/
├─ layers/
│ └─ cfn-response-layer/
│ └─ nodejs/
│ ├─ node_modules/ # [npm i cfn-response] で生成
│ ├─ cfn-response/
│ │ ├─ package.json # [npm init] で生成
│ │ └─ index.js # Layerとして提供する機能
│ │
│ ├─ package.json
│ └─ package-lock.json # [npm i cfn-response] で生成
│
└─ template.yaml # SAMテンプレート
※nodejs文件夹名称不可更改
※index.js文件可以更改名称,但如果更改为其他名称,则在执行npm init时需要指定文件名
山姆的模板
CfnResponse:
Type: AWS::Serverless::LayerVersion
Properties:
LayerName: !Sub ${RootStackName}_cfn-response
ContentUri: layers/cfn-response-layer
CompatibleRuntimes:
- nodejs12.x
RetentionPolicy: Delete
在提供层功能方面,决定将其放置在nodejs文件夹中,
对于ContentUri,请指定路径到前一个目录。
cfn-response 模块的实现
index.js 索引.js
在index.js中实现cfn-response模块的功能
复制github上公开的cfn-response模块代码
提供SUCCESS和FAILED的定义值以及send函数
const https = require('https');
const url = require('url');
module.exports = {
SUCCESS: 'SUCCESS',
FAILED: 'FAILED',
send(
event,
context,
responseStatus,
responseData,
physicalResourceId,
noEcho,
) {
return new Promise((resolve, reject) => {
const responseBody = JSON.stringify({
Status: responseStatus,
Reason: `See the details in CloudWatch Log Stream: ${context.logStreamName}`,
PhysicalResourceId: physicalResourceId || context.logStreamName,
StackId: event.StackId,
RequestId: event.RequestId,
LogicalResourceId: event.LogicalResourceId,
NoEcho: noEcho || false,
Data: responseData,
});
console.log('Response body:\n', responseBody);
const parsedUrl = url.parse(event.ResponseURL);
const options = {
hostname: parsedUrl.hostname,
port: 443,
path: parsedUrl.path,
method: 'PUT',
headers: {
'content-type': '',
'content-length': responseBody.length,
},
};
const request = https.request(options, response => {
console.log(`Status code: ${response.statusCode}`);
console.log(`Status message: ${response.statusMessage}`);
resolve(context.done());
});
request.on('error', error => {
console.log(`send(..) failed executing https.request(..): ${error}`);
reject(context.done(error));
});
request.write(responseBody);
request.end();
});
},
};
nodejs/cfn-response/package.json的中文翻译:
在nodejs/cfn-response/的目录下运行npm init
如果全部选择默认值,将会生成以下的package.json文件
{
"name": "cfn-response",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC"
}
nodejs/package.json可以在此处找到。
仅使用内容{}创建package.json文件
当执行npm install <包名称>,将会添加附加内容
node_modules和package-lock.json
在nodejs文件夹及其子文件夹中运行npm i cfn-response命令会生成index.js文件。该文件使用https和url包,因为这些是nodejs的标准模块,所以无需安装。
使用Layer
SAM模板
ApplyNotificationFunction:
Type: AWS::Serverless::Function
Properties:
FunctionName: !Sub ${RootStackName}-ApplyNotificationFunction
CodeUri: handlers
Role: !GetAtt 'ApplyNotificationFunctionRole.Arn'
Layers:
- !Ref CfnResponse # 先ほどSAMテンプレートで定義したLayerを参照
code
const cfnResponse = require('cfn-response');
exports.handler = async (event, context) => {
try {
if (event.RequestType !== 'Create') {
await cfnResponse.send(event, context, cfnResponse.SUCCESS);
return;
}
...