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

生产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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 14:09:18