You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用IAM认证连接Lambda与Aurora MySQL数据库(已解决)

已解决:通过RDS代理实现Lambda使用IAM认证连接Aurora MySQL

简要说明(TLDR)

我的Aurora MySQL数据库、RDS代理、EC2实例和Lambda函数均处于同一VPC内,各资源安全组已配置必要的入站/出站规则;Lambda配置了包含PyMySQL和rds-combined-ca-bundle(也尝试过global-bundle)的层,且关联了权限正确的IAM角色;但发现即使在同一VPC中,Lambda>配置>RDS数据库选项无法选择目标数据库。

测试情况

关闭代理的IAM强制认证,将MySQL用户改为mysql_native_password时,Lambda可成功连接该用户;且只有当代理关联的Secrets Manager密钥中的用户名与登录用户名匹配时才能连接——即不使用IAM认证时连接正常,但开启IAM强制认证、将数据库用户改为AWSAuthenticationPlugin并使用IAM令牌作为密码时,无论如何操作都无法连接。

详细配置说明

Aurora MySQL数据库详情

  • 引擎版本:8.0.mysql_aurora.3.09.0(开发/测试环境)
  • 配置:Serverless V2、标准集群存储、可公开访问,启用IAM认证;所有资源共用同一新建VPC
  • 安全组:允许自身、Lambda、EC2和RDS代理的IP/安全组访问的入站规则
  • 端点:拥有读写两个端点

EC2实例详情

  • 配置:Amazon Linux 2023 AMI、t2.micro实例类型,新建密钥对,与数据库同VPC
  • 安全组:允许自身入站、全量出站
  • 操作:通过PowerShell SSH登录后,用管理员用户连接数据库,创建并配置IAM认证用户:
ALTER USER 'user'@'%' IDENTIFIED WITH AWSAuthenticationPlugin AS 'RDS';

并为该用户分配数据库访问权限。

RDS代理详情

  • 创建MariaDB和MySQL代理,目标组指向目标数据库
  • 关联IAM角色:拥有SecretsManagerReadWrite权限
  • 关联Secrets Manager密钥:包含dbInstanceIdentifier、engine、host(集群端点)、port、resourceId(集群)、username(IAM数据库用户名)、password(该用户转为IAM认证前的旧密码)
  • 认证配置:认证类型为MySQL Native Password,启用IAM强制认证,连接要求传输层安全,与数据库同VPC

Lambda详情

  • 基础配置:Python 3.13运行时、x86_64架构,与数据库同VPC且选择相同的3个子网
  • IAM角色:包含AWSLambdaVPCAccessExecutionRole策略及以下内联策略:
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "rds-db:connect"
            ],
            "Resource": [
                "arn:aws:rds-db:{MyRegion}:{MyAccountNumber}:dbuser:{Proxy Id}/{DBUser}"
            ]
        }
    ]
}
  • 安全组:配置全量出站及指向RDS代理的出站规则
  • 环境变量:
rds_db_name: DatabaseName
rds_password: password
rds_port: 3306
rds_proxy_host: Proxy Endpoint
rds_region: us-east-2
rds_username: Name Of DB User
  • 注意:即使在同一VPC中,Lambda配置页的RDS数据库选项无法选择目标数据库

初始Lambda代码

import pymysql
import sys
import boto3
import os

# rds settings
username = os.environ['rds_username']
proxy_host = os.environ['rds_proxy_host']
db_name = os.environ['rds_db_name']
region = os.environ['AWS_REGION']
port = 3306
os.environ['LIBMYSQL_ENABLE_CLEARTEXT_PLUGIN'] = '1'

def lambda_handler(event, context):
    client = boto3.client('rds')

    token = client.generate_db_auth_token(
        DBHostname=proxy_host,
        Port=port,
        DBUsername=username,
        Region=region
    )
    try:
        # Connect using IAM token
        connection = pymysql.connect(
            host=proxy_host,
            user=username,
            password=token,
            port=port,
            database=db_name,
            ssl_ca='/opt/python/global-bundle.pem'
        )
        
    except Exception as e:
        print("Database connection failed due to {}".format(e))

问题解决说明

现已解决该问题,原因在于初始代码过度复杂化,删除冗余日志和多余导入、简化代码后即可正常连接,具体触发问题的细节尚不明确,但核心是实现逻辑被不必要的代码干扰。


内容的提问来源于stack exchange,提问作者JasperS

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 23:50:57