如何在 terraform 模板文件中执行 bash `for` 循环?

How to do a bash `for` loop in terraform termplatefile?

我正在尝试通过 Terraform templatefile 函数在 AWS SSM 文档中包含一个 bash 脚本。在 SSM 文档的 aws:runShellScript 部分,我有一个带有 @ 符号的 Bash for 循环,似乎在 terraform validate.

期间产生错误

terraform 版本:0.13.5

main.tf 文件中:

resource "aws_ssm_document" "magical_document" {
  name              = "magical_ssm_doc"
  document_type     = "Command"
  document_format   = "YAML"
  target_type       = "/AWS::EC2::Instance"
  content           = templatefile(
    "${path.module}/ssm-doc.yml",
    {
      Foo: var.foo
    }
  )
}

在我的 ssm-doc.yaml 文件中,我遍历了一个数组:

for i in "$\{arr[@]\}"; do
  if test -f "$i" ; then
    echo "[monitor://$i]" >> $f
    echo "disabled=0" >> $f
    echo "index=$INDEX" >> $f
  fi
done

错误:

Error: Error in function call

Call to function "templatefile" failed: ./ssm-doc.yml:1,18-19: Invalid character; This character is not used within the language., and 1 other diagnostic(s).

我尝试转义 @ 符号,例如 \@,但没有帮助。我如何

虽然错误指向 @ 符号是错误的原因,但正是 ${ } 导致了问题,因为这是 Terraform 插值语法,它适用于模板文件也。 As the docs say:

The template syntax is the same as for string templates in the main Terraform language, including interpolation sequences delimited with ${ ... }.

并且 to escape interpolation syntax in Terraform 的方式是使用双美元符号。

for i in "$${arr[@]}"; do
  if test -f "$i" ; then
    echo "[monitor://$i]" >> $f
    echo "disabled=0" >> $f
    echo "index=$INDEX" >> $f
  fi
done

如果您尝试传入参数,例如在问题 Foo 中,插值语法对 templatefile 很有用。此参数可以在 yaml 文件中作为 ${Foo}.

访问

顺便说一下,虽然 this article didn't give the answer 这个问题,但它帮助我更深入地了解 Terraform 通过 templatefile 函数处理不同语言所做的所有工作。它有一些很酷的技巧,可以为不同的场景进行替换以逃避。