防止 terraform 函数“模板文件”输出 heredoc

Posted

技术标签:

【中文标题】防止 terraform 函数“模板文件”输出 heredoc【英文标题】:Prevent terraform function 'templatefile' from outputting heredoc 【发布时间】:2021-08-16 10:47:27 【问题描述】:

我有一个cloud-init 配置文件,用于使用Terraform 在AWS 中启动VM,我还想使用Multipass 在本地运行以进行测试和调试。

cloud-init 文件包含一些 shell 脚本,Terraform 需要重写这些脚本,以便它们将变量称为 $$var 而不仅仅是 $var。它还使用一个模板变量作为主机名。

为了能够在云端和本地使用相同的配置文件,我想我可以使用以下命令来扩展模板并启动 Multipass VM,而无需手动替换字符串:

terraform console <<< "templatefile(\"cloud-init.yaml\", hostname: \"test\")" | multipass launch -n test --cloud-init -

但事实证明templatefile 函数将其输出包装在heredoc 中:

<<EOT
... contents ...
EOT

Multipass 当然不理解这种语法并打印(相当无用的)错误消息:

launch failed: operator[] call on a scalar (key: "users") 

理想情况下,Terraform 命令应该能够在没有 heredoc 包装器的情况下呈现文件。但是,或者,是否有一个 shell 技巧可以使这个工作?

【问题讨论】:

【参考方案1】:

这有点粗俗,但是通过sed '1d;$d' 传递内容会删除包含heredoc 标记的第一行和最后一行:

terraform console <<< 'templatefile("cloud-init.yaml", hostname: "test")' | sed '1d;$d' | multipass launch -n test --cloud-init -

这当然是脆弱的,例如空白更改可能会破坏标记所在位置的假设。因此,此解决方案应被视为缺乏更好的解决方案。

【讨论】:

以上是关于防止 terraform 函数“模板文件”输出 heredoc的主要内容,如果未能解决你的问题,请参考以下文章

处理 Terraform 模板文件和 Bash 脚本的解析错误

用于 aws 策略列表的 terraform 模板文件

具有自动缩放组的多个模板文件和使用 Terraform 的启动配置

如何使用 terraform 将 aws ec2 私有 ips 传递给模板文件

检查变量是不是存在 - Terraform 模板语法

使用 terraform 输出恢复 Azure ARm 模板的输出值