使用无服务器部署 AWS Lambda 函数在需要外部模块时不会部署
Posted
技术标签:
【中文标题】使用无服务器部署 AWS Lambda 函数在需要外部模块时不会部署【英文标题】:Deploying an AWS Lambda function using serverless does not deploy when external modules are required 【发布时间】:2020-06-07 14:51:49 【问题描述】:我目前正在尝试使用无服务器部署 AWS lambda 函数。如果我不包含任何外部模块,我可以获得正确部署和响应的功能,但是一旦我尝试包含 dynogels 和 Joi:
const dynogels = require("dynogels");
const Joi = require("@hapi/joi");
serverless deploy
命令不会通过“打包外部模块”
不包含外部模块时的完整输出:
❯ sls deploy
addHandler: './addHandler.js'
Serverless: Bundling with Webpack...
1 module
Serverless: No external modules needed
Serverless: Packaging service...
Serverless: Uploading CloudFormation file to S3...
Serverless: Uploading artifacts...
Serverless: Uploading service game-data-service.zip file to S3 (1.9 KB)...
Serverless: Validating template...
Serverless: Updating Stack...
Serverless: Checking Stack update progress...
..............
Serverless: Stack update finished...
Service Information
service: game-data-service
stage: dev
region: ap-southeast-2
stack: game-data-service-dev
resources: 11
api keys:
None
endpoints:
POST - XXXXXXXXXXX/endpoint
functions:
addData: game-data-service-dev-addData
layers:
None
Serverless: Updated basepath mapping.
Serverless Domain Manager Summary
Domain Name
XXXXXXXXXXX.com
Distribution Domain Name
Target Domain: XXXXXXXXXXX
Hosted Zone Id: XXXXXXXXXXX
Serverless: Removing old service artifacts from S3...
Serverless: Run the "serverless" command to setup monitoring, troubleshooting and testing.
包含外部模块时的完整输出:
❯ sls deploy
addHandler: './addHandler.js'
Serverless: Bundling with Webpack...
3 modules
Serverless: Package lock found - Using locked versions
Serverless: Packing external modules: dynogels@^9.1.0, @hapi/joi@^17.1.0
软件包已安装。我不明白为什么这没有部署。有什么方法可以让我从部署中看到一些错误? --verbose
似乎没有提供太多额外信息。感谢您的帮助!
编辑
serverless.yml
service: game-data-service
provider:
name: aws
runtime: nodejs12.x
stage: dev
region: ap-southeast-2
environment:
SERVICE_NAME: $self:service
iamRoleStatements:
- Effect: Allow
Action:
- dynamodb:DescribeTable
- dynamodb:DescribeTable
- dynamodb:Query
- dynamodb:Scan
- dynamodb:GetItem
- dynamodb:PutItem
- dynamodb:UpdateItem
- dynamodb:DeleteItem
- dynamodb:BatchGetItem
Resource: "arn:aws:dynamodb:ap-southeast-2:*:*"
- Effect: Allow
Action:
- codepipeline:StartPipelineExecution
Resource: "arn:aws:codepipeline:ap-southeast-2:*:*"
- Effect: Allow
Action:
- s3:PutObject
- s3:PutObjectAcl
Resource: "arn:aws:s3:::XXXXXXXXXXX-assets-bucket/*"
plugins:
- serverless-domain-manager
- serverless-webpack
custom:
stage: $opt:stage, self:provider.stage
admin_arn: XXXXXXXXXX
user_arn: XXXXXXXXXXX
domains:
prod: XXXXXXXXXXX.com
staging: XXXXXXXXXXX.com
dev: XXXXXXXXXXX.com
webpack:
webpackConfig: "webpack.config.js"
includeModules: true # Node modules configuration for packaging
packagePath: "../package.json"
customDomain:
basePath: gameData
domainName: $self:custom.domains.$self:custom.stage
stage: "$self:custom.stage"
createRoute53Record: true
##############################################################
# Functions
##############################################################
functions:
addData:
handler: addHandler.hello
events:
- http: POST add
webpack.config.js
const slsw = require("serverless-webpack");
const nodeExternals = require("webpack-node-externals");
var path = require("path");
function resolve(dir)
return path.join(__dirname, dir);
console.log(slsw.lib.entries);
module.exports =
entry: slsw.lib.entries,
target: "node",
// Since 'aws-sdk' is not compatible with webpack,
// we exclude all node dependencies
externals: [nodeExternals()],
resolve:
alias:
"@": resolve("../lib"),
"=": resolve("../db")
,
optimization:
minimize: false
,
mode: slsw.lib.webpack.isLocal ? "development" : "production",
stats: "minimal"
;
addHandler.js
"use strict";
import success, failure from "@/response";
// import schema from "=/schema";
// import gameSchema from "=/gameSchema";
// const dynogels = require("dynogels");
// const Joi = require("@hapi/joi");
const cowsay = require("cowsay");
export const hello = (event, context, callback) =>
console.log("Running ADD");
console.log(cowsay.say( text: "Mooodule" ));
const body = JSON.parse(event.body);
const table = body["table"];
const data = body["data"];
if (body["table"] == null)
callback(
null,
failure(
error: "You must provide the table name in the body"
)
);
console.log(`Body recieved for table $table:`, data);
callback(null, success( message: `Data added to $table` ));
// try
// gameSchema[event.pathParameters.table].create(body, (err, res) =>
// if (err)
// callback(null, failure( error: err ));
// return;
//
// callback(null, success(res));
// );
// callback(null, success(res));
// catch (err)
// callback(null, failure( error: err ));
// return;
//
;
【问题讨论】:
哪里出错了? @hephalump - 没有错误消息,它显示“打包外部模块”,这是我收到的最后一个输出。然后它不会部署该功能。 很奇怪。您使用的是什么版本的无服务器?我从未听说过这种行为。除非手动退出,否则它始终会产生输出。您是否尝试将其隔离为单个依赖项?所以只做 Joi 或 dynogels,而不是两者兼而有之。是否可以包含任何其他依赖项? @hephalump 我试过只使用 dynogels 和 Joi,同样的问题。我尝试从 npm 安装和保存 cowsay 并使用完全不同的依赖项 - 同样的问题。我试过包含我自己的 js 文件,这似乎工作正常...... 您使用的是哪个版本的SLS
?另外,您使用的是什么包管理器?
【参考方案1】:
尝试将Lambda Layers 用于您的 SAM 应用程序。
【讨论】:
以上是关于使用无服务器部署 AWS Lambda 函数在需要外部模块时不会部署的主要内容,如果未能解决你的问题,请参考以下文章
AWS攻略——使用CodeBuild进行自动化构建和部署Lambda(Python)
无服务器AWS Lambda:没有名为`secret_manager`的模块