使用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变量,而应被视为字符,文字(常规文本输入)。
运行地形计划具有双美元符号 $$ 的输出如下:
Error: failed to render : <template_file>:11,43-57: Unknown variable; There is no variable named "data_directory".
答案 0 :(得分:1)
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
或{{1 }}参数。
如果将后缀服务器与该Terraform配置分开进行管理,则另一种模式是安排Terraform将必要的数据写入共享的配置存储(例如AWS SSM参数存储或HashiCorp Consul),然后使用单独的软件在postfix服务器上读取并更新metadata
文件。对于HashiCorp Consul,该单独的软件可能是consul-template。其他参数存储也存在类似的软件,使您可以将单个虚拟机的配置与整个基础架构的配置脱钩。