如何通过Bitbucket+Terraform经SSM访问私有VPC内RDS并初始化数据?
实现Bitbucket Pipelines通过SSM堡垒机访问私有VPC内的RDS并初始化数据
核心方案
利用Bitbucket Pipelines容器部署AWS CLI和SSM会话插件,建立本地端口到RDS的转发隧道,让Terraform的PostgreSQL Provider通过本地端口间接访问私有VPC内的RDS,完成数据库、模式、角色的初始化。
1. 配置AWS权限
给Bitbucket Pipelines使用的IAM身份(用户/角色)添加以下权限:
ssm:StartSession:允许启动针对堡垒机实例的SSM会话ec2messages:CreateMessage、ec2messages:GetMessages、ec2messages:DeleteMessage:SSM会话运行必需的基础权限- 确保该IAM身份已被授权访问目标堡垒机实例
2. 在Pipelines中安装依赖
在bitbucket-pipelines.yml里添加步骤,安装AWS CLI和SSM Session Manager插件:
image: hashicorp/terraform:latest pipelines: default: - step: name: RDS初始化 script: # 安装AWS CLI及相关工具 - apk add --no-cache aws-cli curl rpm # 下载并安装SSM插件 - curl "https://s3.amazonaws.com/session-manager-downloads/plugin/latest/linux_64bit/session-manager-plugin.rpm" -o "session-manager-plugin.rpm" - rpm -ivh session-manager-plugin.rpm # 验证插件安装状态 - session-manager-plugin --version
3. 后台启动SSM端口转发隧道
添加命令建立本地端口到RDS的转发,让Pipelines容器能通过本地端口访问RDS:
# 后台运行SSM端口转发,将本地5432端口映射到RDS的5432端口,替换占位符为实际值 aws ssm start-session \ --target <堡垒机实例ID> \ --document-name AWS-StartPortForwardingSessionToRemoteHost \ --parameters '{"host":["<RDS实例端点>"], "portNumber":["5432"], "localPortNumber":["5432"]}' & # 等待隧道建立,避免Terraform提前执行导致连接失败 sleep 10
4. 调整Terraform的PostgreSQL Provider配置
修改Terraform代码,让PostgreSQL Provider连接本地转发的端口:
provider "postgresql" { host = "localhost" # 指向本地转发端口 port = 5432 username = var.rds_admin_username password = var.rds_admin_password sslmode = "require" # 匹配RDS的SSL配置 superuser = false } # 示例:创建应用数据库和角色 resource "postgresql_database" "app_db" { name = "app_db" owner = postgresql_role.app_user.name } resource "postgresql_role" "app_user" { name = "app_user" password = var.app_user_password login = true }
5. 完整的Pipelines配置示例
整合所有步骤,同时用Bitbucket仓库变量存储敏感信息:
image: hashicorp/terraform:latest pipelines: default: - step: name: 部署并初始化RDS资源 script: # 安装依赖 - apk add --no-cache aws-cli curl rpm - curl "https://s3.amazonaws.com/session-manager-downloads/plugin/latest/linux_64bit/session-manager-plugin.rpm" -o "session-manager-plugin.rpm" - rpm -ivh session-manager-plugin.rpm # 加载AWS认证信息 - export AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID - export AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY - export AWS_REGION=$AWS_REGION # 启动SSM隧道 - aws ssm start-session --target $BASTION_INSTANCE_ID --document-name AWS-StartPortForwardingSessionToRemoteHost --parameters '{"host":["'$RDS_ENDPOINT'"], "portNumber":["5432"], "localPortNumber":["5432"]}' & - sleep 10 # Terraform部署 - terraform init - terraform apply -auto-approve variables: # 这些变量需在Bitbucket仓库的"设置>仓库变量"中配置 AWS_ACCESS_KEY_ID: $AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY: $AWS_SECRET_ACCESS_KEY AWS_REGION: cn-north-1 # 替换为实际区域 BASTION_INSTANCE_ID: i-xxxxxxxxxxxxxxxxx # 替换为堡垒机实例ID RDS_ENDPOINT: my-rds-instance.xxxxxx.cn-north-1.rds.amazonaws.com
关键注意点
- 堡垒机实例必须安装并运行最新版SSM Agent,否则无法建立端口转发会话
- 调整
sleep时间,确保隧道完全建立后再执行Terraform - RDS的安全组需允许堡垒机实例访问5432端口
- 若使用非alpine基础镜像,需调整依赖安装命令(比如用apt代替apk)
内容的提问来源于stack exchange,提问作者Thyvo
相关产品推荐
相关产品推荐

