Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Invoking the lambda gets timed out after adding VPC configurations

I am using Serverless framework for creating lambdas. I created a simple Lambda function, which queries from an Mongo instance and returns the response. Initially, I created the Mongo instance with publicIp and made the Lambda access that instance with publicIP. It worked well.

Now, in order to increase the security, I added the VPC configuration to the Lambda. Here is my serverless.yml:

functions:
  graphql:
    handler: handler.graphql
    iamRoleStatements:
      - Effect: Allow
        Resource: "*"
        Action:
          - ec2:CreateNetworkInterface
          - ec2:DescribeNetworkInterfaces
          - ec2:DetachNetworkInterface
          - ec2:DeleteNetworkInterface
          - logs:CreateLogGroup
          - logs:CreateLogStream
          - logs:PutLogEvents
    vpc:
      securityGroupIds:
        - sg-16f9e371
      subnetIds:
        - subnet-883a12fe
        - subnet-3f7b1067
    events:
      - http:
          path: graphql
          method: post
          integration: lambda
          memorySize: 256
          timeout: 10
          cors: true
          response:
            headers:
              Access-Control-Allow-Origin: "'*'"

Adding the above configuration, the serverless deployment was successful. Now when I tried to access the function by invoking the APIGateway URL in postman, I get an timeout error. Here is the screenshot of Postman:

Timeout error

Does adding the VPC configuration to Lambda make it inaccessible by invoking it publicly?

like image 281
Lakshman Diwaakar Avatar asked May 14 '17 09:05

Lakshman Diwaakar


People also ask

How do you fix Lambda timeout?

To troubleshoot the retry and timeout issues, first review the logs of the API call to find the problem. Then, change the retry count and timeout settings of the AWS SDK as needed for each use case. To allow enough time for a response to the API call, add time to the Lambda function timeout setting.

Can you invoke a Lambda in a VPC?

So a public (non-VPC, has Internet access) Lambda function can call the Invoke API to trigger the private Lambda function, but the private VPC (no Internet access) Lambda function cannot access the Invoke API to trigger any Lambda function.

What is the most likely issue with the lambda function's timeout?

There are many reasons why a function might time out, but the most likely is that it was waiting on an IO operation to complete. Maybe it was waiting on another service (such as DynamoDB or Stripe) to respond. Within a Lambda invocation, the function might perform multiple IO operations.


2 Answers

When you create lambda functions inside a VPC, the elastic network interfaces of the lambda functions are assigned only a private IP address. But to connect to a resource in the internet you need a public IP address. If your mongo instance is accessed over the internet, your lambda function wouldn't be able connect to it.

You need to setup a NAT gateway to get internet access to the lambda function. Go to the below link and check under the topic "Internet Access for Lambda Functions" to see steps.

http://docs.aws.amazon.com/lambda/latest/dg/vpc.html

like image 148
Asanka Avatar answered Nov 15 '22 05:11

Asanka


You do right by attaching the Lambda to the VPC for database traffic to be transmitted over a private network. It's an unnecessary security compromise otherwise, and slower over the Internet.

The previous answer is correct, you now have an ENI attached to your Lambda Function, which means it has a private IP connection on your VPC Subnet. I'm guessing that your MongoDB instance is in your VPC too, if it was elsewhere on the internet you should have kept it as publicly connected.

Some relevant info:

  • To communicate with the MongoDB instance you now need to connect to the private IP address of the MongoDB EC2.
  • Make sure that the Security Groups are configured to talk out of the Lambda and into the EC2.
  • If necessary, make sure that the networks are routable.
  • API Gateway can still call VPC attached Lambda Functions and receive a response.

Design Consideration

A combination of patterns that I use for similar scenarios:

  1. When you are designing a serverless solution with API Gateway and Lambda, you should follow the Single Responsibility Principal, i.e. each function does one thing and does it well.
  2. So you have one function ("The Controller") that receives the request from the consumer and has the job of coordinating the process (you could also use Step Functions for this). The Controller is not VPC attached and coordinates a number of child functions.
  3. Cross-over Pattern (I made this one up) to get information from a VPC attached resource (or via DirectConnect), you have a Lambda function that is VPC connected. This function has one job, to communicate with the VCP resource (read, write, api call, etc.). The Controller calls this Lambda function with the request details against the VPC resource, and receives the response for further processing of the information. This way you can keep the majority of your serverless app in the Amazon Ecosystem, so it can talk natively with serverless resources (S3, DynamoDB, Kinesis, SQS, etc.), while being able to send out requests to the serverfull world, a bit like a DMZ.

Hope this helps.

like image 40
Matt D Avatar answered Nov 15 '22 03:11

Matt D