web-dev-qa-db-fra.com

Nodejs - Invoque une fonction AWS.Lambda depuis une autre fonction lambda

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;
45
hyprstack

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".

lambda invoke

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:

Lambda_B

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 ):

lambda-role-for-intra-lambda-execution

Lambda_A

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:

lambda invoke-lambda_a-execution-result

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 .

91
nelsonic

À 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.

enter image description here

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.

enter image description here

25
C.Lee

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:

  • AWSLambdaExecute
  • AWSLambdaBasicExecutionRole

Mais cela ne me permettait pas d'invoquer mon autre fonction lambda, alors j'ai changé le rôle en bas:

  • AWSLambdaRole
  • AWSLambdaBasicExecutionRole

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.

2
Mohammed Asad