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

如何在PowerShell脚本中使用Terraform变量?Windows环境遇阻

Windows环境下Terraform变量无法注入PowerShell脚本的解决办法

问题背景

原本在Linux(Bash)环境下能用的Terraform传变量到脚本的方案,迁移到Windows(PowerShell)环境后失效了。已经配置了对应的template_file模板,PS1脚本里用$RunnerTags = "${RUNNER_TAGS}"读取变量,部署Windows VM扩展后,变量却没成功注入。

现有代码参考

Linux侧资源配置

resource "azurerm_virtual_machine_extension" "runner_server" {
  count = length(var.runner_vm_name)
  name                 = "runnerSettings"
  virtual_machine_id   = azurerm_linux_virtual_machine.runner_server[count.index].id
  publisher            = "Microsoft.Azure.Extensions"
  type                 = "CustomScript"
  type_handler_version = "2.0"
  
  protected_settings = <<PROT
  {
      "script": "${base64encode(data.template_file.runner_settings.rendered)}"
  }
  PROT
}

模板文件

data "template_file" "runner_settings" {
  template = file("${var.runner_script_file}")
  vars = {
    REGISTRATION_TOKEN  = var.gitlab_runner_reg_token,
    GITLAB_URL          = var.gitlab_url,
    DEPLOY_ENV          = replace(var.resource_name_prefix, "-cicd", ""),
    RUNNER_TAGS    = join(",", var.gitlab_runner_tags)
  }
}

Windows侧PS1读取方式

$RunnerTags = "${RUNNER_TAGS}"

Windows VM扩展配置

resource "azurerm_virtual_machine_extension" "windows_runner_server_ext" {
  count = length(var.windows_runner_vm_name)
  name                 = "Settings"
  virtual_machine_id   = azurerm_windows_virtual_machine.windows_runner_server[count.index].id
  publisher            = "Microsoft.Compute"
  type                 = "CustomScriptExtension"
  type_handler_version = "1.9"
  settings = <<SETTINGS
    {
      "commandToExecute": "powershell -command \"[System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String('${base64encode(data.template_file.windows_runner_settings.rendered)}'))  | Out-File -filepath postBuild.ps1\" && powershell -ExecutionPolicy Unrestricted -File postBuild.ps1'"
    }
SETTINGS
}

问题原因

  1. VM扩展参数转义混乱:Windows的CustomScriptExtension和Linux的CustomScript参数结构不同,手动编写JSON时的引号嵌套、转义符处理错误,导致脚本内容解析异常
  2. 文件编码问题:Out-File默认用ANSI编码保存脚本,模板渲染后的UTF8内容可能乱码,变量无法被识别
  3. PowerShell变量读取逻辑:模板替换后的变量在PS1中被多余的引号包裹,无法正确解析为实际值

修复方案

1. 修正VM扩展配置,解决转义和编码问题

改用jsonencode自动处理JSON转义,同时指定文件编码为UTF8:

resource "azurerm_virtual_machine_extension" "windows_runner_server_ext" {
  count = length(var.windows_runner_vm_name)
  name                 = "Settings"
  virtual_machine_id   = azurerm_windows_virtual_machine.windows_runner_server[count.index].id
  publisher            = "Microsoft.Compute"
  type                 = "CustomScriptExtension"
  type_handler_version = "1.9"

  settings = jsonencode({
    commandToExecute = <<-EOT
      powershell -Command "$([System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String('${base64encode(data.template_file.windows_runner_settings.rendered)}'))) | Out-File -FilePath postBuild.ps1 -Encoding UTF8; powershell -ExecutionPolicy Unrestricted -File postBuild.ps1"
    EOT
  })
}

2. 确认模板文件的变量定义

确保Windows侧的模板定义和Linux侧一致,变量能正确渲染:

data "template_file" "windows_runner_settings" {
  template = file("${var.windows_runner_script_file}")
  vars = {
    REGISTRATION_TOKEN = var.gitlab_runner_reg_token,
    GITLAB_URL         = var.gitlab_url,
    DEPLOY_ENV         = replace(var.resource_name_prefix, "-cicd", ""),
    RUNNER_TAGS        = join(",", var.gitlab_runner_tags)
  }
}

3. 调整PS1脚本的变量读取方式

去掉多余的引号包裹,让模板直接替换为实际变量值:

# 模板渲染后会直接替换${RUNNER_TAGS}为实际标签内容
$RunnerTags = ${RUNNER_TAGS}
# 如果变量包含特殊字符,保留引号也可以,但要确保模板替换正确
# $RunnerTags = "${RUNNER_TAGS}"

4. 备选方案:用环境变量传递变量(更稳定)

如果模板替换还是有问题,直接通过环境变量传值:

  • Terraform扩展配置:
settings = jsonencode({
  commandToExecute = <<-EOT
    setx RUNNER_TAGS "${join(",", var.gitlab_runner_tags)}" && powershell -ExecutionPolicy Unrestricted -File postBuild.ps1
  EOT
})
  • PS1脚本读取:
$RunnerTags = $env:RUNNER_TAGS

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 21:02:03