AWS Lambda 无法连接到 RDS 实例,但我可以在本地连接?
AWS Lambda can't connect to RDS instance, but I can locally?
我正在尝试从 lambda 连接到我的 RDS 实例。我在本地编写了 lambda 并在本地进行了测试,一切都很顺利。我部署到 lambda,突然它不起作用了。下面是我 运行 的代码,如果有帮助,我将通过运动流调用 lambda。
'use strict';
exports.handler = (event, context, handlerCallback) => {
console.log('Recieved request for kinesis events!');
console.log(event);
console.log(context);
const connectionDetails = {
host: RDS_HOST,
port: 5432,
database: RDS_DATABASE,
user: RDS_USER,
password: RDS_PASSWORD
};
const db = require('pg-promise')({promiseLib: require('bluebird')})(connectionDetails);
db
.tx(function () {
console.log('Beginning query');
return this.query("SELECT 'foobar'")
.then(console.log)
.catch(console.log)
.finally(console.log);
})
.finally(() => handlerCallback());
};
如果有帮助,这里是来自云监视的日志:
START RequestId: *********-****-****-****-********* Version: $LATEST
2016-05-31T20:58:25.086Z *********-****-****-****-********* Recieved request for kinesis events!
2016-05-31T20:58:25.087Z *********-****-****-****-********* { Records: [ { kinesis: [Object], eventSource: 'aws:kinesis', eventVersion: '1.0', eventID: 'shardId-000000000000:**********************************', eventName: 'aws:kinesis:record', invokeIdentityArn: 'arn:aws:iam::******************:role/lambda_kinesis_role', awsRegion: 'us-east-1', eventSourceARN: 'arn:aws:kinesis:us-east-1:****************:stream/route-registry' } ] }
2016-05-31T20:58:25.283Z *********-****-****-****-********* { callbackWaitsForEmptyEventLoop: [Getter/Setter], done: [Function], succeed: [Function], fail: [Function], logGroupName: '/aws/lambda/apiGatewayRouteRegistry-development', logStreamName: '2016/05/31/[$LATEST]******************', functionName: 'apiGatewayRouteRegistry-development', memoryLimitInMB: '128', functionVersion: '$LATEST', getRemainingTimeInMillis: [Function], invokeid: '*********-****-****-****-*********', awsRequestId: '*********-****-****-****-*********', invokedFunctionArn: 'arn:aws:lambda:us-east-1:*************:function:apiGatewayRouteRegistry-development' }
END RequestId: *********-****-****-****-*********
REPORT RequestId: *********-****-****-****-********* Duration: 20003.70 ms Billed Duration: 20000 ms Memory Size: 128 MB Max Memory Used: 22 MB
2016-05-31T20:58:45.088Z *********-****-****-****-********* Task timed out after 20.00 seconds
@MarkB @Michael-sqlbot 在评论中是正确的,这是一个安全组问题。
我终于得到 AWS 支持响应指出 RDS 安全组确实是特定 IP 私有的。这没有意义,因为我从未配置过它,而且我可以从我的本地机器和弹性 beanstalk 访问数据库。我将 0.0.0.0/0 添加到安全组,现在 lambda 可以连接了。谢谢大家的帮助!
这是我解决这个问题的方法。
创建数据库实例时,系统会要求您select VPC。即使您 select 默认值,它也会将您系统的 public IP 作为默认入站 IP。另一方面,Lambda 函数有自己的 IP 设置。这就是为什么您可以通过任何 IDE 或本地访问但不能通过 lambda 函数访问的原因。
添加IP限制:
转到实例的安全组。 select设置默认安全组后,点击它。在新页面中,向下滚动以找到入站和出站设置。
在入站设置中,点击编辑。您可以在此处更改 IP。 (0.0.0.0/0 使其向世界开放)
如果您在此处添加 public IP,则 IDE 或您的本地连接将可用。
要使 lambda 函数正常工作,请添加 lambda 函数的 IP。
转到 Lambda 函数,网络 --> VPC -->(如果没有 VPC selected,select 与 DB 函数相同的 VPC)并在此处记下 IP。
在入站设置中输入此 IP,这将显示自动填充。
保存并测试您的 lambda 函数。
这是没有全球访问权限的问题的答案。
重复马克的回答:
- 添加对 lambda 函数的 vpc 访问
- 为 lambda 创建一个新的安全组
- 将 RDS 安全组添加到 lambda 的 SG。
我正在尝试从 lambda 连接到我的 RDS 实例。我在本地编写了 lambda 并在本地进行了测试,一切都很顺利。我部署到 lambda,突然它不起作用了。下面是我 运行 的代码,如果有帮助,我将通过运动流调用 lambda。
'use strict';
exports.handler = (event, context, handlerCallback) => {
console.log('Recieved request for kinesis events!');
console.log(event);
console.log(context);
const connectionDetails = {
host: RDS_HOST,
port: 5432,
database: RDS_DATABASE,
user: RDS_USER,
password: RDS_PASSWORD
};
const db = require('pg-promise')({promiseLib: require('bluebird')})(connectionDetails);
db
.tx(function () {
console.log('Beginning query');
return this.query("SELECT 'foobar'")
.then(console.log)
.catch(console.log)
.finally(console.log);
})
.finally(() => handlerCallback());
};
如果有帮助,这里是来自云监视的日志:
START RequestId: *********-****-****-****-********* Version: $LATEST
2016-05-31T20:58:25.086Z *********-****-****-****-********* Recieved request for kinesis events!
2016-05-31T20:58:25.087Z *********-****-****-****-********* { Records: [ { kinesis: [Object], eventSource: 'aws:kinesis', eventVersion: '1.0', eventID: 'shardId-000000000000:**********************************', eventName: 'aws:kinesis:record', invokeIdentityArn: 'arn:aws:iam::******************:role/lambda_kinesis_role', awsRegion: 'us-east-1', eventSourceARN: 'arn:aws:kinesis:us-east-1:****************:stream/route-registry' } ] }
2016-05-31T20:58:25.283Z *********-****-****-****-********* { callbackWaitsForEmptyEventLoop: [Getter/Setter], done: [Function], succeed: [Function], fail: [Function], logGroupName: '/aws/lambda/apiGatewayRouteRegistry-development', logStreamName: '2016/05/31/[$LATEST]******************', functionName: 'apiGatewayRouteRegistry-development', memoryLimitInMB: '128', functionVersion: '$LATEST', getRemainingTimeInMillis: [Function], invokeid: '*********-****-****-****-*********', awsRequestId: '*********-****-****-****-*********', invokedFunctionArn: 'arn:aws:lambda:us-east-1:*************:function:apiGatewayRouteRegistry-development' }
END RequestId: *********-****-****-****-*********
REPORT RequestId: *********-****-****-****-********* Duration: 20003.70 ms Billed Duration: 20000 ms Memory Size: 128 MB Max Memory Used: 22 MB
2016-05-31T20:58:45.088Z *********-****-****-****-********* Task timed out after 20.00 seconds
@MarkB @Michael-sqlbot 在评论中是正确的,这是一个安全组问题。
我终于得到 AWS 支持响应指出 RDS 安全组确实是特定 IP 私有的。这没有意义,因为我从未配置过它,而且我可以从我的本地机器和弹性 beanstalk 访问数据库。我将 0.0.0.0/0 添加到安全组,现在 lambda 可以连接了。谢谢大家的帮助!
这是我解决这个问题的方法。
创建数据库实例时,系统会要求您select VPC。即使您 select 默认值,它也会将您系统的 public IP 作为默认入站 IP。另一方面,Lambda 函数有自己的 IP 设置。这就是为什么您可以通过任何 IDE 或本地访问但不能通过 lambda 函数访问的原因。
添加IP限制:
转到实例的安全组。 select设置默认安全组后,点击它。在新页面中,向下滚动以找到入站和出站设置。
在入站设置中,点击编辑。您可以在此处更改 IP。 (0.0.0.0/0 使其向世界开放)
如果您在此处添加 public IP,则 IDE 或您的本地连接将可用。
要使 lambda 函数正常工作,请添加 lambda 函数的 IP。 转到 Lambda 函数,网络 --> VPC -->(如果没有 VPC selected,select 与 DB 函数相同的 VPC)并在此处记下 IP。
在入站设置中输入此 IP,这将显示自动填充。
保存并测试您的 lambda 函数。
这是没有全球访问权限的问题的答案。
重复马克的回答:
- 添加对 lambda 函数的 vpc 访问
- 为 lambda 创建一个新的安全组
- 将 RDS 安全组添加到 lambda 的 SG。