Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AWS lambda invoke not calling another lambda function - Node.js

After giving all the rights to invoke function. My Lambda function is not able to invoke another function . Every time I am getting timeout having 30 seconds timeout issue. It looks like lambda is not able to get another lambda function

My lambdas are in same region, same policy, same security group .. Also VPC are same in both lambdas. The only thing is different now is lambda functions

Here are the role rights

1) created AWSLambdaExecute and AWSLambdaBasicExecutionRole

2) Created one lambda function which is to be called Lambda_TEST

exports.handler = function(event, context) {   console.log('Lambda TEST Received event:', JSON.stringify(event, null, 2));   context.succeed(event); }; 

3) Here is a another function from where it is called .

var AWS = require('aws-sdk'); AWS.config.region = 'us-east-1'; var lambda = new AWS.Lambda();  exports.handler = function(event, context) {  var params = {    FunctionName: 'Lambda_TEST', // the lambda function we are going to invoke    InvocationType: 'RequestResponse',    LogType: 'Tail',    Payload: '{ "name" : "Arpit" }'  };    lambda.invoke(params, function(err, data) {    if (err) {     context.fail(err);    } else {    context.succeed('Lambda_TEST said '+ data.Payload);   }  }) }; 

Reference taken from : This link

like image 614
Arpit Vaishnav Avatar asked Aug 25 '16 11:08

Arpit Vaishnav


People also ask

Can lambdas invoke other lambdas?

Async lambda invocation is the simplest and straightforward way to go about this problem. Async invocation means that the lambda that invokes the other lambda does not wait for the second lambda to finish and immediately returns.

Can a Lambda call another function?

Functions enable encapsulation and code re-use. Most programming languages support the concept of code synchronously calling functions within a code base.


2 Answers

Note

I will denote by executor the lambda that executes the second lambda.


Why Timeout?

Since the executor is "locked" behind a VPC - all internet communications are blocked.

That results in any http(s) calls to be timed out as they request packet never gets to the destination.

That is why all actions done by aws-sdk result in a timeout.


Simple Solution

If the executor does not have to be in a VPC - just put it out of it, a lambda can work as well without a VPC.

Locating the lambda in a VPC is required when the lambda calls resources inside the VPC.

Real Solution

From the above said, it follows that any resource located inside a VPC cannot access the internet - that is not correct - just few configurations need to be made.

  1. Create a VPC.
  2. Create 2 Subnets, let one be denoted as private and the second public (these terms are explained ahead, keep reading).
  3. Create an Internet Gateway - this is a virtual router that connects a VPC to the internet.
  4. Create a NAT Gateway - pick the public subnet and create a new elastic IP for it (this IP is local to your VPC) - this component will pipe communications to the internet-gateway.
  5. Create 2 Routing Tables - one named public and the second private.

    1. In the public routing table, go to Routes and add a new route:

    Destination: 0.0.0.0/0

    Target: the ID of the internet-gateway

    1. In the private routing table, go to Routes and add a new route:

    Destination: 0.0.0.0/0

    Target: the ID of the nat-gateway

    • A private subnet is a subnet that in its routing table - there is no route to an internet-gateway.

    • A public subnet is a subnet that in its routing table - there exists a route to an internet-gateway


What we had here?

We created something like this:

VPC with NAT and IGW

This, what allows resources in private subnets to call out the internet. You can find more documentation here.

like image 89
johni Avatar answered Sep 23 '22 02:09

johni


I've experienced this same problem where Lambdas that are "pinned" to a VPC are not able to invoke other Lambdas. I've been dealing with this issue, without using NAT, by refactoring the structure of my solution.

Let's say I have several lambdas, A, B, C, D,... and I would like these Lambdas to each have query access to an RDS database. In order to have this DB access, I need to put the lambdas in same VPC as database. But I'd also like various lambdas among A, B, C, D,... to invoke one another. So I run into the problem that Arpit describes.

I've been dealing with this issue by splitting each Lambda into two Lambdas: one that focuses on the process flow (i.e. invoking other lambdas and being invoked by another lambda); and the other focusing on doing "real" work, like querying the database. So I now have functions A_flow, B_flow, C_flow, D_flow, ...; and functions A_worker, B_worker, C_worker, D_worker, ... The various flow lambdas are not "pinned" to a specific VPC, and can thus invoke other lambdas. The various worker Lambdas are in the same VPC as database, and can query the DB.

Each flow lambda "delegates" the work of interacting with DB to the corresponding worker lambda. It does this delegation by performing a synchronous invocation of the worker lambda. The worker lambdas do not invoke any other lambdas. (In terms of process flow graph, the worker lambdas are terminal nodes.) In my own system, the invocations of flow Lambdas by other flow lambdas have generally been asynchronous; but I suppose they could be synchronous if desired.

Even though I devised this approach as a workaround, it has a nice feature of cleanly separating the high-level function design into (a) process flow and (b) performing more detailed work, including interaction with DB resources.

like image 24
Jim Robertson Avatar answered Sep 20 '22 02:09

Jim Robertson