Javascript 从 zip 文件在 AWS 中创建 lambda 函数

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/30670957/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 05:34:37  来源:igfitidea点击:

Creating a lambda function in AWS from zip file

javascriptnode.jsamazon-web-servicesaws-lambda

提问by jstnchng

I am trying to create a simple lambda function, and I'm running into an error.

我正在尝试创建一个简单的 lambda 函数,但遇到了错误。

My code is basically

我的代码基本上是

console.log('Loading function');

exports.handler = function(event, context) {
    console.log('value1 =', event.key1);
    console.log('value2 =', event.key2);
    console.log('value3 =', event.key3);
    context.succeed(event.key1);  // Echo back the first key value
    // context.fail('Something went wrong');
}

in a helloworld.js file. I zip that up and upload it as a zip file in the creating a lambda function section, and I keep getting this error:

在 helloworld.js 文件中。我将其压缩并将其作为 zip 文件上传到创建 lambda 函数部分,但我不断收到此错误:

{
  "errorMessage": "Cannot find module 'index'",
  "errorType": "Error",
  "stackTrace": [
    "Function.Module._resolveFilename (module.js:338:15)",
    "Function.Module._load (module.js:280:25)",
    "Module.require (module.js:364:17)",
    "require (module.js:380:17)"
  ]
}

Anyone have any ideas?

谁有想法?

回答by James

The name of your file needs to match the module name in the Handlerconfiguration. In this case, your Handler should be set to helloworld.handler, where helloworldis the file that would be require()'d and handleris the exported function. Then it should work with the same zip file.

您的文件名称需要与Handler配置中的模块名称匹配。在这种情况下,您的 Handler 应该设置为helloworld.handler,其中helloworld需要()的文件handler是导出的函数。然后它应该使用相同的 zip 文件。

AWS Lambda configuration screenshot

AWS Lambda 配置屏幕截图

回答by bithavoc

Make sure your index.js is in the root of the zipfile and not in a subdirectory.

确保您的 index.js 位于 zipfile 的根目录中,而不是在子目录中。

In my case I had the name of the module matching the name of the file and the exported handler, the real problem was macOS and the zip program which basically creates a folder inside the zip file so when uncompressed in AWS Lambda engine the index.js ends in a subdirectory.

就我而言,我的模块名称与文件名称和导出的处理程序相匹配,真正的问题是 macOS 和 zip 程序,它基本上在 zip 文件中创建了一个文件夹,因此当在 AWS Lambda 引擎中解压缩时 index.js以子目录结尾。

Using Finder

使用 Finder

Don't right click and compress the directory, instead select the files individual files like index.js, package.jsonand the node_modulesdirectory and right-click to compress, you may end up with a file Archive.zip in the same directory. The name of the zip file is not going to be fancy but at least it will work when you submit it to AWS Lambda.

不要右键单击并压缩目录,而是选择文件单个文件,例如index.jspackage.jsonnode_modules目录,然后右键单击进行压缩,您可能会在同一目录中得到一个 Archive.zip 文件。zip 文件的名称不会很花哨,但至少当您将其提交给 AWS Lambda 时它会起作用。

Using the command line

使用命令行

You could make the same mistake using the command line with zip -r function.zip functionwhich basically creates a zip file with a directory called functionin it, instead do:

您可以使用命令行犯同样的错误,该命令行zip -r function.zip function基本上会创建一个带有调用目录的 zip 文件function,而是执行以下操作:

$ zip function.zip index.js package.json node_modules

adding: index.js (deflated 47%)
adding: package.json (deflated 36%)
adding: node_modules/ (stored 0%)

How to know verify your zip file

如何知道验证您的 zip 文件

Using finder, if you double click the zip file and it uncompresses in a subdirectory then Lambda won't be able to see the file as index.js lives in that subdirectory.

使用finder,如果您双击 zip 文件并将其解压缩到子目录中,则 Lambda 将无法看到该文件,因为 index.js 位于该子目录中。

Using the command lineand zipinfo:

使用命令行zipinfo

$ zipinfo function.zip | grep index.js | more
-rw-r--rw-  2.1 unx     1428 bX defN 27-Jul-16 12:21 function/index.js

Notice how index.js ended up inside the subdirectory function, you screwed up.

注意 index.js 是如何在子目录中结束的function你搞砸了

$ zipinfo function.zip | grep index.js | more
-rw-r--rw-  3.0 unx     1428 tx defN 27-Jul-16 12:21 index.js

Notice that index.js is not inside a subfolder, this zip file will work in AWS Lambda.

请注意 index.js 不在子文件夹中,此 zip 文件将在 AWS Lambda 中工作

Leveraging npm commands to zip the function

利用 npm 命令压缩函数

So I added a script to my package to zip the project files for me just by running npm run zip

所以我在我的包中添加了一个脚本,只需运行即可为我压缩项目文件 npm run zip

{
  "name": "function",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "zip": "zip function.zip package.json *.js node_modules"
  },
  "dependencies": {
    "aws-sdk": "^2.4.10"
  }
}

$ npm run zip

> [email protected] zip 
> zip function.zip package.json *.js node_modules

  adding: package.json (deflated 41%)
  adding: index.js (deflated 47%)
  adding: local.js (deflated 42%)
  adding: node_modules/ (stored 0%)

回答by Jingo Bingo

Here is an advance way with AWS CLI. It will save your time in long term use.

这是 AWS CLI 的高级方法。长期使用可以节省您的时间。

First of all you should install and configure AWS CLI:

首先,您应该安装和配置 AWS CLI:

http://docs.aws.amazon.com/cli/latest/userguide/installing.html

http://docs.aws.amazon.com/cli/latest/userguide/installing.html

1) Create an archive

1) 创建存档

$ zip -r lambda *

$ zip -r 拉姆达 *

It will create for us lambda.zip file with all folders and files in the our current location.

它将为我们创建 lambda.zip 文件,其中包含我们当前位置中的所有文件夹和文件。

2) Get role ARN

2) 获取角色 ARN

$ aws iam list-roles | grep "your_role"

$ aws iam 列表角色 | grep“你的角色”

It will return to us ARN that we will use with our lambda. You should create it by your hands

它将返回给我们 ARN,我们将在 lambda 中使用它。你应该亲手创造它

Example for list-roles

列表角色示例

3) Create our lambda

3) 创建我们的 lambda

$ aws lambda create-function --function-name"your_lambda_name" --zip-filefileb://lambda.zip --handlerindex.handler --runtimenodejs6.10 --timeout15 --roleCOPY_HERE_YOUR_ARN_FROM_THE_STEP_2

$ aws lambda create-function --function-name"your_lambda_name" --zip-filefileb://lambda.zip --handlerindex.handler --runtimenodejs6.10 --timeout15 --roleCOPY_HERE_YOUR_ARN_FROM_THE_STEP_2

We are done!

我们完了!

回答by jaym

Automation - using Grunt

自动化 - 使用 Grunt

Complete AWS Lambda Seedproject is available on Git.

完整的AWS Lambda Seed项目在Git上可用

Step 1:Init npm module

第 1 步:初始化 npm 模块

npm init

npm init

Step 2:Install Grunt

第 2 步:安装 Grunt

npm install --save-dev grunt grunt-cli

npm install --save-dev grunt grunt-cli

Step 3:Install grunt-aws-lambda

第 3 步:安装grunt-aws-lambda

npm install --save-dev grunt-aws-lambda

npm install --save-dev grunt-aws-lambda

Step 4:Create Folder for Lambda service

步骤 4:为 Lambda 服务创建文件夹

# Create directory
mkdir lambdaTest

# Jump into folder
cd lambdaTest

# Create service file
touch lambdaTest.js

# Initialize npm
npm init

Keep your logic/code into lambdaTest.js

保持你的逻辑/代码进入 lambdaTest.js

'use strict'

exports.handler = (event, context, callback) => {
    console.log("Hello it's looks like working");
};

Step 5:Create Gruntfile.js

第 5 步:创建Gruntfile.js

Navigate back to root folder touch Gruntfile.js

导航回根文件夹 touch Gruntfile.js

'use strict'
module.exports = function (grunt) {
    grunt.initConfig({
        lambda_invoke: {
            lambdaTest: {
                options: {
                    file_name: "lambdaTest/lambdaTest.js",
                    event: "lambdaTest/test.json",
                }
            }
        },
        lambda_package: {
            lambdaTest: {
                options: {
                    package_folder: 'lambdaTest/'
                }
            }
        },
        lambda_deploy: {
            lambdaTest: {
                arn: 'arn:aws:lambda:eu-central-1:XXXXXXXX:function:lambdaTest',
                options: {
                    credentialsJSON: 'awsCredentials.json',
                    region: "eu-central-1"
                },
            }
        },
    });

    grunt.loadNpmTasks('grunt-aws-lambda');


    grunt.registerTask('ls-deploy', ['lambda_package:lambdaTest', 'lambda_deploy:lambdaTest']);
};

Step 6:Create awsCredentials.js

第 6 步:创建awsCredentials.js

Create AWS IAM User with custom policy, Custom policy should have access to lambda:GetFunction, lambda:UploadFunction, lambda:UpdateFunctionCode, lambda:UpdateFunctionConfigurationand iam:PassRole

创建自定义策略AWS IAM用户,自定义政策应该有机会获得lambda:GetFunctionlambda:UploadFunctionlambda:UpdateFunctionCodelambda:UpdateFunctionConfigurationiam:PassRole

{
    "accessKeyId": "XXXXXXXXXXXXXXXXXXXX",
    "secretAccessKey": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
}

Step 7:Create a zip and deploy to AWS Lambda.

步骤 7:创建一个 zip 文件并部署到 AWS Lambda。

ls-deployis custom task created by in Gruntfile above, which creates a zip of source code and deploy to Lambda.

ls-deploy是由上面的 Gruntfile 创建的自定义任务,它创建源代码的 zip 并部署到 Lambda。

grunt ls-deploy

grunt ls-deploy

Complete AWS Lambda Seedproject is available on Git.

完整的AWS Lambda Seed项目在Git上可用

回答by kisHoR

Its because in exports.handler, you are not referencing the index function. This can be solved in a more simpler way

这是因为在exports.handler 中,您没有引用索引函数。这可以用更简单的方式解决

Try this,

尝试这个,

console.log('Loading function');

    exports.handler = function index (event, context) {
        console.log('value1 =', event.key1);
        console.log('value2 =', event.key2);
        console.log('value3 =', event.key3);
        context.succeed(event.key1);  // Echo back the first key value
        // context.fail('Something went wrong');
    }