【问题标题】:Terraform: store the contents of a set of files into a single variableTerraform:将一组文件的内容存储到单个变量中
【发布时间】:2020-02-19 03:10:37
【问题描述】:

如果有帮助,这在 TF V0.12 中 在一个目录中,我有可变数量的单行文件。
我需要以某种方式读取它们的内容,并将它们与换行符连接起来,并将结果存储到一个变量中。 (不是字符串数组) 我知道我可以使用以下方法获取要读取的文件列表:

locals{
  my files=tolist(fileset("${var.file_path}", "**")) }

如果我只有一个文件,我知道我可以通过使用读取内容

locals {
  file_value=file("${var.file_path}\\${local.my_files}") # if there was only a single file
}

但是我的大脑只是转向了棉花,我如何才能进行多次读取,我觉得我应该在空资源中使用计数和连接,但似乎无法解决逻辑问题。 这是正确的道路还是我应该怎么做?

【问题讨论】:

  • 为什么不先使用空资源local_exec并在本地拼接文件?

标签: terraform hcl


【解决方案1】:

我们可以将这个问题分解为三个步骤:

  1. 枚举与所需模式匹配的文件名。
  2. 将每个文件的内容读入内存。
  3. 将所有文件内容连接在一起。

我们可以将上面的内容重新表述为三个局部值表达式,每一个都建立在前一个的基础上:

locals {
  filenames            = fileset(".", "${var.file_path}/**")
  file_contents        = { for fn in local.filenames : fn => file(fn) }
  file_contents_concat = join("\n", local.file_contents)
}

或者,我们可以在一个表达式中一起完成所有这些步骤:

locals {
  file_contents_concat = join("\n", [
    for fn in fileset(".", "${var.file_path}/**") : file(fn)
  ])
}

请注意,在fileset 调用中,我将var.file_path 包含在pattern 参数中而不是path 参数中,因为这样生成的文件路径都将与当前工作目录相关,因此我们可以直接将它们传递给file,而无需在那里重新添加var.file_path

filesetpathpattern 之间的分隔有助于解决将一堆文件镜像到 S3 等情况,在这种情况下,将生成的路径相对于存储桶根目录而不是当前工作目录,但这种映射在这里并不重要,因为文件名根本不会出现在结果中。)

【讨论】:

  • 以这种方式尝试测试我得到错误:main.tf 第 7 行的函数调用错误,在本地:7: filenames = fileset(".", "${var.file_path}/* ")
    |---------------- | var.file_path 为“C:/path/test/” 调用函数“fileset”失败:未能修剪匹配路径():Rel:无法使 C:\path\test\test1.test.txt 相对于..
  • 为糟糕的标记道歉,我今天似乎无法为我格式化
  • 嗯...您的var.file_path 是否包含..?看起来这导致它失败,因为fileset 的合同是在第一个参数中给出的路径下生成路径,但.. 不在. 内。如果您确实需要在父目录中工作,那么您可能需要按照最初的方式编写它,在 path 参数中使用 var.file_path,然后在 file 调用中重新添加它。 (请注意,即使在 Windows 上,Terraform 也使用正斜杠作为路径,因此配置可以在平台之间移植。)
  • 我得到一个错误:file_contents_concat = join("\n", local.file_contents) |---------------- | local.file_contents 是具有 2 个属性的对象
【解决方案2】:

在本地与 null_resource 连接。

resource "null_resource" "concatenate_my_files" {
  provisioner "local-exec" {
    working_dir = "${var.file_path}"
    command = <<EOF
      cat "${local.my_files}" > "${var.concatenated_file_name}"
EOF
  }
}

【讨论】:

    【解决方案3】:

    谢谢@mon,它提醒我我应该永远亲吻

    消除我最终得到的复杂性

    resource "null_resource" "concatenate_my_files" {
      provisioner "local-exec" {
        working_dir = var.file_path
        command = <<EOF
    cat * > my_temp_file
    EOF
      }
    }
    

    然后我可以像以前一样阅读此内容。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-02-23
      • 1970-01-01
      • 2017-04-08
      相关资源
      最近更新 更多