【AWS实战】用Terraform部署RDS:别在参数组上踩坑
这次复盘我想分享一下在构建生产级RDS实例时,几个绝对不能忽视的细节,尤其是关于版本锁定和参数组的坑。
一、依赖链的逻辑顺序
在整个VPC架构里,RDS其实是个“叶子节点”。它的部署顺序必须在VPC、IAM和Security Group之后。因为RDS必须绑定到一个DB Subnet Group(需要私有子网ID)以及一个安全组(用于控制流量)。如果你尝试先起ALB或EC2,你会发现由于数据库没就绪,应用层的健康检查会一直失败,导致部署流程卡死。
二、避坑指南:版本锁定与配置
在编写 modules/rds 时,我发现一个非常关键的点:必须锁定小版本号。
# 这是一个典型的配置片段
resource "aws_db_instance" "this" {
identifier = "postgres-db-dev"
db_name = "notetaker"
engine = "postgres"
engine_version = "16.3" # 必须精确到 16.3,不能只写 16
allocated_storage = 20
username = "postgres"
port = 5432
# ... 其他配置
}这里有个血泪教训:如果你只写 16,Terraform 在执行 apply 时会自动抓取当前 AWS 区域最新的次要版本(比如 16.4 或 16.5)。在开发环境没问题,但在生产环境,这种不确定的自动升级可能会带来不可预知的行为变化,甚至导致应用崩溃。
三、最容易被忽视的参数组(Parameter Groups)
这是我踩坑最深的地方。很多第三方 Terraform 模块为了通用,默认配置里可能塞了 MySQL 的参数。如果你在部署 PostgreSQL 时直接沿用,会发现配置根本不生效,甚至直接报错。
我实测发现,对于 PostgreSQL 调试来说,开启连接日志是最高效的。我把默认的 MySQL 参数全部删掉,换成了以下配置:
parameters = [
{
name = "log_connections",
value = "1"
},
{
name = "log_disconnections",
value = "1"
},
]为什么要这么做?
在处理连接池耗尽(Connection Pool Exhaustion)或者内存泄漏导致的连接不释放问题时,如果没有这两项日志,你面对的将是一个黑盒。开启后,你可以直接在 AWS CloudWatch 日志里看到哪个 IP 在什么时间点建立了连接,排查速度快了不止一个量级。
四、关于 Option Groups 的误区
很多教程会让你配置 options 块。但我发现很多模块默认带了 MARIADB_AUDIT_PLUGIN。记住,这是 MariaDB 专用的!
如果你用的是 PostgreSQL,请直接把 options 块删掉。PostgreSQL 的审计是通过 pgaudit 扩展实现的,需要通过 shared_preload_libraries 在参数组里配置,而不是通过 Option Group。强行给 Postgres 加 MariaDB 插件,部署时会直接抛出 InvalidParameterValue 错误。
总结一下这次实操的配置逻辑:
- 网络: 必须绑定在私有子网(Private Subnets)。
- 版本: 强制锁定到具体的次要版本(如 16.3)。
- 参数: 检查
parameter_group_family是否与引擎匹配,剔除无关引擎的默认值。 - 审计: 弃用 Option Group,改用 Parameter Group 的日志配置。
虽然过程有点波折,但看到数据库成功在私有子网跑起来的那一刻,真的很有成就感!希望能帮到同样在折腾 AWS 基础设施的朋友们。
