Создание лямбда-функции в AWS из zip файла
Я пытаюсь создать простую лямбда-функцию, и я столкнулся с ошибкой.
Мой код в основном
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');
}
в файле helloworld.js. Я застегнул это и загрузил его в виде zip файла при создании секции лямбда-функции, и я продолжаю получать эту ошибку:
{
"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)"
]
}
У кого-нибудь есть идеи?
Ответы
Ответ 1
Имя вашего файла должно соответствовать имени модуля в конфигурации Handler. В этом случае ваш обработчик должен быть установлен в helloworld.handler
, где helloworld
- это файл, который будет требовать() 'd и handler
- экспортированная функция. Затем он должен работать с одним и тем же zip файлом.
![AWS Lambda configuration screenshot]()
Ответ 2
Убедитесь, что ваш index.js находится в корневом каталоге zipfile, а не в подкаталоге.
В моем случае у меня было имя модуля, соответствующего имени файла и экспортированному обработчику, реальной проблемой был macOS и zip-программа, которая в основном создает папку внутри zip файла, поэтому при несжатом в AWS Lambda engine index.js заканчивается в подкаталоге.
Использование Finder
Не щелкайте правой кнопкой мыши и не сжимайте каталог, вместо этого выберите файлы с отдельными файлами, такими как index.js, package.json и каталог node_modules и щелкните правой кнопкой мыши для сжатия, вы можете закончить с файлом Archive.zip в том же каталоге. Имя zip файла не будет выглядеть, но, по крайней мере, оно будет работать, когда вы отправите его в AWS Lambda.
Использование командной строки
Вы можете сделать ту же ошибку, используя командную строку с 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%)
Как узнать подтверждение вашего zip файла
Используя finder, если вы дважды щелкните zip файл, и он распакуется в подкаталоге, Lambda не сможет увидеть файл, поскольку index.js живет в этом подкаталоге.
Используя командную строку и 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
Обратите внимание, что 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
Обратите внимание, что index.js не находится внутри подпапки, этот zip файл будет работать в AWS Lambda.
Использование команд npm для zip функции
Итак, я добавил script в мой пакет, чтобы заархивировать файлы проекта для меня, просто запустив 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%)
Ответ 3
Автоматизация - с помощью Grunt
Завершить Проект AWS Lambda Seed доступен на Git.
Шаг 1: Инициировать модуль npm
npm init
Шаг 2: Установите Grunt
npm install --save-dev grunt grunt-cli
Шаг 3: Установить grunt-aws-lambda
npm install --save-dev grunt-aws-lambda
Шаг 4: Создать папку для службы лямбды
# Create directory
mkdir lambdaTest
# Jump into folder
cd lambdaTest
# Create service file
touch lambdaTest.js
# Initialize npm
npm init
Держите свою логику/код в lambdaTest.js
'use strict'
exports.handler = (event, context, callback) => {
console.log("Hello it looks like working");
};
Шаг 5: Создать 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']);
};
Шаг 6: Создать awsCredentials.js
Создайте пользователя AWS IAM с настраиваемой политикой, пользовательская политика должна иметь доступ к lambda:GetFunction
, lambda:UploadFunction
, lambda:UpdateFunctionCode
, lambda:UpdateFunctionConfiguration
и iam:PassRole
{
"accessKeyId": "XXXXXXXXXXXXXXXXXXXX",
"secretAccessKey": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
}
Шаг 7: Создайте zip и разверните его в AWS Lambda.
ls-deploy
- это настраиваемая задача, созданная в Gruntfile выше, которая создает zip исходного кода и развертывается в Lambda.
grunt ls-deploy
Завершить Проект AWS Lambda Seed доступен на Git.
Ответ 4
Вот предварительный путь с AWS CLI. Это сэкономит ваше время в долгосрочной перспективе.
Прежде всего, вы должны установить и настроить AWS CLI:
http://docs.aws.amazon.com/cli/latest/userguide/installing.html
1) Создайте архив
$zip -r lambda *
Он создаст для нас файл lambda.zip со всеми папками и файлами в нашем текущем местоположении.
2) Получить роль ARN
$aws iam list-role | grep "your_role"
Он вернет нам ARN, что мы будем использовать с нашей лямбдой. Вы должны создать его руками.
Пример для списка-роли
3) Создайте нашу лямбда
$aws lambda create-function - имя-функции "your_lambda_name" - zip файл fileb://lambda.zip - обработчик index.handler - время выполнения nodejs6.10 - время ожидания 15 - роль COPY_HERE_YOUR_ARN_FROM_THE_STEP_2
Мы закончили!
Ответ 5
Потому что в export.handler вы не ссылаетесь на функцию индекса. Это можно решить более простым способом.
Попробуйте это,
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');
}