AWS Lambda can't connect to RDS instance, but I can locally?

20,177

Solution 1

@MarkB @Michael-sqlbot were correct in the comments, it was a security group issue.

I finally got AWS support response to point out that the RDS security group was indeed private to a specific IP. This doesn't make sense as I never configured that, and I could access the database from my local machine and elastic beanstalk. I added 0.0.0.0/0 to the security group and now the lambda can connect. Thanks for your help guys!

Solution 2

Here is how I fixed this issue.

When you create a DB instance, you are asked to select VPC. Even if you select default values, it takes the public IP of your system as default inbound IP. Lambda function, on the other hand, has its own IP setting. That's why you can access through any IDE or locally however not through lambda function.

To add Ip restrictions:

  1. Go to Security group of your instance. After selecting the default security group, click on it. In the new page, scroll down to find inbound and outbound settings.

  2. In inbound setting, click edit. You can change the IP here. (0.0.0.0/0 makes it open to the world)

  3. If you add public IP here then IDE or your local connection would work.

  4. For lambda function to work, add IP of the lambda function. Go to Lambda function, Network --> VPC --> (if no VPC is selected, select a VPC same as DB function) and note the IP here.

  5. Type this IP in inbound settings, this will show auto filler.

Save it and test your lambda function.

Solution 3

Here's the answer to this with no world wide access.

Allow AWS Lambda to access RDS Database

Repeating Mark's answer:

  1. Add vpc access to the lambda function
  2. Create a new security group for the lambda
  3. Add the RDS security group to the lambda's SG.
Share:
20,177

Related videos on Youtube

LordZardeck
Author by

LordZardeck

Updated on July 17, 2022

Comments

  • LordZardeck
    LordZardeck almost 2 years

    I am trying to connect to my RDS instance from a lambda. I wrote the lambda locally and tested locally, and everything worked peachy. I deploy to lambda, and suddenly it doesn't work. Below is the code I'm running, and if it helps, I'm invoking the lambda via a kinesis stream.

    'use strict';
    
    exports.handler = (event, context, handlerCallback) => {
        console.log('Recieved request for kinesis events!');
        console.log(event);
        console.log(context);
    
        const connectionDetails = {
            host:     RDS_HOST,
            port:     5432,
            database: RDS_DATABASE,
            user:     RDS_USER,
            password: RDS_PASSWORD
        };
    
        const db = require('pg-promise')({promiseLib: require('bluebird')})(connectionDetails);
    
        db
                .tx(function () {
                    console.log('Beginning query');
    
                    return this.query("SELECT 'foobar'")
                               .then(console.log)
                               .catch(console.log)
                               .finally(console.log);
                })
                .finally(() => handlerCallback());
    };
    

    Here is the logs from cloud watch if it helps:

    START RequestId: *********-****-****-****-********* Version: $LATEST 
    2016-05-31T20:58:25.086Z    *********-****-****-****-*********  Recieved request for kinesis events! 
    2016-05-31T20:58:25.087Z    *********-****-****-****-*********  { Records:  [ { kinesis: [Object], eventSource: 'aws:kinesis', eventVersion: '1.0', eventID: 'shardId-000000000000:**********************************', eventName: 'aws:kinesis:record', invokeIdentityArn: 'arn:aws:iam::******************:role/lambda_kinesis_role', awsRegion: 'us-east-1', eventSourceARN: 'arn:aws:kinesis:us-east-1:****************:stream/route-registry' } ] } 
    2016-05-31T20:58:25.283Z    *********-****-****-****-*********  { callbackWaitsForEmptyEventLoop: [Getter/Setter], done: [Function], succeed: [Function], fail: [Function], logGroupName: '/aws/lambda/apiGatewayRouteRegistry-development', logStreamName: '2016/05/31/[$LATEST]******************', functionName: 'apiGatewayRouteRegistry-development', memoryLimitInMB: '128', functionVersion: '$LATEST', getRemainingTimeInMillis: [Function], invokeid: '*********-****-****-****-*********', awsRequestId: '*********-****-****-****-*********', invokedFunctionArn: 'arn:aws:lambda:us-east-1:*************:function:apiGatewayRouteRegistry-development' } 
    END RequestId: *********-****-****-****-********* 
    REPORT RequestId: *********-****-****-****-*********    Duration: 20003.70 ms   Billed Duration: 20000 ms Memory Size: 128 MB   Max Memory Used: 22 MB   
    2016-05-31T20:58:45.088Z *********-****-****-****-********* Task timed out after 20.00 seconds
    
    • Mark B
      Mark B almost 8 years
      Did you enable VPC access for your Lambda function?
    • LordZardeck
      LordZardeck almost 8 years
      @MarkB nope. I have the dropdown set to "No VPC"
    • Mark B
      Mark B almost 8 years
      So you have Publicly Accessible enabled on your RDS instance, and you have the RDS instance's security group open to the world?
    • LordZardeck
      LordZardeck almost 8 years
      @MarkB Yes, and I can access RDS form my laptop directly. The whole lambda works perfectly fine on my local machine.
    • jarmod
      jarmod almost 8 years
      20 seconds would seem like enough time, but does it work if you bump up the Lambda timeout temporarily to 60s?
    • LordZardeck
      LordZardeck almost 8 years
      @jarmod Yes, I had it at 60 seconds at one point. No change
    • Michael - sqlbot
      Michael - sqlbot almost 8 years
      You really should connect this to the VPC that (hopefully) your RDS instance is in. Otherwise your RDS instance has to allow access from 0.0.0.0/0 -- which it really sounds like is not currently the case, but if it is, it's a terrible idea from a security perspective.
    • LordZardeck
      LordZardeck almost 8 years
      @Michael-sqlbot you are correct, having it in the same VPC would be ideal, but we are just trying to bootstrap this for internal development, we aren't releasing anything yet. We will lock down security before it goes live. And the RDS instance is public available right now.
    • LordZardeck
      LordZardeck almost 8 years
      @MarkB @Michael-sqlbot, I finally got AWS support response to point out that the RDS security group was indeed private to a specific IP. This doesn't make sense as I never configured that, and I could access the database from my local machine and elastic beanstalk. I added 0.0.0.0/0 to the security group and now the lambda can connect. Thanks for your help guys!
  • UncleAdam
    UncleAdam almost 7 years
    Hello, Can you elaborate? Where and to what did you add the 0.0.0.0/0?
  • Nativ
    Nativ almost 7 years
    But adding 0.0.0.0/0 to your inbound in the security group meaning opening the connection to the world. Don't you afraid of that?
  • LordZardeck
    LordZardeck over 6 years
    @Nativ it was for development and testing purposes. Later it got locked down to the correct security group. Yes, opening the connection to the world would not be a great idea for production use.
  • Trevor
    Trevor over 6 years
    So, did you eventually add your lambda to the VPC?
  • Juan M. Molina
    Juan M. Molina over 5 years
    @LordZardeck AWS automatically configures your public IP as Inbound in the security group at the moment of the RDS instance creation. That's why the code was working from your machine, but nowhere else. Same happened to me! :)
  • nxmohamad
    nxmohamad about 5 years
    would this apply if I set Publicly Accessible to true?
  • Hashir Baig
    Hashir Baig almost 5 years
    You are a life saver. Thanks a lot!
  • stdunbar
    stdunbar over 4 years
    What is this adding to the answers?
  • MarcoSantana
    MarcoSantana over 4 years
    I like this answer better because the first one opens your RDS instance to the world and the second one doesn't work, or at least it didn't for me. This one is elegant and well referenced.
  • thanos.a
    thanos.a over 2 years
    How about the subnets ? Does it matter what it being selected there ?
  • thanos.a
    thanos.a over 2 years
    How about the subnets ? Does it matter what it being selected there ?