updated : AWS Lambda is not able to connect to MySQL - amazon-web-services

I was not able to connect to MySQL using AWS Lambda with Node.js.
I had tried configured the security groups for AWS MySQL and Lambda. When I used console.log it shows correct response from the data base as the data from db : rk, but when I tried to test it was not showing the correct response.
Below was the logs and the index.js files and logs. Can anybody please guide me ?
index.js (i had updated my code as below ):
var mysql = require('mysql');
var pool = mysql.createPool({
host : 'mydbinstancelamda.connqa9taxeg.us-east-1.rds.amazonaws.com',
user : 'admin',
password : 'password',
database : 'dbname'
});
exports.handler = (event, context, callback)=> {
pool.getConnection(function(err, connection) {
if (err) throw err;
var queryString = "SELECT emp_name from employee where emp_name='rk'";
connection.query(queryString, function(err, rows, fields) {
if (err) throw err;
console.log("the data from db : " + rows[0].emp_name);
callback(null);
connection.release();
});
});
};
error :
Response:
{
"errorMessage": "2018-06-11T02:34:19.817Z ef864d3d-6d1f-11e8-b6e3-97ac89a0f544 Task timed out after 3.00 seconds"
}
Request ID:
"ef864d3d-6d1f-11e8-b6e3-97ac89a0f544"
Function Logs:
START RequestId: ef864d3d-6d1f-11e8-b6e3-97ac89a0f544 Version: $LATEST
dadf1a33-6d22-11e8-869d-7d7e31ccaf6e the data from db : rk
END

Try changing the lambda execution timeout from lambda console as shown in the below picture:
Make sure that security group of RDS MySQL DB is allowing connections from Lambda's security group, if there are the same then you are good to go.
UPDATE:
You need to call callback after the MySQL returns the response.
// change following line:
exports.handler = (event, context, req,res,callback)=> {
// To this line:
exports.handler = (event, context, callback)=> {
After the work is finished, You need to callback to tell lambda that work is complete:
callback(undefined, result);
Example: https://docs.aws.amazon.com/lambda/latest/dg/nodejs-prog-model-handler.html#nodejs-prog-model-handler-example

i followed my instructions given by #Dilip Kola , were my mistakes are not closing the pool , handler arguments !...
my complete code looks like now :
var mysql = require('mysql');
var pool = mysql.createPool({
host : 'url for mysql ',
user : 'username ',
password : 'paswrod ',
database : 'database-name'
});
exports.handler = (event, context, callback)=> {
pool.getConnection(function(err, connection) {
if (err) throw err;
var queryString = "SELECT emp_name from employee where emp_name='rk'";
connection.query(queryString, function(err, rows, fields) {
if (err) throw err;
console.log("the data from db : " + rows[0].emp_name);
connection.release();
pool.end();
callback(null,rows[0].emp_name);
});
});
};
finally i got my output as :

Related

Lambda function access by RDS trigger creates connection lost

I created 2 tables in RDS aurora:
test-table in aurora db with values id(PK), tasknumber, status , contactid(FK)
contact-table in same db with values contactid(PK), email, phone
I created a trigger in 'test-table' that whenever a 'status' changes, the trigger should call AWS-Lambda ARN.
The Lambda function and Aurora has all the permissions, and security cleared, still on testing from Lambda I get below image error and on updating the 'status' field manually in aurora(via Workbench Sql query) it shows:
Operation failed: There was an error while applying the SQL script to the database.
ERROR 2013: 2013: Lost connection to MySQL server during query
I have attached my Lambda Node.Js code too.
var AWS = require('aws-sdk');
AWS.config.update({ region: 'us-east-1' });
const mysql = require('mysql');
var con = mysql.createConnection({
host: 'correct value',
user: 'root',
password: 'correct value',
port: correct value,
database: 'correct value'
});
exports.handler = (event, context, callback) => {
context.callbackWaitsForEmptyEventLoop = false;
var fk = event.contact_id;
console.log('FOREIGN KEY=', fk)
con.connect(function(err) {
if (err) throw err;
var sql = `SELECT * FROM db.contacts where contact_id=${fk}`
con.query(sql, function(err, result) {
if (err) throw err;
var email = result[0].email;
console.log(email);
var sns = new AWS.SNS();
var params = {
Message: email,
Subject: "Test SNS From Lambda",
TopicArn: "arn:correct value"
};
sns.publish(params, function(err, data) {
if (err) console.log(err, err.stack);
else {
console.log(data);
callback(null, 'Success');
}
});
});
});
};
Image1ErrorMySqlWorkbench
Image2ErrorLambdaaws
Also followed for NodeJs package: https://github.com/isaacs
you have to close the connection if you want the instant response otherwise it will take the default time to close the connection, please let me know if makes sense

AWS Unrecognizable Lambda Output Cognito error

I recently started working with AWS. I have integrated AWS Amplify using cognito user pools for my user management(login&signup) and it went perfect(User pool gets updated whenever a new user registers). Now i have added an Cognito Post confirmation trigger to save the registered email into database and here is my trigger codevar 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) => {
let inserts = [event.request.userAttributes.email];
context.callbackWaitsForEmptyEventLoop = false; //prevents duplicate entry
pool.getConnection(function(error, connection) {
connection.query({
sql: 'INSERT INTO users (Email) VALUES (?);',
timeout: 40000, // 40s
values: inserts
}, function (error, results, fields) {
// And done with the connection.
connection.release();
// Handle error after the release.
if (error) callback(error);
else callback(null, results);
});
});
};
whenever a user registers and confirms his email this trigger invokes and throws me this error
"Unrecognizable Lambda Output Cognito ". Even though it throws me this error in the background my DB is getting inserted with new registered email, but i am unable to redirect my page due to this. Any help will be appreciated. Thanks
Aravind
Short answer: Replace callback(null, results); to callback(null, event);
Reason: You have to return the result that Cognito will use it for continue the authentication workflow. In this case, this is event object.

Not able to connect to AWS documentDb from Lambda

I'm trying to connect to AWS documentDB from Lambda function but, not able to connect.
MongoClient.connect never calls the callback function connected.
TLS is off on documentDB Cluster. I'm able to connect via mongo shell.
Lambda & documentDB are in same VPC & Security group.
'use strict';
module.exports.search = async (event, context, callback) => {
const MongoClient = require('mongodb').MongoClient;
const url = "mongodb://xxx:xxxx#xxx-db.cluster-xxx.us-east-2.docdb.amazonaws.com:27017";
console.log("Starting");
MongoClient.connect(url,
{
useNewUrlParser: true
},
function(err, client) {
if(err)
throw err;
console.log("Connected");
db = client.db('mydb');
col = db.collection('mycollection');
col.find({}).toArray().then(result => {
console.log(result);
return { statusCode: 200, body: result };
}).catch(err => {
console.log('=> an error occurred: ', err);
return { statusCode: 500, body: 'error' };
});
});
};
Output only prints starting which was consoled before calling Mongo.Connect.
How to identify or debug the issue ?
Just from looking at the current code I am pretty sure your function exit before it is able to complete. Therefore, your callback is not executed
Because MongoClient.connect runs asynchronously
Try to take a look at some resource around async/await/promise and Lambda
https://medium.com/tensult/async-await-on-aws-lambda-function-for-nodejs-2783febbccd9
How to wait for async actions inside AWS Lambda?

AWS Lambda Timeout Followed by Connection Error

I have an AWS Lambda that runs every five minutes. The Lambda will create a connection to an RDS database inside my VPC and run some queries.
The Lambda will successfully run three times, so for about 15 minutes or so, but, then I get a timeout error:
Task timed out after 600.10 seconds
After this timeout error, the next time the Lambda attempts to run, I can no longer connect to my RDS database. I get the following timeout error:
Error: connect ETIMEDOUT
I'm pretty stumped at this point and could use some more eyes on this:
'use strict';
const mysql = require('mysql');
const util = require('util');
const {
fetchQuery,
insertQuery,
updateQuery,
} = require('./queries');
const {
getInsertValues,
getUpdateValues,
} = require('./utils');
const connection = mysql.createConnection({
host: process.env.DB_HOST,
user: process.env.DB_USER,
password: process.env.DB_PASSWORD,
database: process.env.DB_NAME,
});
// node native promisify
const query = util.promisify(connection.query).bind(connection);
connection.connect();
module.exports.scan = async (event, context, callback) => {
let results = await query(fetchQuery);
console.log(`found ${results.length} forms that are scheduled to be filed`);
if (results.length > 0) {
const insertValues = getInsertValues(results);
const updateValues = getUpdateValues(results);
try {
console.log(`creating user_tasks`);
await query(insertQuery, [insertValues]);
console.log(`updating next_scheduled dates`);
await query(updateQuery, [updateValues]);
callback(null, 'successfully updated form next_scheduled')
} catch (err) {
console.error('error creating user_tasks')
callback(err, 'error creating user_tasks')
}
}
}
Try closing the connection to the database once you are done using it, I previously had a similar error because the open connection was keeping the Lambda alive until it got timeout

How to use WCF service hosted on IIS in an AWS lambda function?

I have this scenario in which a service hosted on IIS must be used by my AWS lambda function. When I try adding it as a service reference, I'm getting "An error occurred while attempting to discover services in the solution: No services found in the solution.. " error. I don't find any issue with the service, and it is working fine.
Is there any link that I'm missing to make my service available to be used by AWS?
If you are using node.js for Lambda then please do like below,
var soap = require('soap');
var url = 'YouServiceURL.svc?wsdl';
var soapOptions = {
forceSoap12Headers: true
};
var soapHeader = {
'wsa:Action': 'http://tempuri.org/MyBinding/MyOperation',
'wsa:To': 'YouServiceURL.svc'
};
exports.handler = function(event, context, callback) {
var params = {
param1: event.param1,
param2: event.param2
};
soap.createClient(url, soapOptions, function(err, client) {
if (err) callback(err);
client.addSoapHeader(soapHeader, '', 'wsa', 'http://www.w3.org/2005/08/addressing');
client.MyOperation(params, function(err, data) {
if (err) callback(err);
callback(null, data);
});
});
}
Please find sample code here