在无服务器框架中创建可用于 Lambda 函数的 RDS 实例

Posted

技术标签:

【中文标题】在无服务器框架中创建可用于 Lambda 函数的 RDS 实例【英文标题】:Create an RDS instance available to Lambda functions in Serverless Framework 【发布时间】:2021-12-21 00:32:06 【问题描述】:

我有一个通过无服务器框架部署的 AWS Lambda 应用程序。它需要一个数据库,即我在 serverless.yaml 的 resources 部分中包含的 CloudFormation。

在对 VPC、子网和安全组了解最少的情况下,我的目标如下:

    使用serverless deploys 创建/更新 mysql RDS 实例。 Lambda 应用程序中的函数应该能够访问数据库。 数据库应该可以通过密码公开访问,这样我就可以从我的计算机连接 MySQL 工具,例如 Sequel Ace。

到目前为止我所做的尝试:

我已尝试使用以下无服务器配置进行此操作。它创建了数据库,但不满足 #2 和 #3。

我还尝试将 serverless.yaml 中的 provider.vpc.securityGroupIdsprovider.vpc.subnetIds 设置为 RDS 实例使用的相同,但无济于事。

serverless.yaml

(相关部分)

service: myapp

provider:
    name: aws
    runtime: provided.al2
    lambdaHashingVersion: 20201221

functions:
    console:
        handler: bin/console
        timeout: 120 # in seconds
        layers:
            - $bref:layer.php-80 # PHP
            - $bref:layer.console # The "console" layer

resources:
    Resources:
        # RDS instance
        ProductDatabase:
            Type: AWS::RDS::DBInstance
            Properties:
                AllocatedStorage: 5
                DBInstanceClass: db.t3.micro
                DBName: myapp
                Engine: mysql
                EngineVersion: 8.0.25
                MasterUsername: myappuser
                MasterUserPassword: redacted
                PubliclyAccessible: true

【问题讨论】:

【参考方案1】:

有一篇很好的文章here 解释了你需要的步骤。

为了让您的 Lambda 能够访问您的 AWS 资源,它需要位于同一 VPC 中,并且其执行角色需要通过 IAM 角色/组获得适当的权限。

您还希望避免 RDS 对外开放,因此您应该在 VPC 中创建所有这些。您可以将 lambda 函数附加到 VPC,然后通过安全组仅允许对 VPC 子网的 RDS 访问。

这将为您提供第 1 步和第 2 步的要求。

在同一个安全组中,您可以允许访问您计算机的外部 IP 地址以执行第 3 步。您可以通过 CLI 进行配置,因此如果您没有静态 IP,则只需一秒钟即可添加。下面的 PowerShell 示例:

Grant-EC2SecurityGroupIngress -GroupId "sg-xxxxxxxxxx" -IpPermission @(123.123.123.123/32)

【讨论】:

我已按照那篇文章中的步骤操作,但没有成功。当我的 lambda 函数尝试连接到数据库时,它无法连接到主机(SQLSTATE[HY000] [2002] php_network_getaddresses: getaddrinfo failed: Temporary failure in name resolution)。我正在使用 RDS 实例上指定的主机和端口。我已经确认 function 和 db 在同一个 VPC 和子网上,并且每个都有自己的安全组。这是我的 serverless.yaml 的样子:gist.github.com/amacrobert/caf25534e9bb3dced0e81444637186cf 我会做一些事情来看看它在哪里倒塌。首先是设置 VPC 流日志。这些记录通过网络接口的所有流量。设置完成后,您应该会在其中看到来自 Lambda 并以 RDS 为目标的条目。如果您收到拒绝消息,那么这是您需要查看的安全组配置。这是有关设置docs.aws.amazon.com/vpc/latest/userguide/flow-logs.html 的文档。只是为了让您使用 RDS 中连接和安全选项卡中的端点作为主机名? 如果它根本没有命中 VPC 流日志,请查看 Lambda 控制台,找到您的 Lambda 函数、配置选项卡,然后在左侧列表中找到 VPC。检查它是否已附加到 VPC,并且子网和安全组信息看起来都正确。您还可以在与 Lambda 函数相同的子网中启动 EC2 实例,并为其使用 Lambda 安全组。创建一个简单的测试 php 页面,该页面使用您在 Lambda 函数中使用的相同配置连接到 RDS 实例。这可能会更容易调试。 您也可以在控制台中使用VPC下的Reachability Analyzer来检查EC2网络接口和RDS网络接口之间的配置。我不认为它可以与 Lambda 函数一起使用(但我没有专门尝试过)。

以上是关于在无服务器框架中创建可用于 Lambda 函数的 RDS 实例的主要内容,如果未能解决你的问题,请参考以下文章

如何在无服务器框架或 AWS lambda 中启用节点 js 的实验性功能

在 Google AdWords 中创建可重用函数

如何在无服务器框架中包含静态文件?

如何在反应钩子中创建可重用状态?

如何使用无服务器框架从另一个 lambda 异步调用 lambda

如何在 React 中创建可排序的表?如何从排序的对象访问类方法?