AWS lambda invoke not calling another lambda function - Node.js
Asked Answered
K

3

57

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

Knot answered 25/8, 2016 at 11:57 Comment(9)
Is your Lambda function running inside a VPC?Piton
Yes, and both are sharing same VPC , lambda execution role and security group . . Thanks for replyKnot
You won't be able to access the AWS API, or anything else that exists outside your VPC, from a Lambda function that exists in your VPC unless you add a NAT Gateway to the VPC.Piton
Thanks for the reply. I will check and get back to you.Knot
@MarkB , 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 :D.Knot
None of those details matter in this instance. You are trying to call the AWS API, which happens to be a resource that exists outside your VPC.Piton
Mark is correct. See docs.aws.amazon.com/lambda/latest/dg/… .Armagh
Any concrete solution or any reference where we can check & just call one lambda to another lambda? This is occurring under the same environment.Knot
I am facing the very same issue, Lambda A and B, able to invoke Lambda B from Local using IAM creds, but unable to from Lambda A, which has Lambda IAM role. Both Lambdas under No VPC, as they don't need VPC resources.Malia
C
86

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.

Chicky answered 29/8, 2016 at 12:42 Comment(11)
Thanks for the detailed reply @Chicky .I am able to run with Simple solution. Will surely try the other one and accept the answer.Knot
Sure I am accepting the the answer , but i did nt get chance to work with other option which seems more reliable .Knot
I have similar issue. and configured private Subnet with NAT Gateway, following your instructions, even so, still have no access to Internet. Any help?Chromatic
I would suggest you open a new thread with all the details, configurations you've made, errors that you get and so (make sure you correlate everything to the steps in this guide) and I'll be able to answer with a more appropriate content. this can't be handled in these comments. put a link here once it's posted. i promise to helpChicky
So the resources in public subnet cannot call internet?Chante
They can, going through the internet gateway.Chicky
Thank you, maybe you could mention that Lambda should be located inside private subnets.Scrutable
I had to follow this and @BEm's comment forums.aws.amazon.com/message.jspa?messageID=724554Religious
Note that NAT Gateway has a corresponding cost.Chloromycetin
Here is some helpful documentation: aws.amazon.com/premiumsupport/knowledge-center/…Sarabia
Thanks @Ricky, that was the missing step for me as well. Posted an edit to the answer listing out those steps. For posterity: you need to force the Subnet Association for the Route Table (done by clicking on Route Table thru dashboard -> Subnet Associations -> Edit -> choose the corresponding subnet).Courtney
L
12

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.

Lonnie answered 29/12, 2017 at 18:29 Comment(6)
Can't believe this worked, but this is faster and easier way. I still wonder why a Lambda outside VPC can invoke a Lambda inside a VPC while the vice-verse cannot.Baez
I used the same approach...but since a couple of days it seems lambdas outside the VPC are not able to invoke lambdas inside....am I missing something? Each lambda has policy to invoke the destination lambda....Vennieveno
I follow the steps but it didn't work out. I want to use Gmail SMTP details in Lambda function, as well as connect to RDS instance that is inside a VPC. If I remove the VPC then it cannot connect to RDS until I make that available public, and mail worked. But if put Lambda in the same VPC then RDS connection worked but Mail function giving "Connection Timeout". I have created NAT Gateway with Elastic IP and associate with same subnet of Lambda but still the same issue.Radiolarian
It all seems crazy but this works. A lambda outside a VPC can invoke a lambda within the VPC but not the other way around. Setting up a NAT GW would be a simple solution that would allow many things but it costs quite a bit (for me anyway) when running personal experiments/learning all this.Buckjumper
This approach is correct when the invoker lambda can remain outside a VPC. It works because the invoker lambda has access to AWS API which is a public endpoint. Via the API you can instantiate any resource and doesn't matter where it is.Radial
How's the latency? I imagine if I used Node and code is relatively small, cold start first func ~150ms + VPC func ~700ms, warn execution (excluding execution time and network latency) ~10ms + ~20ms.Cleopatra
U
2

As of Oct 2020, AWS PrivateLink is an easier solution than configuring an internet-gateway/NAT-gateway. See release notes here, and links to PrivateLink documentation therein: https://aws.amazon.com/blogs/aws/new-use-aws-privatelink-to-access-aws-lambda-over-private-aws-network/

Note that, if both lambdas are in different VPCs, and the executing lambda needs to handle a response from the target lambda, then both lambdas will need an endpoint.

Unlade answered 24/11, 2021 at 20:0 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.