生产VPC访问限制下Terraform执行Aurora psql查询方案咨询
方案选型结论
优先选择SSH隧道方案(即你提到的思路2),相比直接SSH登录EC2执行脚本有三个明显优势:
- 敏感信息(数据库账号密码、SQL逻辑)全程只在本地Terraform执行端流转,不需要上传到跳板EC2,不会在跳板机残留执行痕迹、临时文件,安全风险更低
- 不需要提前在跳板EC2上预装psql客户端、配置脚本执行权限、调整OS级环境变量,测试/预发环境验证过的SQL脚本几乎可以零修改复用,环境依赖更少
- 隧道生命周期和本地Terraform执行流程绑定,脚本执行完成或报错退出时会自动关闭隧道,不会遗留后台进程占用本地端口
不推荐直接SSH到EC2执行的方案:你需要额外处理脚本跨机器传输、跳板机环境依赖、执行后临时文件清理、跳板机IAM/数据库权限配置等问题,维护成本高且容易出安全疏漏。
可直接运行的代码参考
前置依赖
- 本地执行Terraform的机器已安装
openssh-client、postgresql-client(提供psql命令)、netcat(提供nc端口检测命令) - 跳板EC2安全组已放通本地IP的22端口入站规则
- Aurora安全组已放通跳板EC2所属安全组的5432端口入站规则
main.tf 核心配置
# 可根据实际环境调整变量默认值,敏感变量建议执行时通过环境变量传入 variable "jumpbox_public_ip" { type = string } variable "jumpbox_ssh_user" { type = string default = "ec2-user" } variable "jumpbox_ssh_private_key_path" { type = string default = "~/.ssh/prod_env.pem" } variable "aurora_cluster_writer_endpoint" { type = string } variable "aurora_master_user" { type = string } variable "aurora_master_password" { type = string sensitive = true } variable "aurora_default_db" { type = string default = "postgres" } resource "null_resource" "aurora_post_init" { # 配置触发规则:Aurora地址、SQL脚本变更时自动重新执行 triggers = { aurora_endpoint = var.aurora_cluster_writer_endpoint sql_script_hash = filemd5("${path.module}/pg_queries.sh.tpl") } provisioner "local-exec" { interpreter = ["/bin/bash", "-c"] command = <<-EOT set -euo pipefail # 自动选取本地空闲端口,避免固定端口冲突 LOCAL_TUNNEL_PORT=$(shuf -i 10000-65535 -n1) # 后台启动SSH隧道 ssh -i ${var.jumpbox_ssh_private_key_path} \ -o StrictHostKeyChecking=no \ -o UserKnownHostsFile=/dev/null \ -N -L $${LOCAL_TUNNEL_PORT}:${var.aurora_cluster_writer_endpoint}:5432 \ ${var.jumpbox_ssh_user}@${var.jumpbox_public_ip} & TUNNEL_PID=$! # 注册退出钩子,无论执行成功失败都自动关闭隧道 trap "kill $${TUNNEL_PID} 2>/dev/null || true" EXIT # 等待隧道连通,最多等待30秒 echo "Waiting for SSH tunnel to be ready..." for i in {1..30}; do if nc -z 127.0.0.1 $${LOCAL_TUNNEL_PORT}; then echo "SSH tunnel established successfully" break fi if [ $i -eq 30 ]; then echo "Wait for SSH tunnel timeout, exit" exit 1 fi sleep 1 done # 注入数据库连接环境变量,执行初始化脚本 export PGHOST=127.0.0.1 export PGPORT=$${LOCAL_TUNNEL_PORT} export PGDATABASE=${var.aurora_default_db} export PGUSER=${var.aurora_master_user} export PGPASSWORD=${var.aurora_master_password} bash ${path.module}/pg_queries.sh.tpl EOT } }
pg_queries.sh.tpl 脚本
#!/bin/bash set -euo pipefail echo "Start executing Aurora initialization SQL..." psql -v ON_ERROR_STOP=1 <<EOF -- 以下SQL可根据实际业务需求替换 CREATE USER IF NOT EXISTS app_user WITH ENCRYPTED PASSWORD 'replace_with_your_app_password'; CREATE DATABASE app_db OWNER app_user; \c app_db CREATE EXTENSION IF NOT EXISTS pgcrypto; CREATE EXTENSION IF NOT EXISTS pg_stat_statements; -- 其他用户、库、权限、扩展创建逻辑可追加在此处 EOF echo "All initialization SQL executed completed"
补充说明
- 数据库主账号密码、业务账号密码等敏感信息不要硬编码在代码里,建议通过Terraform敏感变量、云厂商密钥管理服务存储,执行时动态注入
- 如果本地是Windows环境执行,需要把interpreter换成PowerShell或者WSL的bash路径,逻辑保持一致即可
- 如果你的环境已经有VPN或者专线连通生产VPC,也可以直接把Terraform执行机的IP加到Aurora安全组白名单,不需要走跳板机隧道
内容的提问来源于stack exchange,提问作者P_Ar
相关产品推荐
相关产品推荐

