带计数的 terraform 嵌套插值 [英] terraform nested interpolation with count
问题描述
使用 terraform 我希望引用文件列表的内容(最终我想使用 archive_file 提供程序将它们压缩起来,但在本文的上下文中这并不重要).这些文件都在同一个目录中,所以我有两个变量:
变量source_root_dir"{类型 = 字符串"description = "包含所有文件的目录"}变量source_files"{类型=列表"description = "要添加到云函数的文件列表.位置相对于 source_root_dir"}
我想使用模板数据提供者来引用文件的内容.鉴于 source_files
中的文件数量可能会有所不同,我需要使用 count
对所有文件执行相同的操作.
感谢
成功了!
现在我想将嵌套字符串插值语法与我的 count
结合起来.因此,我的 terraform 项目现在看起来像这样:
提供者模板"{版本 = 1.0.0"}变量source_root_dir"{类型 = 字符串"description = "包含所有文件的目录"}变量source_files"{类型=列表"description = "要添加到云函数的文件列表.位置相对于 source_root_dir"}数据模板文件"t_file"{count = "${length(var.source_files)}"模板 = "${file("${"${var.source_root_dir}"/"${element("${var.source_files}", count.index)}"}")}"}输出我的输出"{value = "${data.template_file.t_file.*.rendered}"}
是的,它看起来很复杂,但在语法上,它是正确的(至少我认为是这样).但是,如果我运行 init 并应用:terraform 初始化 &&terraform apply -var source_files='["foo", "bar"]' -var source_root_dir='mydir'
我收到错误:
<块引用>错误:data.template_file.t_file:发生 2 个错误:
* data.template_file.t_file[0]:__builtin_StringToInt:strconv.ParseInt:解析mydir":无效语法:
${file("${"${var.source_root_dir}"/"${element("${var.source_files}", count.index)}"}")}
* data.template_file.t_file
我最好的猜测是它将 /
解释为除法运算,因此它试图将 source_root_dir
中的值 mydir 解析为 int.
我已经玩了很多年了,但无法弄清楚.有人可以弄清楚如何使用嵌套字符串插值和 count
来使用模板提供程序引用多个文件的内容吗?
好的,我想我想通了.formatlist
救援
提供者模板"{版本 = 1.0.0"}变量source_root_dir"{类型 = 字符串"description = "包含所有文件的目录"}变量source_files"{类型=列表"description = "要添加到云函数的文件列表.位置相对于 source_root_dir"}当地人{fully_qualified_source_files = "${formatlist("%s/%s", var.source_root_dir, var.source_files)}"}数据模板文件"t_file"{count = "${length(var.source_files)}"模板 = "${file(element("${local.fully_qualified_source_files}", count.index))}"}输出我的输出"{value = "${data.template_file.t_file.*.rendered}"}
应用时:
terraform init &&terraform apply -var source_files='["foo", "bar"]' -var source_root_dir='mydir'
输出:
<块引用>申请完成!资源:添加 0 个,更改 0 个,销毁 0 个.
输出:
我的输出 = [这是 foo 的内容
,
这是栏的内容
]
Using terraform I wish to refer to the content of a list of files (ultimately I want to zip them up using the archive_file provider, but in the context of this post that isn't important). These files all live within the same directory so I have two variables:
variable "source_root_dir" {
type = "string"
description = "Directory containing all the files"
}
variable "source_files" {
type = "list"
description = "List of files to be added to the cloud function. Locations are relative to source_root_dir"
}
I want to use the template data provider to refer to the content of the files. Given the number of files in source_files
can vary I need to use a count
to carry out the same operation on all of them.
Thanks to the information provided at https://stackoverflow.com/a/43195932/201657 I know that I can refer to the content of a single file like so:
provider "template" {
version = "1.0.0"
}
variable "source_root_dir" {
type = "string"
}
variable "source_file" {
type = "string"
}
data "template_file" "t_file" {
template = "${file("${var.source_root_dir}/${var.source_file}")}"
}
output "myoutput" {
value = "${data.template_file.t_file.rendered}"
}
Notice that that contains nested string interpolations. If I run:
terraform init && terraform apply -var source_file="foo" -var source_root_dir="./mydir"
after creating file mydir/foo of course then this is the output:
Success!
Now I want to combine that nested string interpolation syntax with my count
. Hence my terraform project now looks like this:
provider "template" {
version = "1.0.0"
}
variable "source_root_dir" {
type = "string"
description = "Directory containing all the files"
}
variable "source_files" {
type = "list"
description = "List of files to be added to the cloud function. Locations are relative to source_root_dir"
}
data "template_file" "t_file" {
count = "${length(var.source_files)}"
template = "${file("${"${var.source_root_dir}"/"${element("${var.source_files}", count.index)}"}")}"
}
output "myoutput" {
value = "${data.template_file.t_file.*.rendered}"
}
yes it looks complicated but syntactically, its correct (at least I think it is). However, if I run init and apply:
terraform init && terraform apply -var source_files='["foo", "bar"]' -var source_root_dir='mydir'
I get errors:
Error: data.template_file.t_file: 2 error(s) occurred:
* data.template_file.t_file[0]: __builtin_StringToInt: strconv.ParseInt: parsing "mydir": invalid syntax in:
${file("${"${var.source_root_dir}"/"${element("${var.source_files}", count.index)}"}")}
* data.template_file.t_file1: __builtin_StringToInt: strconv.ParseInt: parsing "mydir": invalid syntax in:
${file("${"${var.source_root_dir}"/"${element("${var.source_files}", count.index)}"}")}
My best guess is that its interpreting the /
as a division operation hence its attempting to parse the value mydir in source_root_dir
as an int.
I've played around with this for ages now and can't figure it out. Can someone figure out how to use nested string interpolations together with a count
in order to refer to the content of multiple files using the template provider?
OK, I think I figured it out. formatlist
to the rescue
provider "template" {
version = "1.0.0"
}
variable "source_root_dir" {
type = "string"
description = "Directory containing all the files"
}
variable "source_files" {
type = "list"
description = "List of files to be added to the cloud function. Locations are relative to source_root_dir"
}
locals {
fully_qualified_source_files = "${formatlist("%s/%s", var.source_root_dir, var.source_files)}"
}
data "template_file" "t_file" {
count = "${length(var.source_files)}"
template = "${file(element("${local.fully_qualified_source_files}", count.index))}"
}
output "myoutput" {
value = "${data.template_file.t_file.*.rendered}"
}
when applied:
terraform init && terraform apply -var source_files='["foo", "bar"]' -var source_root_dir='mydir'
outputs:
Apply complete! Resources: 0 added, 0 changed, 0 destroyed.
Outputs:
myoutput = [ This is the content of foo
,
This is the content of bar]
这篇关于带计数的 terraform 嵌套插值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!