Terraform能否实现双堡垒机三级连接?求可行方案
在Terraform中实现三级堡垒机跳转(Bastion1 → Bastion2 → 目标实例)的方案
没错,Terraform官方文档里确实只给出了单堡垒机的实现方式,原生并不支持直接配置三级跳转。不过别担心,我们有几种可行的替代方案来覆盖这个场景,下面给你详细拆解:
方案一:借助本地SSH配置+Terraform变量
把多级跳转的逻辑交给本地SSH配置来处理,Terraform只需要引用这个配置即可,操作起来很灵活:
- 先在本地
~/.ssh/config中添加三级跳转规则:
Host bastion1 HostName <bastion1-public-ip> User <bastion1-user> IdentityFile ~/.ssh/your-key.pem Host bastion2 HostName <bastion2-private-ip> User <bastion2-user> IdentityFile ~/.ssh/your-key.pem ProxyJump bastion1 Host target-instance HostName <target-private-ip> User <target-user> IdentityFile ~/.ssh/your-key.pem ProxyJump bastion2
- 在Terraform的
remote-exec或其他provisioner中直接使用这个主机别名:
resource "aws_instance" "target" { # 这里填目标实例的基础配置,比如AMI、实例类型等 provisioner "remote-exec" { connection { type = "ssh" host = "target-instance" user = "<target-user>" private_key = file("~/.ssh/your-key.pem") timeout = "5m" } inline = [ "echo '成功通过双层堡垒机连接到目标实例!'", ] } }
方案二:直接在Terraform中定义嵌套ProxyCommand
如果不想依赖本地SSH配置,也可以直接在Terraform的connection块里写嵌套的proxy_command,把跳转逻辑完全放在Terraform代码里:
resource "aws_instance" "target" { # 目标实例基础配置... provisioner "remote-exec" { connection { type = "ssh" host = "<target-private-ip>" user = "<target-user>" private_key = file("~/.ssh/your-key.pem") # 先通过Bastion1连到Bastion2,再跳转到目标实例 proxy_command = "ssh -W %h:%p -i ~/.ssh/your-key.pem <bastion2-user>@<bastion2-private-ip> -o ProxyJump='<bastion1-user>@<bastion1-public-ip> -i ~/.ssh/your-key.pem'" timeout = "5m" } inline = [ "echo '通过ProxyCommand实现双层堡垒机跳转成功!'", ] } }
这种方式的好处是不需要修改本地环境,所有逻辑都在Terraform配置中,适合团队协作或者CI/CD场景。
方案三:封装成Terraform模块复用逻辑
如果你的项目中多次需要用到这种三级跳转配置,可以把连接逻辑封装成一个可复用的模块,减少重复代码:
比如创建modules/double-bastion-proxy模块,内部定义好连接配置的输出:
# modules/double-bastion-proxy/main.tf variable "bastion1_public_ip" { type = string } variable "bastion1_user" { type = string } variable "bastion2_private_ip" { type = string } variable "bastion2_user" { type = string } variable "target_ip" { type = string } variable "target_user" { type = string } variable "private_key_path" { type = string } output "connection_config" { type = object({ type = string host = string user = string private_key = string proxy_command = string timeout = string }) value = { type = "ssh" host = var.target_ip user = var.target_user private_key = file(var.private_key_path) proxy_command = "ssh -W %h:%p -i ${var.private_key_path} ${var.bastion2_user}@${var.bastion2_private_ip} -o ProxyJump='${var.bastion1_user}@${var.bastion1_public_ip} -i ${var.private_key_path}'" timeout = "5m" } }
然后在主配置中调用这个模块:
module "double_bastion" { source = "./modules/double-bastion-proxy" bastion1_public_ip = "<bastion1-public-ip>" bastion1_user = "<bastion1-user>" bastion2_private_ip = "<bastion2-private-ip>" bastion2_user = "<bastion2-user>" target_ip = "<target-private-ip>" target_user = "<target-user>" private_key_path = "~/.ssh/your-key.pem" } resource "aws_instance" "target" { # 目标实例基础配置... provisioner "remote-exec" { connection = module.double_bastion.connection_config inline = [ "echo '通过复用模块实现双层堡垒机跳转!'", ] } }
这种方式能让你的代码更整洁,后续修改跳转逻辑只需要更新模块即可,非常适合规模化的项目。
内容的提问来源于stack exchange,提问作者Claudio Saavedra
相关产品推荐
相关产品推荐

