Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Error: connect ETIMEDOUT rds lambda

I am trying to connect to RDS using Lambda function, but I am getting an error:

var mysql = require('mysql');
exports.handler = function(event, context) {   
           //Connect to RDS

var connection = mysql.createConnection({
host     : 'hostname',
user     : 'username',
password : 'password',
database : 'database'

});

connection.connect( function(err)
{
   if (err)
   { 
     throw err;
   }
else 
  {
    console.log('DB connection establish');
  }
  });

 };

The error I am getting is:

START RequestId: 9711e650-e582-11e5-af5f-97ba391a42ae Version: $LATEST

2016-03-08T23:08:06.737Z    9711e650-e582-11e5-af5f-97ba391a42ae    
Error: connect ETIMEDOUT  
  at Connection._handleConnectTimeout (/var/task/node_modules/mysql/lib/Connection.js:412:13)       
      at Socket.g (events.js:180:16)   
    at Socket.emit (events.js:92:17)   
    at Socket._onTimeout (net.js:327:8)     
    at _makeTimerTimeout (timers.js:429:11)   
    at Timer.unrefTimeout [as ontimeout] (timers.js:493:5)    
    --------------------
    at Protocol._enqueue (/var/task/node_modules/mysql/lib/protocol   /Protocol.js:141:48)    
    at Protocol.handshake (/var/task/node_modules/mysql/lib/protocol    /Protocol.js:52:41)      
    at Connection.connect (/var/task/node_modules/mysql     /lib/Connection.js:123:18)     
    at exports.handler (/var/task/exports.js:21:12)     
END RequestId: 9711e650-e582-11e5-af5f-97ba391a42ae        
REPORT RequestId: 9711e650-e582-11e5-af5f-97ba391a42ae  
Duration: 10988.17ms    
Process exited before completing request
like image 618
user1042327 Avatar asked Mar 08 '16 23:03

user1042327


People also ask

Can't connect to mysql server on AWS Lambda?

When you are connecting Lambda to My SQL DB make sure to follow the below steps: The Execution Role which is assigned to Lambda must have Permission to EC2 Full access. Go to VPC Tab in Lambda and make sure you have VPC there. Edit and add Required VPC Connection with proper Subnets and Security Groups.

What is connect Etimedout?

ETIMEDOUT (Operation timed out): A connect or send request failed because the connected party did not properly respond after a period of time. Usually encountered by HTTP or net. Often a sign that a socket.

What is callbackWaitsForEmptyEventLoop?

callbackWaitsForEmptyEventLoop – Set to false to send the response right away when the callback runs, instead of waiting for the Node. js event loop to be empty. If this is false, any outstanding events continue to run during the next invocation.


2 Answers

I had the same problem as this and just got it fixed. Seeing as this is the top search result for this problem on stackoverflow, I am going to post my solution here.

This answer is for an RDS instance inside a VPC

  1. place the Lambda function in the same VPC as your RDS instance
  2. your lambda execution role you will need to have VPC execution policy AWSLambdaVPCAccessExecutionRole

  3. assign a security group to the lambda function

  4. In the security attached to the RDS instance, add an inbound rule for mysql/aurora (port 3306) and rather than adding it for an IP address add it for your lambda functions security group.

In summary this places the lambda in the same VPC as RDS and gives the lambda function inbound access to MYSQL regardless of the IP of the lambda function.

like image 70
ajmcgarry Avatar answered Sep 21 '22 09:09

ajmcgarry


I had the same issue and found your entry while googling but now I solved it. Sadly I am not certainly sure, which action actually solved it but check:

  • If you don't make use of VPCs see if it works with a publicly accessible RDS, at least for testing purposes
  • Grant your Role (for example lambda_basic_execution) AmazonRDSFullAccess within the Identity and Access Management area
  • Within the RDS Overview of your DB instance, you can click on the chosen security group(s) to edit them: in the following window you can specify inbound and outbound traffic rules. In my working example, I allowed all traffic from all ports and all IPs (0.0.0.0/0) for both ways. Of course this is not a secure solution but regarding your example I guess that you are - like me - just getting into AWS and trying to build working examples first. You can always edit those rules later to gradually limit the traffic. I did this to test my access to the RDS via my own computer at first

I made it work without setting VPC options or API endpoints in the lambda function and established a connection via

exports.handler = function(event, context) {
var mysql      = require('mysql');
var connection = mysql.createConnection({
host     : 'hostwithoutport',
user     : 'user',
password : 'password',
database : 'database'
});

connection.query('SELECT * FROM Xy WHERE ID = "1"', function(err, rows) {
if (err) {
console.error('error connecting: ' + err.stack);
context.fail();
return;
}

console.log('connected as id ' + connection.threadId);
context.succeed(rows);
});
};

You can also do it differently but keep in mind to always succeed and fail (or done) a lambda function, preferably within an if clause after the statement. Otherwise you might get problems due to the lambda function succeeding before the query can determine the results and you do not get a proper result. If you dont end the lambda function in some way, the function itself will time out, which will however look differently.

Also remember to always end connections, this is implied by directly using a query - this method connects and ends by itself. According to what I read in a different thread, this problem could theoretically also occur due to a still open connection you once invoked.

like image 40
kopaka Avatar answered Sep 20 '22 09:09

kopaka