从 Lambda 函数(SAM 应用程序)连接到 SQL 服务器 RDS 数据库?
Connect to an SQL Server RDS database from a Lambda function (SAM App)?
var sql = require("mssql");
const config = {
user: 'username',
password: 'password',
server: 'mssql-instance.cmujwb4lclgy.us-east-1.rds.amazonaws.com',
database: 'mssql-instance',
port: 1433
};
exports.clock = async(event) => {
console.log('Connecting to the rds..')
let message = "Not Connected"
sql.connect(config, function (err) {
if (err) console.log(err);
let sqlRequest = new sql.Request();
let sqlQuery = "SELECT * from InexistantTable where InexistantId = 0;"
message = "Connected"
sqlRequest.sqlQuery(sqlQuery, function(err, data) {
if (err) console.log(err)
console.table(data.recordset);
message = "Connected, attempted query."
sql.close();
});
});
const response = {
statusCode: 200,
body: JSON.stringify("SQL Server: " + message)
}
return response;
}
我得到这个日志
2022-01-25T21:47:01.796Z c3c94b7f-92a9-4b90-8cc4-fe208fff611a INFO ConnectionError: Failed to connect to mssql-instance.cmujwb4lclgy.us-east-1.rds.amazonaws.com:1433 in 15000ms
at /var/task/node_modules/mssql/lib/tedious/connection-pool.js:71:17
at Connection.onConnect (/var/task/node_modules/tedious/lib/connection.js:1043:9)
at Object.onceWrapper (events.js:520:26)
at Connection.emit (events.js:400:28)
at Connection.emit (/var/task/node_modules/tedious/lib/connection.js:1071:18)
at Connection.connectTimeout (/var/task/node_modules/tedious/lib/connection.js:1530:10)
at Timeout._onTimeout (/var/task/node_modules/tedious/lib/connection.js:1475:12)
at listOnTimeout (internal/timers.js:557:17)
at processTimers (internal/timers.js:500:7) {
code: 'ETIMEOUT',
originalError: ConnectionError: Failed to connect to mssql-instance.cmujwb4lclgy.us-east-1.rds.amazonaws.com:1433 in 15000ms
at ConnectionError (/var/task/node_modules/tedious/lib/errors.js:13:12)
at Connection.connectTimeout (/var/task/node_modules/tedious/lib/connection.js:1530:54)
at Timeout._onTimeout (/var/task/node_modules/tedious/lib/connection.js:1475:12)
at listOnTimeout (internal/timers.js:557:17)
at processTimers (internal/timers.js:500:7) {
code: 'ETIMEOUT'
}
}
它位于默认 VPC 中,因此我认为我不需要执行任何安全组或角色。研究这个也很混乱。
如果我必须设置它,我应该在哪里设置?在 VPC 仪表板中?直接在 Lambda 函数中还是在 RDS 实例本身?我是否将它与 RDS 或 Lambda 相关联?入站还是出站?
此外,我正在使用数据库实例名称进行连接。我使用另一个指南创建了一个 MySQL RDS 并且有一个地方我也给了它一个数据库名称,这是我用来连接的那个,但是对于 SQL Server RDS 我没有设置快速标准配置数据库时的此类选项。
您需要为 lambda 创建一个角色。转到(控制台)IAM->Roles->Create role->(select)Lambda->(in permissions)AWSLambdaVPCAccessExecutionRole->tags->name..etc
.
您的 'Trust relationships'(在您创建角色后)应该类似于
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "lambda.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
现在转到您的 lambda 并在 Configuration
选项卡中,编辑 Execution role
并提供您创建的角色的 arn。
编辑:现在在 Configuration
选项卡中,转到 VPC->Edit->select vpc (where your RDS is situated)->select subnet(where your RDS is situated)->select a security group(select any, maybe the one attached to the DB)*->Save
。
如果我没记错的话,任何安全组都可以,Lambda 不需要白名单。
可以找到更多详细信息 here。我希望这能解决您的问题。
我最终成功了。问题不在于安全组或 VPC。这是异步部分。由于我在建立连接之前将响应返回给 Lambda,它从来不知道它成功了,所以它超时了
我必须先确保连接已建立,但我的代码感觉真的很乱。我想改进它
const sql = require('mssql');
exports.mssql = (event, context, callback) => {
sql.connect({
user: 'user',
password: 'pass',
server: 'host',
database: 'testdb',
port: 1433,
},
err => {
if (err) {
console.log("Fail")
callback('connect failed', err);
} else {
let sqlRequest = new sql.Request();
let sqlQuery = "SELECT * from TestTable;"
sqlRequest.query(sqlQuery, function(err, data) {
if (err) {
console.log(err)
}
console.table(data.recordset);
sql.close();
});
callback(null, sqlRequest);
response = {
statusCode: 200,
body: JSON.stringify({
message: "Query returned",
})
}
return response;
}
})
}
var sql = require("mssql");
const config = {
user: 'username',
password: 'password',
server: 'mssql-instance.cmujwb4lclgy.us-east-1.rds.amazonaws.com',
database: 'mssql-instance',
port: 1433
};
exports.clock = async(event) => {
console.log('Connecting to the rds..')
let message = "Not Connected"
sql.connect(config, function (err) {
if (err) console.log(err);
let sqlRequest = new sql.Request();
let sqlQuery = "SELECT * from InexistantTable where InexistantId = 0;"
message = "Connected"
sqlRequest.sqlQuery(sqlQuery, function(err, data) {
if (err) console.log(err)
console.table(data.recordset);
message = "Connected, attempted query."
sql.close();
});
});
const response = {
statusCode: 200,
body: JSON.stringify("SQL Server: " + message)
}
return response;
}
我得到这个日志
2022-01-25T21:47:01.796Z c3c94b7f-92a9-4b90-8cc4-fe208fff611a INFO ConnectionError: Failed to connect to mssql-instance.cmujwb4lclgy.us-east-1.rds.amazonaws.com:1433 in 15000ms
at /var/task/node_modules/mssql/lib/tedious/connection-pool.js:71:17
at Connection.onConnect (/var/task/node_modules/tedious/lib/connection.js:1043:9)
at Object.onceWrapper (events.js:520:26)
at Connection.emit (events.js:400:28)
at Connection.emit (/var/task/node_modules/tedious/lib/connection.js:1071:18)
at Connection.connectTimeout (/var/task/node_modules/tedious/lib/connection.js:1530:10)
at Timeout._onTimeout (/var/task/node_modules/tedious/lib/connection.js:1475:12)
at listOnTimeout (internal/timers.js:557:17)
at processTimers (internal/timers.js:500:7) {
code: 'ETIMEOUT',
originalError: ConnectionError: Failed to connect to mssql-instance.cmujwb4lclgy.us-east-1.rds.amazonaws.com:1433 in 15000ms
at ConnectionError (/var/task/node_modules/tedious/lib/errors.js:13:12)
at Connection.connectTimeout (/var/task/node_modules/tedious/lib/connection.js:1530:54)
at Timeout._onTimeout (/var/task/node_modules/tedious/lib/connection.js:1475:12)
at listOnTimeout (internal/timers.js:557:17)
at processTimers (internal/timers.js:500:7) {
code: 'ETIMEOUT'
}
}
它位于默认 VPC 中,因此我认为我不需要执行任何安全组或角色。研究这个也很混乱。
如果我必须设置它,我应该在哪里设置?在 VPC 仪表板中?直接在 Lambda 函数中还是在 RDS 实例本身?我是否将它与 RDS 或 Lambda 相关联?入站还是出站?
此外,我正在使用数据库实例名称进行连接。我使用另一个指南创建了一个 MySQL RDS 并且有一个地方我也给了它一个数据库名称,这是我用来连接的那个,但是对于 SQL Server RDS 我没有设置快速标准配置数据库时的此类选项。
您需要为 lambda 创建一个角色。转到(控制台)IAM->Roles->Create role->(select)Lambda->(in permissions)AWSLambdaVPCAccessExecutionRole->tags->name..etc
.
您的 'Trust relationships'(在您创建角色后)应该类似于
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "lambda.amazonaws.com" }, "Action": "sts:AssumeRole" } ] }
现在转到您的 lambda 并在 Configuration
选项卡中,编辑 Execution role
并提供您创建的角色的 arn。
编辑:现在在 Configuration
选项卡中,转到 VPC->Edit->select vpc (where your RDS is situated)->select subnet(where your RDS is situated)->select a security group(select any, maybe the one attached to the DB)*->Save
。
如果我没记错的话,任何安全组都可以,Lambda 不需要白名单。
可以找到更多详细信息 here。我希望这能解决您的问题。
我最终成功了。问题不在于安全组或 VPC。这是异步部分。由于我在建立连接之前将响应返回给 Lambda,它从来不知道它成功了,所以它超时了
我必须先确保连接已建立,但我的代码感觉真的很乱。我想改进它
const sql = require('mssql');
exports.mssql = (event, context, callback) => {
sql.connect({
user: 'user',
password: 'pass',
server: 'host',
database: 'testdb',
port: 1433,
},
err => {
if (err) {
console.log("Fail")
callback('connect failed', err);
} else {
let sqlRequest = new sql.Request();
let sqlQuery = "SELECT * from TestTable;"
sqlRequest.query(sqlQuery, function(err, data) {
if (err) {
console.log(err)
}
console.table(data.recordset);
sql.close();
});
callback(null, sqlRequest);
response = {
statusCode: 200,
body: JSON.stringify({
message: "Query returned",
})
}
return response;
}
})
}