AWS Lambda RDS connection timeout

Sir Codesalot picture Sir Codesalot · Mar 5, 2017 · Viewed 25.8k times · Source

I'm trying to write a Lambda function using Node.js which connects to my RDS database. The database is working and accessible from my Elastic Beanstalk environment. When I run the function, it returns a timeout error.

Tried to increase the timeout up to 5 minutes with the exact same result.

The conclusion I came to after some research is that it's probably a security issue but couldn't find the solution in Amazon's documentation or in this answer (which is the only one I could find on the topic).

Here are the security details:

  • Both the RDS and the Lambda are in the same security group.
  • The RDS has All traffic inbound and outbound rules.
  • The Lambda has AmazonVPCFullAccess policy in it's role.

My code is:

'use strict';
console.log("Loading getContacts function");

var AWS = require('aws-sdk');
var mysql = require('mysql');

exports.handler = (event, context, callback) => {

   var connection = mysql.createConnection({
        host     : '...',
        user     : '...',
        password : '...',
        port     : 3306,
        database: 'ebdb',
        debug    :  false
    });

    connection.connect(function(err) {
      if (err) callback(null, 'error ' +err);
      else callback(null, 'Success');
    });

};

The result I'm getting is:

"errorMessage": "2017-03-05T05:57:46.851Z 9ae64c49-0168-11e7-b49a-a1e77ae6f56c Task timed out after 10.00 seconds"

Answer

ambaum2 picture ambaum2 · Jul 17, 2017

While using context will work, you just need to add context.callbackWaitsForEmptyEventLoop = false; to the handler and then use callback as normal like this:

exports.handler = (event, context) => {
  context.callbackWaitsForEmptyEventLoop = false; 
  var connection = mysql.createConnection({
    //connection info
  });
  connection.connect(function(err) {
    if (err) callback(err); 
    else callback(null, 'Success');
  });
};

The answer is here in the docs (took me a few hours to find this): http://docs.aws.amazon.com/lambda/latest/dg/nodejs-prog-model-using-old-runtime.html

In the section "Comparing the Context and Callback Methods" it has an "Important" note that explains things.

At the bottom of the note it reads:

Therefore, if you want the same behavior as the context methods, you must set the context object property, callbackWaitsForEmptyEventLoop, to false.

Basically, callback continues to the end of the event loop as opposed to context which ends the event loop. So setting callbackWaitsForEmptyEventLoop makes callback work like context.