使用 terraform v0.12.9 并使用 template_file 数据源构建文件,我无法使用双美元符号 $$ 将输入 ${data_directory} 视为文字。
寻找以正确方式解决此问题的解决方案,或寻找任何其他建议或解决方法,以帮助创建包含此内容的文件。
我曾尝试使用双美元符号(如下面的代码示例中所示)将此 ${data_directory} 隔离为文件输出中的文字。
这是我尝试使用 terraform 创建 postfix main.cf 文件的代码:
variable "hostname" {
default = "test"
}
variable "domain_name" {
default = "test.com"
}
variable "fn_main_cf" {
default = "main.cf"
}
data "template_file" "main_cf" {
template = <<EOF
##
## Network settings
##
mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128
inet_interfaces = 127.0.0.1, ::1, 120.121.123.124, 2a03:b0a0:3:d0::5e79:4001
myhostname = ${var.hostname}.${var.domain_name}
###
### Outbound SMTP connections (Postfix as sender)
###
smtp_tls_session_cache_database = btree:$${data_directory}/smtp_scache
EOF
}
data "template_cloudinit_config" "main_cf" {
gzip = false
base64_encode = false
part {
filename = "${var.fn_main_cf}"
content_type = "text/cloud-config"
content = "${data.template_file.main_cf.rendered}"
}
}
resource "null_resource" "main_cf" {
triggers = {
template = "${data.template_file.main_cf.rendered}"
}
provisioner "local-exec" {
command = "echo \"${data.template_file.main_cf.rendered}\" > ~/projects/mail-server/files/etc/postfix/${var.fn_main_cf}"
}
}
正如您所看到的,有很多变量并且所有这些都工作正常,但是 ${data_directory} 不应被视为变量而应视为文字,并且应保持在磁盘上的输出文件中。
保存在磁盘上的 main.cf 创建文件中的预期输出应如下所示:
##
## Network settings
##
mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128
inet_interfaces = 127.0.0.1, ::1, 120.121.123.124, 2a03:b0a0:3:d0::5e79:4001
myhostname = test.test.com
###
### Outbound SMTP connections (Postfix as sender)
###
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache
因此 ${data_directory} 不应被 terraform 视为 terraform 变量,而应视为一组字符、文字(常规文本输入)。
运行 terraform plan 带有双美元符号 $$ 的输出如下:
Error: failed to render : <template_file>:11,43-57: Unknown variable; There is no variable named "data_directory".
最佳答案
template_file
在 Terraform 中仍然可用,主要供 Terraform 0.11 用户使用。在 Terraform 0.12 中不需要使用 template_file
,因为它已被另外两个功能取代:
templatefile
function可以直接在语言中呈现外部模板,而无需单独的提供程序和数据源。 local_file
资源也是在磁盘上创建本地文件的更好方法,而不是使用 local-exec
供应商。通过使用 template_file
和 local-exec
在这里,您强制自己应对两个级别的额外转义: Terraform 模板转义以将文字模板放入 template_file
数据源,然后 shell 在您的配置器中转义。这是一种更直接的方式来表示您的模板和文件:
variable "postfix_config_path" {
# Note that for my example this is expected to be the full path
# to the file, not just the filename. Terraform idiom is to be
# explicit about this sort of thing, rather than relying on
# environment variables like HOME.
type = string
}
locals {
postfix_config = <<-EOT
##
## Network settings
##
mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128
inet_interfaces = 127.0.0.1, ::1, 120.121.123.124, 2a03:b0a0:3:d0::5e79:4001
myhostname = ${var.hostname}.${var.domain_name}
###
### Outbound SMTP connections (Postfix as sender)
###
smtp_tls_session_cache_database = btree:$${data_directory}/smtp_scache
EOT
}
resource "local_file" "postfix_config" {
filename = var.postfix_config_path
content = local.postfix_config
}
如
local
提供者文档警告说,Terraform 并不是真正设计用于直接管理本地机器上的文件和其他资源。 local
提供者在不寻常的情况下存在,这可能是其中一种情况,在这种情况下,上述是解决它的合理方法。但请注意,更标准的 Terraform 使用模式是 Terraform 用于启动新的虚拟机,该虚拟机将运行 Postfix 并通过供应商特定的
user_data
传递必要的配置。或 metadata
争论。如果 postfix 服务器与此 Terraform 配置分开管理,那么另一种模式是安排 Terraform 将必要的数据写入共享配置存储(例如 AWS SSM Parameter Store 或 HashiCorp Consul),然后在 postfix 上使用单独的软件服务器读取并更新
main.cf
文件。对于 HashiCorp Consul,单独的软件可能是 consul-template .其他参数存储也存在类似的软件,允许您将单个虚拟机的配置与整体基础架构的配置分离。
关于variables - 如何使用 terraform 创建文件并将变量包含为文字?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58006272/