Error connecting AWS RDS MYSQL from AWS Lambda Node.js - mysql

I am trying to connect AWS RDS Mysql from Lamda function written in Node.js. Initially I was getting "timed out" error, then I made below configuration.
-The Lambda execution role has full access to VPC.
-The Lambda function and the RDS instances are now in the same VPC.
-The Lambda function and the RDS instances are in same subnets.
-The Lambda function and the RDS instances shares a security group.
-All inbound traffic permitted.
Now I says that the DB I am trying to connect is unknown.Giving below error:
Response:
{
"errorType": "Error",
"errorMessage": "ER_BAD_DB_ERROR: Unknown database 'empdb'",
"trace": [
"Error: ER_BAD_DB_ERROR: Unknown database 'empdb'",
I am copying the code snippet as well.
var mysql = require('mysql');
var connection = mysql.createConnection({
host : process.env.RDS_HOSTNAME,
user : process.env.RDS_USERNAME,
password : process.env.RDS_PASSWORD,
port : process.env.RDS_PORT,
database : process.env.RDS_DATABASE
});
connection.connect();
exports.handler = (event, context, callback) => {
// allows for using callbacks as finish/error-handlers
context.callbackWaitsForEmptyEventLoop = false;
const sql = "insert into MESSAGE values('Testing1');";
connection.query(sql, (err, res) => {
if (err) {
throw err
}
callback(null, '1 records inserted.');
})
};
I tried both Create and Insert statements. I am new to AWS. Please advise.

Related

aws rds proxy throws timeout error from nodejs12.x

I'm getting a connection timeout when I try to connect to mysql rds proxy. I'm followed this tutorial
This is my code
import mysql2 from 'mysql2';
import AWS from 'aws-sdk';
const getConnection = async () => {
const signer = new AWS.RDS.Signer({
username: 'my-user-name',
hostname: 'proxy-name.proxy-someid.us-east-1.rds.amazonaws.com',
port: 3306
});
console.info('Connecting to MySQL proxy via IAM authentication');
const rdsSignerAuth = () => () => {
console.info('CALL rdsSignerAuth');
return signer.getAuthToken({
username: 'my-user-name',
region: 'us-east-1',
hostname: 'proxy-name.proxy-someid.us-east-1.rds.amazonaws.com',
port: 3306
});
};
let connection;
try {
connection = await mysql2.createConnection({
host: 'proxy-name.proxy-someid.us-east-1.rds.amazonaws.com',
user: 'my-user-name',
database: 'database-name',
connectTimeout: 60000,
ssl: { rejectUnauthorized: false },
authPlugins: { mysql_clear_password: rdsSignerAuth },
});
console.info('Connected');
}
catch (e) {
console.error(`MySQL connection error: ${e}`);
throw e;
}
return connection;
};
const mysql2Impl = async () => {
const connection = await getConnection();
//console.info({ type: 'connection', connection });
const result = await connection.promise().query('select * from destiny;');
console.info({ type: 'result', result });
};
export async function testRdsProxy(event, context){
console.info(JSON.stringify({ event, context }));
await mysql2Impl();
return 200;
}
And this is the response
Error {
code: 'ETIMEDOUT',
errno: undefined,
message: 'connect ETIMEDOUT',
sqlState: undefined,
}
I already checked that my lambda function has a policy "rds-db:connect" to "*" resource. Besides, I checked that my proxy is in the same VPC and subnet that my rds db. The secret that holds the credentials to RDS is ok. What I am doing wrong?
The doc states that the RDS proxy cannot be accessed public, so your lambda function need to be in the same security group with the rds proxy.
Please aware that when you make your lambda into a vpc, your lambda may lost its ability to access internet.
Thank you.
You can connect RDS proxy even outside VPC by doing VPC peering from same or different account. I did it for one of the project
If you pass IAM certification
check the user-name(mysql user) has execute [INVOKE LAMBDA] permission
If IAM authentication fails
you should let the proxy setup wizard automatically create an IAM like below
Connectivity > IAM role > Create IAM role
                     > IAM authentication > Required

RDS MySQL timing out intermittently when called from Lambda using NodeJS

My web app uses Lambda using NodeJS and backend is RDS(MySQL). I'm using serverless-mysql to make db calls.
For some reason, the db call times out intermittently. I tried the following:
Enabled flow logs to see if there are any errors (but couldn't find any reject statuses).
Tried making the database publicly available and took lambda out of VPC (to see if it is an issue with VPC configuration). But still, it was failing intermittently. So VPC is out of the equation.
RDS is not having any unusual spikes and connection exhaustion as monitoring shows a peak of only up to 3 connections. Lambda is always kept warm. I tried increasing the time out to up to 25 seconds. Still no luck.
Below is the code I use:
export async function get(event, context, callback) {
if (await warmer(event)) return 'warmed';
context.callbackWaitsForEmptyEventLoop = false;
try {
const userId = getUserIdFromIdentityId(event);
const query = "select * from UserProfile where UserId = ?";
const result = await mysql.query(query, [userId]);
console.log(result);
console.log('getting user account');
mysql.quit();
return success({
profileSettings: result.length > 0 ? result[0] : null,
});
} catch(e) {
console.log(e);
return failure();
}
}
Success function basically returns a json object like below:
return {
statusCode: 200,
headers: {
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Credentials": true
},
body: JSON.stringify(body)
};
mysql is initialized as below:
export const mysql = AWSXray.captureMySQL(require('serverless-mysql')({
config: {
host: process.env.dbHost,
user: process.env.dbUsername,
password: process.env.dbPassword,
database: process.env.database,
}
}));
The only error I can see in Cloudwatch logs is:
Task timed out after 10.01 seconds.

Connection to mysql works fine locally but not as AWS lambda function

I've created a simple mySQL database that I'm trying to access data from via an AWS Lambda function.
This is a version of the code that runs fine locally:
var mysql = require('mysql');
var config = require('./config.json');
var pool = mysql.createPool({
host : config.dbhost,
user : config.dbuser,
password : config.dbpassword,
database : config.dbname
});
pool.getConnection(function(err, connection) {
// Use the connection
connection.query("SELECT username FROM ClimbingDB.users WHERE email = 'testemail1'", function (error, results, fields) {
// And done with the connection.
connection.release();
// Handle error after the release.
if (error) throw error;
console.log(results);
process.exit();
});
});
This is that code converted to work with AWS Lambda:
var mysql = require('mysql');
var config = require('./config.json');
var pool = mysql.createPool({
host : config.dbhost,
user : config.dbuser,
password : config.dbpassword,
database : config.dbname
});
exports.handler = (event, context, callback) => {
//prevent timeout from waiting event loop
context.callbackWaitsForEmptyEventLoop = false;
pool.getConnection(function(err, connection) {
if (err) return callback(err)
// Use the connection
connection.query("SELECT username FROM ClimbingDB.users WHERE email = 'testemail1'", function (error, results, fields) {
// And done with the connection.
connection.release();
// Handle error after the release.
if (error) return callback(error);
else return callback(null,results);
});
});
};
Which times out with this error message:
{
"errorMessage": "2019-07-19T17:49:04.110Z 2f3e208c-62a6-4e90-b8ec-29398780a2a6 Task timed out after 3.00 seconds"
}
I'm not sure why it doesnt seem to be able to connect. I tried adding the function to a vpc and a security group that has access to RDB's, neither of which do anything. I'm not sure what I'm doing wrong here.
You will need:
The Amazon RDS instance in the same VPC as the AWS Lambda function
A security group on the Lambda function (Lambda-SG)
A security group on the RDS instance (DB-SG) that permits inbound connections on port 3306 from Lambda-SG
That is, DB-SG should specifically reference Lambda-SG (it will turn into a security group ID in the format sg-1234).
You might also want to increase the timeout of the Lambda function to give it a bit more time to run.

non-Google MySQL database connection with firebase cloud function

When i try to connect to my MySQL, server sends me an error Error: connect ETIMEDOUT
Here is sample code
const mysql = require('mysql');
const mysqlConfig = {
connectionLimit: 1,
host: "remote_host_ip",
user: "server_user",
password: "server_pass",
database: "server_db",
port: 3306
};
mysql.createConnection(mysqlConfig).connect(function (err) {
if (!err) {
console.log("Database is connected");
} else {
console.log("Database is not connected " + err);
}
});
I am on firebase blaze(pay as you go) plan.
I know the question title already states it, but you are not using GCP Cloud SQL, right?
In that case, there's a great possibility of your MySQL server is not reachable from Cloud Functions. Are you sure network connectivity is OK?
Besides, even in Cloud Functions, it's a good idea to use connection pools. Consider using it, it will be something like that:
var config = {
user: 'root',
password: 'akdaskdasdaE',
database: 'database1'
}
config.connectionLimit = 10
config.multipleStatements = true
// needed in GCP Cloud SQL, but it seems it's not your case
// config.socketPath = `/cloudsql/__INSTANCE_CONNECTION_NAME__`
var connectionPool = mysql.createPool(config)
connectionPool.on('connection', () => {
console.log(`[connectionPool] new connection opened`)
})
// then you use connectionPool.getConnection(..)

How to configure custom database Mysql in Auth0 Connection?

I'm using auth0 as my authentification services into my project. I really love it, but I have a problem when using custom database(MySql), I sure that I have configured the db.connection parameter to my remote shared hosting database in Plesk. It always show : "[Error] Script execution did not complete within 20 seconds. Are you calling the callback function?", When I trying to run "Create" script.
here the script :
function create (user, callback) {
var mysql = require('mysql');
var connection = mysql.createConnection({
host : '192.168.23.16',
user : 'user',
password : 'pass',
port : '3306',
database : 'dbname' });
connection.connect();
var query = "INSERT INTO users SET ?";
var insert = {
password: bcrypt.hashSync(user.password, 10),
email: user.email
};
connection.query(query, insert, function (err, results) {
if (err) return callback(err);
if (results.length === 0) return callback();
callback(null);
});
}
What should I'm doing right now to solve this problem? I'm new to this
Thanks..
Regards,
fxbayuanggara
You're trying to connect to a local IP address (192.168.23.16), which will always fail since database scripts and rules are executed from Auth0's servers. You'll need to make your MySQL server accessible from Auth0's IP addresses, which at the time of writing are the following:
US domains: 138.91.154.99, 54.221.228.15, 54.183.64.135, 54.67.77.38, 54.67.15.170, 54.183.204.205, 54.173.21.107, 54.85.173.28
EU domains: 52.28.56.226, 52.28.45.240, 52.16.224.164, 52.16.193.66