J'ai la fonction suivante que j'utilise pour appeler une fonction Lambda à partir de mon code.
Cependant, lorsque j'essaie de l'utiliser dans une fonction Lambda, l'erreur suivante apparaît:
AWS lambda undefined 0.27s 3 retries] invoke({ FunctionName: 'my-function-name',
InvocationType: 'RequestResponse',
LogType: 'Tail',
Payload: <Buffer > })
Comment invoquer une fonction Lambda depuis une fonction Lambda?
Ma fonction:
'use strict';
var AWS = require("aws-sdk");
var lambda = new AWS.Lambda({
apiVersion: '2015-03-31',
endpoint: 'https://lambda.' + process.env.DYNAMODB_REGION + '.amazonaws.com',
logger: console
});
var lambdaHandler = {};
// @var payload - type:string
// @var functionName - type:string
lambdaHandler.invokeFunction = function (payload, functionName, callback) {
var params = {
FunctionName: functionName, /* required */
InvocationType: "RequestResponse",
LogType: "Tail",
Payload: new Buffer(payload, 'utf8')
};
var lambdaRequestObj = lambda.invoke(params);
lambdaRequestObj.on('success', function(response) {
console.log(response.data);
});
lambdaRequestObj.on('error', function(response) {
console.log(response.error.message);
});
lambdaRequestObj.on('complete', function(response) {
console.log('Complete');
});
lambdaRequestObj.send();
callback();
};
module.exports = lambdaHandler;
Invoquer une fonction Lambda depuis une autre fonction Lambda est assez simple en utilisant le aws-sdk
Qui est disponible dans chaque Lambda.
Je suggère de commencer par quelque chose simple en premier.
Voici le "Hello World" de l'invocation intra-lambda:
Lambda_A
Appelle Lambda_B
Avec un Payload
contenant un seul paramètre name:'Alex'
.Lambda_B
Répond avec une charge utile: "Hello Alex"
.
Commencez par créer Lambda_B
, Ce qui attend une propriété name
sur le paramètre event
et répond à la demande avec "Hello "+event.name
:
exports.handler = function(event, context) {
console.log('Lambda B Received event:', JSON.stringify(event, null, 2));
context.succeed('Hello ' + event.name);
};
Assurez-vous de donner le même rôle à Lambda_B
Et à Lambda_A
.
Exemple: créer un rôle appelé lambdaexecute
qui comporte à la fois AWSLambdaExecute
et AWSLambdaBasicExecutionRole
( pour une raison quelconque, les deux étaient obligatoires ):
var AWS = require('aws-sdk');
AWS.config.region = 'eu-west-1';
var lambda = new AWS.Lambda();
exports.handler = function(event, context) {
var params = {
FunctionName: 'Lambda_B', // the lambda function we are going to invoke
InvocationType: 'RequestResponse',
LogType: 'Tail',
Payload: '{ "name" : "Alex" }'
};
lambda.invoke(params, function(err, data) {
if (err) {
context.fail(err);
} else {
context.succeed('Lambda_B said '+ data.Payload);
}
})
};
Une fois que vous avez enregistré ces deux fonctions Lambda, lancez le test Lambda_A
:
Une fois que l'invocation intra-lambdda fonctionne de base , vous pouvez facilement l'étendre pour invoquer des fonctions Lambda plus élaborées.
La principale chose que vous devez rappelez-vous est de définissez le
ARN Role
Approprié pour toutes les fonctions .
À compter du 3 décembre 2016, vous pouvez simplement utiliser une fonction AWS Step pour définir la fonction Lambda Lambda_B en tant qu'étape séquentielle de Lambda_A .
Avec AWS Step Functions, vous définissez votre application comme une machine à états, une série d'étapes qui capturent ensemble le comportement de l'application. Les états de la machine à états peuvent être des tâches, des étapes séquentielles, des étapes parallèles, des chemins de branchement (choix) et/ou des temporisateurs (attente). Les tâches sont des unités de travail. Ce travail peut être effectué par des fonctions AWS Lambda, des instances Amazon EC2 de tout type, des conteneurs ou des serveurs sur site. Toute tâche pouvant communiquer avec l'API Step Functions peut être affectée à une tâche.
La machine à états suivante devrait donc répondre à vos besoins.
Voici le code correspondant à la machine à états.
{
"Comment": "A simple example of the Amazon States Language using an AWS Lambda Function",
"StartAt": "Lambda_A",
"States": {
"Lambda_A": {
"Type": "Task",
"Resource": "arn:aws:lambda:REGION:ACCOUNT_ID:function:FUNCTION_NAME",
"Next": "Lambda_B"
},
"Lambda_B":{
"Type": "Task",
"Resource": "arn:aws:lambda:REGION:ACCOUNT_ID:function:FUNCTION_NAME",
"End": true
}
}
}
De plus, vous pouvez ajouter des logiques beaucoup plus sophistiquées dans une machine à états, telles que des étapes parallèles et des échecs de capture. Il enregistre même les détails de chaque exécution, ce qui améliore considérablement le débogage, en particulier pour les fonctions lambda.
Tout ce que mentionne @nelsonic est correct, à l'exception des rôles.
J'ai essayé de choisir les rôles qu'il a mentionnés ci-dessus:
Mais cela ne me permettait pas d'invoquer mon autre fonction lambda, alors j'ai changé le rôle en bas:
La raison derrière est AWSLambdaExecute seulement fournit Put, Obtenez l'accès à S3 et un accès complet aux journaux CloudWatch. mais AWSLambdaRole fournit stratégie par défaut pour le rôle de service AWS Lambda. Si vous observez sa stratégie de permission, elle parlera de invokeFunction
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"lambda:InvokeFunction"
],
"Resource": [
"*"
]
}
]
}
Remarque : il est correct de poursuivre sans AWSLambdaBasicExecutionRole, car elle active uniquement la journalisation dans le nuage ne surveille pas grand-chose. Mais AWSLambdaRole est absolument nécessaire.