运行 python 脚本通过 AWS Lambda 删除 RDS 快照时超时

Timeout while running a python script to delete RDS snapshots through AWS Lambda

我正在尝试使用以下 AWS Lambda 的 python 脚本删除旧的 RDS 快照,但是当我尝试 运行 该脚本时,它给我错误 "Task timed out after [whatever timeout period I've specified]." 我我试过将超时时间增加到几分钟,这比这个任务应该花费的时间要长得多,所以我相当有信心这不是因为我的超时时间太短。此外,当 运行 来自 EC2 实例而不是来自 Lambda 时,这段代码工作得很好。

import boto3
import pprint
import time
import re
import datetime

def lambda_handler(event, context):

    DAYS_EXPIRE = 2

    client = boto3.client('rds', region_name='us-east-1')

    snapshots = client.describe_db_snapshots(
            DBInstanceIdentifier='test-rds-instance',
            SnapshotType='manual',
            MaxRecords=100
    )

    list_snapshots = snapshots['DBSnapshots']
    for snap in list_snapshots:
        dbs_id = snap['DBSnapshotIdentifier']
        delta_datetime = datetime.timedelta(days=DAYS_EXPIRE)
        acceptable_datetime = datetime.datetime.now() - delta_datetime
        datestring = re.search(r'\d{4}-\d{2}-\d{2}-\d{2}-\d{2}$', dbs_id).group()
        datetime_snapshot = datetime.datetime.strptime(datestring, '%Y-%m-%d-%H-%M')
        if (datetime_snapshot < acceptable_datetime):
            print "Deleting" + dbs_id
            client.delete_db_snapshot(DBSnapshotIdentifier=dbs_id)

我尝试注释掉各个部分并重新运行以找出错误发生的位置,我认为它在这里:

snapshots = client.describe_db_snapshots(
            DBInstanceIdentifier='test-rds-instance',
            SnapshotType='manual',
            MaxRecords=100
    )

我不确定为什么,因为它在 Lambda 之外工作,但我认为这是连接问题。该脚本附加了一个 IAM 策略,允许它使用 VPC 进行 Lambda 访问和完整的 RDS 访问。我不知道安全组是否限制 Lambda 请求,但为了以防万一,我修改了 RDS 实例的安全组以接受所有入站流量。 RDS 实例可公开访问。我还尝试修改客户端定义以包括控制台中给出的 RDS 端点(尽管这引发了错误 "invalid endpoint")以及接受访问密钥 ID 和访问密钥。但是,这也不起作用。有什么建议吗?

这种说法毫无意义:

The script has an IAM policy attached to it which allows it VPC for Lambda access and full RDS access.

IAM策略和VPC是完全不同的两个东西。此外,您不会在任何地方的 Lambda 函数中打开与数据库的连接,因此关于数据库可公开访问的内容无关紧要。您所有的代码都在调用 AWS API 来管理您的 AWS 账户中的资源。为此,您的 Lambda 函数只需要 Internet 访问权限和适当的 IAM 角色。

听起来您可能已将 Lambda 函数放在 VPC 中。当您这样做时,Lambda 函数只能访问您的 VPC 内的资源。这意味着您的函数无法访问 AWS API 或 Internet。您可以通过向 VPC 添加 NAT 网关来解决此问题。

但是,由于您的 Lambda 函数实际上并未访问您的 VPC 中的任何内容,因此最简单且成本最低的解决方案是从您的 VPC 中删除您的 Lambda 函数。然后它应该能够进行 AWS API 调用来管理您的 RDS 资源。