带计数的 terraform 嵌套插值 [英] terraform nested interpolation with count

查看:21
本文介绍了带计数的 terraform 嵌套插值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆