带有 RDS Postgresql 的 AWS Lambda - 未知问题

AWS Lambda with RDS Postgresql - Unknown Issue

我已经为这个问题苦苦思索了 3 天,无法弄清楚问题出在哪里。我在 Lambda 函数中将所有登录凭据设置为环境变量。我的 RDS 实例对公众开放,安全组也打开传入和传出端口。

我的 PostgresQL 代码有很多变体,最新的一个来自这个

我当前的 lambda 代码

const pg = require('pg')
const pool = new pg.Pool()

async function query (q) {
  const client = await pool.connect()
  let res
  try {
    await client.query('BEGIN')
    try {
      res = await client.query(q)
      await client.query('COMMIT')
    } catch (err) {
      await client.query('ROLLBACK')
      throw err
    }
  } finally {
    client.release()
  }
  return res
}

exports.handler = async (event, context, callback) => {
    try {
      const { rows } = await query("select 'thaison' as ")
      console.log(JSON.stringify(rows[0]))
      var response = {
          "statusCode": 200,
          "headers": {
              "Content-Type" : "application/json"
          },
          "body": JSON.stringify(rows),
          "isBase64Encoded": false
      };
      callback(null, response);
    } catch (err) {
      console.log('Database ' + err)
      callback(null, 'Database ' + err);
    }
};

我可以在pool.connect()前后成功地做一个console.log。我也可以在 client.query() 之前 console.log 但不能在之后。问题是在 client.query() 之后,没有任何反应。我检查了 Cloudwatch 日志和指标,日志上没有任何内容,也没有任何错误报告。代码必须在某处失败,但我无法弄清楚在哪里。响应为空,查询后我无法记录任何内容,甚至在 catch(err) 块中也没有。我做的最后一件事是将 PG 端点更改为甚至不存在的东西,但我仍然没有收到任何错误。这东西就默默的失败了。

我做错了什么?

由于您使用的是 Publicly Available = Yes,数据库的 DNS 名称将解析为 public IP 地址。这意味着 Lambda 函数 需要 Internet 访问权限

这可以通过 NOT 将 Lambda 函数附加到 VPC 或通过将 Lambda 函数附加到 私有子网 来完成然后在 public 子网中使用 NAT 网关 来提供对 Internet 的访问。安全组应允许来自 0.0.0.0/0 的访问(这对安全性非常不利)。

配置此类系统的更多 'secure' 方法是:

  • 使用 Publicly Available = No,这只会将 RDS 数据库的 DNS 名称解析为 私有 IP 地址
  • 将 Lambda 函数附加到与 RDS 数据库位于同一 VPC 中的子网
  • 将安全组附加到允许默认“允许所有”出站访问的 Lambda 函数 (Lambda-SG)
  • 将安全组附加到 RDS 数据库 (RDS-SG),允许使用 Source = Lambda-SG
  • 在端口 5432 (PostgreSQL) 上进行入站访问

也就是说,RDS-SG 在其入站规则中特别引用了 Lambda-SG。这将允许 Lambda 函数访问 RDS 数据库。

但是,请注意,RDS 数据库只能从 VPC 内部访问。您将无法从您自己的 Internet 计算机连接到它(因为它现在更安全)。如果需要,您可以使用带有端口转发的 跳转框 进行连接。