AWS Lambda无法连接到RDS实例,但我可以在本地吗?

Lor*_*eck 15 javascript amazon-web-services amazon-rds amazon-kinesis aws-lambda

我正在尝试从lambda连接到我的RDS实例.我在本地写了lambda并在本地测试,一切都很好用.我部署到lambda,突然它不起作用.下面是我正在运行的代码,如果有帮助,我将通过kinesis流调用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());
};
Run Code Online (Sandbox Code Playgroud)

以下是来自云监视的日志,如果它有帮助:

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
Run Code Online (Sandbox Code Playgroud)

Lor*_*eck 19

@MarkB @ Michael-sqlbot在评论中是正确的,这是一个安全组问题.

我终于获得了AWS支持响应,指出RDS安全组确实是特定IP的私有.这没有意义,因为我从未配置过,我可以从本地机器和弹性beanstalk访问数据库.我将0.0.0.0/0添加到安全组,现在lambda可以连接.谢谢你的帮助!

  • 但是在安全组中向入站添加0.0.0.0/0意味着打开与世界的连接.你不害怕吗? (5认同)
  • @Nativ是用于开发和测试目的。后来,它被锁定到正确的安全组。是的,与世界建立联系对于生产用途而言并不是一个好主意。 (2认同)

小智 10

这是我解决此问题的方法。

创建数据库实例时,要求您选择VPC。即使选择默认值,它也将系统的公共IP作为默认入站IP。另一方面,Lambda函数具有其自己的IP设置。这就是为什么您可以通过任何IDE或本地访问但不能通过lambda函数访问的原因。

添加IP限制:

  1. 转到您实例的安全组。选择默认安全组后,单击它。在新页面中,向下滚动以查找入站和出站设置。

  2. 在入站设置中,单击编辑。您可以在此处更改IP。(0.0.0.0/0向世界开放)

  3. 如果您在此处添加公共IP,则IDE或本地连接将起作用。

  4. 为了使lambda函数起作用,请添加lambda函数的IP。转到Lambda函数,网络-> VPC->(如果未选择VPC,请选择与DB函数相同的VPC)并在此处记下IP。

  5. 在入站设置中键入此IP,它将显示自动填充。

保存并测试您的lambda函数。


小智 5

这是无法在全球范围内访问的答案。

允许 AWS Lambda 访问 RDS 数据库

重复马克的回答:

  1. 添加对 lambda 函数的 vpc 访问
  2. 为 lambda 创建一个新的安全组
  3. 将 RDS 安全组添加到 lambda 的 SG。