2

I am trying to a connect a AWS Lambda function to a database in RDS, I followed a few posts that have suggested they both need to be inside the same VPC, but have been told by Amazon support that this is not the case. Although I have tried a multi subnet VPC with nat gateway and security groups allowing access to each, with no prevail.

I am able to talk to the Database instances in SQL management studio or MySQL workbench without a problem.

10:13:00 2017-05-16T10:13:00.509Z Callback connection.connect() 10:13:00 2017-05-16T10:13:00.547Z Error ETIMEDOUT

I have tried a few different methods of connection now, I used an example as seen in the post, the only difference is this databases wasn't in RDS.

Querying a MySQL database from a NodeJS AWS Lambda Function

I have tried a MSSQL and MSSQL databases instances, both experiences a timeout on connection. I have attached all relevant policy's to the lambda function.

I have included below one of my simple tests, just to try and get a connection.

Test Code added below, not this at the bottom of a alexa call.

function mysqltest2() {
    var mysql      = require('mysql');
    var connection = mysql.createConnection({
      host     : 'endpoint.rds.amazonaws.com',
      user     : 'user',
      password : 'pass',
      database : 'db'
      });
                  var test;
                  console.log(`Intent Request`);
                  console.log('Then run MySQL code:');
                  connection.connect(function(err) {
                      console.log('Inside connection.connect() callback');
                      if (!err) {
                          console.log("Database is connected ... ");
                          connection.query("SELECT 1 + 1 AS solution",
                              function(err, result) {
                                  console.log("Inside connection.query() callback")
                                  if (!err) {
                                      console.log(result);
                                      console.log("Query Successful! Ending Connection.");
                                      test = result;
                                      connection.end();
                            } else {
                                      console.log("Query error!");
                                  }
                              });
                      } else {
                          console.log("Error connecting database ..." +             err.message);
                      }
                  });
                  return test;
  }
RickWeb
  • 1,765
  • 2
  • 25
  • 40
  • They do not *have* to both be in the same VPC, but that is the most straightforward, most secure, and most cost-effective configuration. In any event, this isn't difficult to do, so there must be something you are overlooking or an incorrect assumption that you are making. So, tell us how you *want* to do it and we can troubleshoot from there. You might also explain how it is that you have talked to AWS support yet you don't have a working solution. – Michael - sqlbot May 16 '17 at 19:44
  • provide lambda function so we can help you. – Binary101010 May 16 '17 at 23:18
  • Does the route table for your lambda's vpc subnet have a route to send 0.0.0.0/0 traffic to the nat gateway? Are you able to access the internet from your lambda? You could try accessing a simple web page to confirm this. – user818510 May 17 '17 at 02:26
  • @Michael-sqlbot I sure it is pretty simple but there is something I am missing or not understanding. AWS support is from another account regarding a different issue. Ideally i need a MSSQL databases in RDS that that I can query from a node.js Lambda function which also has access to the internet. – RickWeb May 17 '17 at 09:10
  • @Binary101010 added to the main question. – RickWeb May 17 '17 at 09:11
  • @user818510 this maybe where I was struggling I had 3 subnets within my VPC all 3 where added to both Lambda and RDS, I had route for the RDS to get to an IGW so it could be accessed and I also had a route for the Lambda to get to the Nat gateway, ideally if i could do this without a nat gateway it would keep costs down. – RickWeb May 17 '17 at 09:18
  • @RickWeb You can use a NAT instance on EC2 instead of a gateway to keep the costs down. The downside is that you'll have to manage the EC2 instance yourself. – user818510 May 17 '17 at 10:24
  • Simple config: Public subnet A has RDS on it (if you need to access RDS via Internet) and has NAT device **on it** (gateway now, instance later maybe) and default route to IGW. Private subnet B has Lambda on it and default route to NAT device. Don't mess with outbound security group rules or Network ACL, leave defaults. Add inbound rules to security groups. If no joy, temporarily allow from 0.0.0.0 in security groups to prove that you don't have an SG misconfig. Also read about public/private subnets [here](http://stackoverflow.com/a/22212017/1695906). – Michael - sqlbot May 17 '17 at 11:03
  • @Michael-sqlbot Thank you for all your help and help on other posts on here, your responses solved the problems. – RickWeb Jun 01 '17 at 15:27

1 Answers1

2

There were two problems.

1 VPC Setup

VPC setup, reading @ Michael - sqlbot post about VPCs helped a lot.

When using lambda within a VPC the following needs to be taken into consideration.

  • The Lambda execution role needs to be able to create, describe and delete network interfaces.
  • The Lambda function and the RDS instances need to be in the same VPC.
  • The Lambda function and the RDS instances need to be in the same subnets.
  • The Lambda function and the RDS instances need to share a security group.
  • That security group needs to have a rule allowing traffic from other entities in the same security group.
  • The subnet needs to have spare address space to allow lambda to create Elastic Network Interfaces.

    Source Amazon Web Services Support

2. Node.js Callbacks

The second was basically callback hell in node.js

As the function was being called from Alexa intent it was executing the the content.success before the callback had fired. This was then causing a timeout the next time the code executed due to it still being busy executing the previous command. I solved this by making all the callbacks nested and generating the SpeechletResponse in the callback.

RickWeb
  • 1,765
  • 2
  • 25
  • 40