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

问题描述

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

cloud-init 文件包含一些 terraform 需要重写的 shell 脚本,以便它们将变量引用为 $$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 技巧可以使此工作正常进行?

解决方法

有点恶心,但是通过 sed '1d;$d' 管道内容删除了包含heredoc 标记的第一行和最后一行:

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

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

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...