4

How can I invoke a Lambda function within a Lambda function?

for example,

in function 1, it will be triggered by an API Gateway request and will invoke a second lambda function as an event (InvocationType = Event).

in function 2, it will do an http request to an endpoint.

also, am I going to code in serverless.yml? or code only on index/app/handler.js?

I tried the link here on stackoverflow -> Nodejs - Invoke an AWS.Lambda function from within another lambda function but it's not working.

var AWS = require('aws-sdk');
AWS.config.region = 'eu-west-1';
var lambda = new AWS.Lambda();

//LAMBDA A
exports.handler = function(event, context) {
  var params = {
    FunctionName: 'Lambda_B', // the lambda function we are going to invoke
    InvocationType: 'RequestResponse',
    LogType: 'Tail',
    Payload: '{ "name" : "Yza" }'
  };

  lambda.invoke(params, function(err, data) {
    if (err) {
      context.fail(err);
    } else {
      context.succeed('Lambda_B said '+ data.Payload);
    }
  })
};

 //LAMBDA B
 exports.handler = function(event, context) {
   console.log('Lambda B Received event:', JSON.stringify(event, null, 2));
   context.succeed('Hello ' + event.name);
 };

2 Answers 2

6

Your problem is that the lambda.invoke() function is non-blocking, so Lambda_A is finishing its execution before it gets to call Lambda_B. You can use promises to deal with that. If you're using Node.js 8.10+, you can do this:

Lambda_A:

let AWS = require('aws-sdk');
let lambda = new AWS.Lambda();

exports.handler = async (event) => {

    let params = {
      FunctionName: 'Lambda_B',
      InvocationType: 'RequestResponse',
      Payload: '{ "foo" : "bar" }'
    };

    return await lambda.invoke(params, function(err, data) {
      if (err) {
        throw err;
      } else {
        console.log('LambdaB invoked: ' +  data.Payload);
      }
    }).promise();
};

Lambda_B:

exports.handler = async (event) => {
    return {
        statusCode: 200,
        body: JSON.stringify('Hello from Lambda_B!'),
    };
};

Response when Lambda_A invoked:

{
  "StatusCode": 200,
  "ExecutedVersion": "$LATEST",
  "Payload": "{\"statusCode\":200,\"body\":\"\\\"Hello from Lambda_B!\\\"\"}"
}

Console output from Lambda_A when invoked:

START RequestId: 016a763d-c79e-4d72-bd44-0aaa89a5efaf Version: $LATEST
2019-02-07T08:07:11.154Z    016a763d-c79e-4d72-bd44-0aaa89a5efaf    LambdaB invoked: {"statusCode":200,"body":"\"Hello from Lambda_B!\""}
END RequestId: 016a763d-c79e-4d72-bd44-0aaa89a5efaf
REPORT RequestId: 016a763d-c79e-4d72-bd44-0aaa89a5efaf  Duration: 717.40 ms Billed Duration: 800 ms     Memory Size: 128 MB Max Memory Used: 30 MB  
Sign up to request clarification or add additional context in comments.

2 Comments

I'm not very familiar with the serverless project, but I assume the code should just go in handler.js
I tried your code but it gives me an error Serverless Error --------------------------------------- Stack:arn:aws:cloudformation:us-east-1:376014394890:stack/lambda-test-dev/be4e1a40-29c0-11e9-8b17-0a9ef6cbb06a is in UPDATE_IN_PROGRESS state and can not be updated.
1

You can add an user which has policy includes LambdaInvoke then add below configuration

enter code var credentials = {
accessKeyId : process.env.ACCESS_KEY,
secretAccessKey : process.env.SECRET_KEY};   
AWS.config.update(
{
"credentials":credentials,
"region":"eu-central-1"
});

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.