使用PyMySql从Lambda连接RDS时遭遇(1045, Access Denied)错误排查
我尝试使用PyMySql库从AWS Lambda连接MySQL RDS,但持续收到错误:(1045, "Access denied for user 'user'@'10.224.13.51' (using password: YES)")
我通过AWS CDK创建Lambda,RDS与Lambda处于同一VPC,基础设施代码如下:
// Shared lambda SecurityGroup const lambdaSecurityGroup = new SecurityGroup(scope, 'exampleSG', { vpc: sharedResources.vpc, allowAllOutbound: true, description: stackConfig.stackName + '-sg', securityGroupName: stackConfig.stackName + '-sg', }); lambdaSecurityGroup.addIngressRule(lambdaSecurityGroup, Port.tcp(3306)); // RDS SecurityGroup const rdsSecurityGroup = SecurityGroup.fromSecurityGroupId(this, 'RDS-SG', 'sg-id'); // Add an ingress rule to the RDS security group to allow traffic from Lambda security group rdsSecurityGroup.addIngressRule(lambdaSecurityGroup, Port.tcp(3306), 'Allow Lambda to connect to RDS'); // get Claims Lambda this.getClaimsLambda = new lambda.Function(this, 'GetClaims', { code: lambda.Code.fromAsset(path.join(__dirname, 'lambdas/get_claims')), runtime: lambda.Runtime.PYTHON_3_11, handler: 'get_claims_lambda.execute', logRetention: logs.RetentionDays.ONE_WEEK, timeout: Duration.seconds(10), description: stackConfig.environmentKey, environment: { ENVIRONMENT: environmentKey, RDS_HOST: secretProvider.getEncryptedSecretVal(stackConfig.rdsSecrets.RDS_HOST, kmsKey), USER_NAME: secretProvider.getEncryptedSecretVal(stackConfig.rdsSecrets.USER_NAME, kmsKey), PASSWORD: secretProvider.getEncryptedSecretVal(stackConfig.rdsSecrets.PASSWORD, kmsKey), }, tracing: Tracing.ACTIVE, // enable X-ray insightsVersion: LambdaInsightsVersion.VERSION_1_0_143_0, layers: [lambdaLayer], vpc: sharedResources.vpc, vpcSubnets: { subnets: sharedResources.subnets, }, role: getClaimsLambdaRole, securityGroups: [lambdaSecurityGroup] });
连接RDS的Python代码如下:
def get_connection(user_name, password, rds_host, db_name): try: return pymysql.connect(host=rds_host, user=user_name, password=password, database=db_name, connect_timeout=5) except Exception as e: logger.error("rds_utils: ERROR Unexpected error: Could not connect to MySQL instance.") logger.error(e)
我已验证凭证正确,可通过MySQLWorkbench正常连接RDS,也配置了RDS与Lambda的安全组规则,请问还有哪些可能的遗漏点?
MySQL用户授权范围不匹配:你用Workbench连接的用户可能仅允许从本地IP访问(比如
user@xxx.xxx.xxx.xxx),但Lambda的IP(10.224.13.51)不在该用户的授权网段内。执行SQL查看用户授权范围:SELECT user, host FROM mysql.user;,如果没有匹配Lambda所在VPC网段的记录,需要新增授权:GRANT ALL ON 目标数据库名.* TO 'user'@'10.224.%.%' IDENTIFIED BY '你的密码'; FLUSH PRIVILEGES;Lambda环境变量解密失败:代码中用
secretProvider.getEncryptedSecretVal获取加密后的凭证,但Lambda角色getClaimsLambdaRole可能没有KMS解密权限。检查该角色是否附加了kms:Decrypt权限,同时确认KMS密钥的策略允许该角色访问。若解密失败,环境变量会是加密字符串,导致凭证无效。VPC子网路由或网络ACL限制:确认Lambda所在子网与RDS子网的路由表包含VPC内部路由;同时检查VPC网络ACL,确保双向允许3306端口流量(Lambda到RDS的出站、RDS到Lambda的入站),网络ACL是无状态规则,两端都要配置。
RDS IAM数据库认证是否启用:如果RDS开启了IAM认证,不能直接用密码连接,需要通过Lambda角色生成临时token作为连接密码。检查RDS实例设置,若开启该功能,需修改连接逻辑并配置Lambda角色对应的RDS IAM权限。
数据库名称错误:连接代码中的
db_name参数是否正确?Workbench连接时可能指定了正确的库,但Lambda代码中可能传入了不存在或无权限访问的数据库名。Lambda环境变量未更新:确认Lambda的环境变量是最新的,有时候部署后环境变量可能未同步,可通过Lambda控制台查看加密后的变量,或重新部署Lambda确保凭证正确加载。
内容的提问来源于stack exchange,提问作者Abdelrahman Khamis

