首页 > 解决方案 > 如何在 terraform termplatefile 中执行 bash `for` 循环?

问题描述

我正在尝试通过 Terraformtemplatefile函数在 AWS SSM 文档中包含一个 bash 脚本。在aws:runShellScriptSSM 文档的部分中,我有一个 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

错误

错误:函数调用错误

调用函数“模板文件”失败:./ssm-doc.yml:1,18-19:无效字符;该字符未在该语言中使用。以及 1 个其他诊断。

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

标签: bashamazon-web-servicesterraformaws-ssm

解决方案


@尽管错误将符号指向错误的原因,但${ }正是导致问题的原因,因为这是 Terraform 插值语法,它也适用于模板文件。正如文档所说

模板语法与主要 Terraform 语言中的字符串模板相同,包括用${ ... }.

在 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

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

顺便说一句,虽然本文没有给出这个确切问题的答案,但它帮助我更深入地了解了 Terraform 为通过该templatefile函数处理不同语言所做的所有工作。它有一些很酷的技巧来进行替换以逃避不同的场景。


推荐阅读