【问题标题】:Terraform Plan passing value for list variable on WindowsTerraform Plan 为 Windows 上的列表变量传递值
【发布时间】:2021-07-26 13:22:13
【问题描述】:

在以下 YAML 脚本中,我想将 IP 作为 terraform 变量中的列表传递。该变量已在 Terraform 代码中定义为 List。范围是在 Windows 代理 上的 Azure DevOps 管道内运行此 CLI。运行管道时,它失败并显示以下消息: 这意味着 -var='ips=$(ips)' 未正确传递。 我也试过-var="ips=$(ips)"。 我要分配的值是 ["123.456.111","123.456.222"] 的文本 在这种情况下,如何正确地将参数作为 List 传递?

Terraform中变量ips使用的代码我附在下面。

 - task: CmdLine@2
            displayName: Terraform Plan
            inputs:
              script: terraform plan -input=false -out=tfplan -var='ips=$(ips)'
              workingDirectory: infrastructure/terraform/dev
locals {
   }
  ips           = tolist(toset(var.ips))
  feature_flags = {
    provision_vm      = tobool(var.provision_vm)
    provision_webapp  = tobool(var.provision_webapp)
  }
}

【问题讨论】:

  • 它实际上是说变量ips 没有在根模块中声明,而不是它传递不正确。你的(根)模块是什么样子的?更重要的是,您的variables.tf 看起来如何,它是否有正确的ips 声明?看错误信息我猜不是。
  • 我认为有。在 Ubuntu 机器上我没有这个问题。这是声明: variable "ips" { description = "value" type = list default = [""] } 。有什么建议吗?
  • 变量声明在infrastructure/terraform/dev?您在任务定义中设置了一个工作目录,以便将其视为主模块。看起来这是一个特定阶段/环境的模块。但我只是猜测,如果没有看到infrastructure/terraform 中的实际 Terraform 代码,SO 上的人将无法进一步提供帮助。
  • 是的,infrastructure/terraform/dev 是根目录,包含上面声明的 ips 的 variables.tf
  • 还添加了变量在本地使用的地方。

标签: azure azure-devops yaml terraform


【解决方案1】:

在运行 Terraform 等命令行工具时,务必了解您的命令在到达最终运行的命令的过程中会经过哪些命令行解释器和其他层。

在像 Linux 或 Mac OS X 这样的 Unix 系统上,您的命令行通常会被 bashzsh 这样的 shell 解释。 Unix风格的shell遵循'字符标记要完全按字面解释的字符序列的约定,因此使用-var='foo=bar baz'这样的命令行子字符串,shell将是处理那些'的,将它们删除这个过程,导致发送给程序的最终参数是-var=foo=bar baz,这恰好是 Terraform 期望的该参数的语法,因此它可以工作。

不幸的是,在 Windows 上,约定是相当不同的。您的命令行可能由 Windows 命令解释器 (cmd.exe) 或其他一些解释器(如 PowerShell)处理。每个都有自己处理命令行的约定,这意味着可以根据您使用的解释器对同一命令行进行不同的解释。

为了运行 Terraform,我建议尽可能使用 Windows 命令解释器,因为它的命令行处理规则相对简单:它根本不解释引号,只是将完整的命令行参数传递到程序作为单个字符串。但是,这确实意味着在 Windows 上,像 -var='foo=bar baz' 这样的命令行将传递给 Terraform,完全像这样,而 ' 引号仍然存在,因此命令行解析将失败。 p>

Windows 上的 Terraform 遵循用 C 编写的软件或使用解析命令行的 Windows API 函数使用的典型命令行解析约定,其中一部分约定是使用 " 来指示字符序列,其中空格应该从字面上理解,因此当使用 Windows 命令解释器在 Windows 上运行 Terraform 时,您需要将字符的文字序列括在 " 中,然后用反斜杠转义任何 literal " 字符,给出一些东西像这样:

-var="ips=[\"123.456.111\",\"123.456.222\"]"

由于您打算从自动化工具中的变量填充此值,因此仅当该自动化工具具有自动使用反斜杠转义引号的模式时才有效,否则结果将无效。

像这样在模板化命令行上处理所有不同的解析层可能会非常混乱,因此通常更容易将变量值放在a .tfvars file 中,然后传递文件名在命令行上。在这种情况下,Terraform 将直接解析该文件的内容,而不受命令行解释器的任何干扰,因此您只需要处理 Terraform 自己的语言,而不需要处理额外的分层 shell 语言。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-01-20
    • 1970-01-01
    • 2021-07-25
    • 2016-10-30
    • 1970-01-01
    • 1970-01-01
    • 2019-12-04
    • 2021-09-25
    相关资源
    最近更新 更多