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

如何通过Terraform让同一VPC内的ECS实例连接固定主机名的RDS数据库?

解决方案:无需重建镜像实现ECS与RDS的固定连接

当然可以实现,不用每次为了RDS的DNS地址重新构建Docker镜像。以下是几种适配同一VPC场景的可行方案:

1. 直接使用RDS静态私有IP(单AZ场景适用)

如果你的RDS是单AZ部署,其私有IP在实例生命周期内是固定的(除非手动销毁重建)。你可以在Terraform中直接获取RDS的私有IP,然后通过ECS任务定义的环境变量注入,完全不需要修改镜像:

# 定义RDS实例
resource "aws_db_instance" "my_rds" {
  # 你的RDS配置参数...
}

# 在ECS任务定义中注入数据库地址环境变量
resource "aws_ecs_task_definition" "app_task" {
  # 其他任务配置...
  container_definitions = jsonencode([
    {
      name = "app-container"
      image = "your-ecr-repo/app-image:latest"
      environment = [
        {
          name = "DB_HOST"
          value = aws_db_instance.my_rds.private_ip
        }
        # 其他业务环境变量...
      ]
    }
  ])
}

注意:多AZ RDS故障转移后,私有IP会切换到备用实例,这种场景下该方案不适用。

2. 配置Route 53私有托管区(多AZ/单AZ通用)

在同一VPC下创建Route 53私有托管区,将一个固定的自定义域名(比如db.internal.yourdomain.com)解析到RDS的端点或私有IP。ECS容器直接使用这个固定域名连接数据库,无需修改镜像:

# 创建私有DNS托管区
resource "aws_route53_zone" "private_db_zone" {
  name = "db.internal.yourdomain.com"
  vpc {
    vpc_id = aws_vpc.your_vpc.id
  }
}

# 配置CNAME记录指向RDS官方端点(多AZ推荐),单AZ也可改用A记录指向私有IP
resource "aws_route53_record" "db_dns" {
  zone_id = aws_route53_zone.private_db_zone.zone_id
  name    = "mysql.db.internal.yourdomain.com"
  type    = "CNAME"
  ttl     = "300"
  records = [aws_db_instance.my_rds.endpoint]
}

优势:多AZ场景下,RDS故障转移后官方端点会自动指向新实例,Route 53会同步解析结果,容器无需任何改动即可继续连接。

3. 通过SSM参数存储动态获取地址(通用方案)

把RDS的连接地址存储在SSM参数存储中,由Terraform负责更新参数值,ECS容器启动时通过脚本从SSM拉取地址,完全解耦镜像和数据库地址:

# 在SSM中存储RDS私有IP
resource "aws_ssm_parameter" "db_host" {
  name        = "/ecs/app/db_host"
  type        = "String"
  value       = aws_db_instance.my_rds.private_ip
  description = "RDS private IP for ECS application"
}

# 给ECS任务执行角色添加SSM读取权限
resource "aws_iam_role_policy" "ecs_ssm_access" {
  name = "ecs-ssm-read-access"
  role = aws_iam_role.ecs_task_execution_role.id

  policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Action = "ssm:GetParameter"
        Effect = "Allow"
        Resource = aws_ssm_parameter.db_host.arn
      }
    ]
  })
}

然后在容器的启动脚本(比如entrypoint.sh)中添加拉取逻辑:

#!/bin/bash
# 从SSM获取数据库地址
export DB_HOST=$(aws ssm get-parameter --name /ecs/app/db_host --query Parameter.Value --output text)
# 启动应用
exec your-app-command

这种方案既支持单AZ也支持多AZ,即使RDS地址变化,Terraform会自动更新SSM参数,容器重启后就能获取最新地址。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 13:33:23