使用SQLAlchemy连接含Secret Manager的AWS RDS PostgreSQL遇加密错误
问题:AWS RDS PostgreSQL连接失败(密码认证错误+无加密配置)
1. CDK创建RDS实例代码
我用AWS CDK通过Secret Manager生成的凭证创建了PostgreSQL实例,代码如下:
rds.DatabaseInstance( self, id=resource_name, instance_identifier=resource_name, database_name=db_name, port=db_port, engine=rds.DatabaseInstanceEngine.postgres( version=rds.PostgresEngineVersion.VER_16_8, ), instance_type=instance_type, vpc=vpc, vpc_subnets=vpc_subnets, multi_az=True, allocated_storage=20, credentials=rds.Credentials.from_generated_secret( username="db_user", secret_name=name_provider.resource("rds-credentials-admin-pw"), ), iam_authentication=True, removal_policy=RemovalPolicy.RETAIN, security_groups=[rds_sg], )
2. 连接RDS的代码
尝试用以下代码连接实例:
db_url = f"postgresql://{db_user_name}:{db_password}@{db_endpoint_writer}:{db_port}/{db_name}" engine = create_db_engine(db_url) session_mgr = SessionManager(engine) with rds_session_mgr.create_session() as session: # 执行查询逻辑
3. 连接错误信息
连接时出现两个错误:
connection to server at "xxx.rds.amazonaws.com" (1.1.1.1), port ppppp failed: FATAL: password authentication failed for user "db_user" connection to server at "xxx.rds.amazonaws.com" (1.1.1.1), port ppppp failed: FATAL: no pg_hba.conf entry for host "2.2.2.2", user "db_user", database "dbname", no encryption (Background on this error at: https://sqlalche.me/e/20/e3q8)
背景与疑问
之前用SSM参数存储凭证时,相同的连接配置能正常工作。现在意识到需要在连接时启用加密,但不知道怎么在SQLAlchemy里配置。找到过相关问题,但不知道如何应用到当前场景。
解决方案
1. 确保正确获取Secret Manager中的凭证
Secret Manager生成的凭证是JSON格式,包含username、password、host等字段,不能像SSM那样直接取明文值。需要用boto3解析Secret内容:
import boto3 import json # 初始化Secrets Manager客户端 secrets_client = boto3.client('secretsmanager') # 获取Secret内容 secret_response = secrets_client.get_secret_value(SecretId='rds-credentials-admin-pw') secret_data = json.loads(secret_response['SecretString']) # 从解析后的JSON中提取连接参数 db_user_name = secret_data['username'] db_password = secret_data['password'] db_endpoint_writer = secret_data['host'] db_port = secret_data['port'] db_name = secret_data['dbname']
2. 在SQLAlchemy连接URL中启用加密
RDS PostgreSQL默认要求加密连接,需要在URL中添加sslmode参数:
基础加密配置(仅要求加密,不验证证书)
db_url = f"postgresql://{db_user_name}:{db_password}@{db_endpoint_writer}:{db_port}/{db_name}?sslmode=require"
严格加密配置(验证RDS CA证书)
如果需要更高安全性,可使用verify-full模式,需先下载AWS RDS官方CA证书(如rds-ca-2019-root.pem),然后指定证书路径:
db_url = f"postgresql://{db_user_name}:{db_password}@{db_endpoint_writer}:{db_port}/{db_name}?sslmode=verify-full&sslrootcert=rds-ca-2019-root.pem"
3. 额外检查项
- 确认RDS安全组已开放客户端IP访问5432端口;
- 若不需要IAM认证,可关闭
iam_authentication=True(或确保密码认证方式在RDS参数组中被允许)。
内容的提问来源于stack exchange,提问作者DarkTrick
相关产品推荐
相关产品推荐

