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

OpenTofu变量可用于inline命令,远程执行脚本为何无法读取?

问题原因

OpenTofu对inline命令里的${var.xxx}变量是本地预解析:在发送命令到远程机器前,OpenTofu会先把变量替换成实际值,再将完整的命令字符串传给远程执行,所以远程bash拿到的是已经替换好的内容。

而file provisioner是直接把本地的base.sh文件原封不动传输到远程机器,脚本里的${var.new_root_passwd}这类写法,到了远程bash环境中会被当作bash自身的变量引用,但远程机器根本没定义这些变量,自然会触发「bad substitution」错误。

解决方案

针对这个问题,有三种常用的解决思路:

1. 使用模板生成带变量的脚本

把base.sh改成模板文件,用OpenTofu的templatefile函数在本地替换变量后,再传输到远程:

  • 先创建模板文件scripts/base.sh.tmpl:
#!/bin/bash
echo 'root:${new_root_passwd}' | chpasswd
subscription-manager register --org=XXX --activationkey=${satellite_key} && echo '${satellite_key}' > /opt/activationkey_satellite.txt
  • 修改file provisioner,用templatefile生成内容:
provisioner "file" {
  content     = templatefile("scripts/base.sh.tmpl", {
    new_root_passwd = var.new_root_passwd
    satellite_key   = var.satellite_key
  })
  destination = "/tmp/base.sh"

  connection {
    type          = "ssh"
    user          = var.c_user
    password      = var.d_passwd_user
    host          = var.vm_ip
  }
}

这样传输到远程的base.sh已经是替换好变量的完整脚本,直接运行即可。

2. 通过环境变量传递变量

在remote-exec中先导出环境变量,再用sudo -E保留环境变量运行脚本:

  • 修改remote-exec的inline命令:
provisioner "remote-exec" {
  inline = [
    "echo 'SSH connection successful' > /tmp/1ssh_test_flag",
    "alias sudo='sudo -S <<< ${var.d_passwd_user}'",
    "sudo chmod +x /tmp/base.sh",
    "export NEW_ROOT_PASSWD=${var.new_root_passwd} SATELLITE_KEY=${var.satellite_key}",
    "sudo -E /tmp/base.sh"
  ]
  connection {
    type        = "ssh"
    user        = var.c_user
    password    = var.d_passwd_user
    host        = var.vm_ip
  }
}
  • 调整base.sh,使用环境变量(注意用双引号让bash解析变量):
#!/bin/bash
echo "root:$NEW_ROOT_PASSWD" | chpasswd
subscription-manager register --org=XXX --activationkey=$SATELLITE_KEY && echo "$SATELLITE_KEY" > /opt/activationkey_satellite.txt

3. 以命令行参数传递变量

在运行脚本时直接把变量作为参数传入,脚本内通过位置参数读取:

  • 修改remote-exec的inline命令:
provisioner "remote-exec" {
  inline = [
    "echo 'SSH connection successful' > /tmp/1ssh_test_flag",
    "alias sudo='sudo -S <<< ${var.d_passwd_user}'",
    "sudo chmod +x /tmp/base.sh",
    "sudo /tmp/base.sh ${var.new_root_passwd} ${var.satellite_key}"
  ]
  connection {
    type        = "ssh"
    user        = var.c_user
    password    = var.d_passwd_user
    host        = var.vm_ip
  }
}
  • 调整base.sh,使用位置参数:
#!/bin/bash
NEW_ROOT_PASSWD=$1
SATELLITE_KEY=$2
echo "root:$NEW_ROOT_PASSWD" | chpasswd
subscription-manager register --org=XXX --activationkey=$SATELLITE_KEY && echo "$SATELLITE_KEY" > /opt/activationkey_satellite.txt

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 12:28:13