【问题标题】:Terraform - create and pass files between modules in loopTerraform - 在循环中的模块之间创建和传递文件
【发布时间】:2022-01-02 10:31:16
【问题描述】:

我的 TF 脚本正在创建 k8s 资源并基于 template_file 生成 kubeconfig 文件。
然后我想将其传递给另一个模块(使用 GitLab 提供程序 - 将它们保存为 GitLab 变量)。

到目前为止,我只创建了一个 kubconfig,而且方法非常简单:

data "template_file" "kubeconfig_template" {
  template = "${file("${path.module}/templates/kubeconfig.tpl")}"
  vars     = {...}
}

output "kubeconfig" {
  value = data.template_file.kubeconfig_template.rendered
}

然后传递给 GitLab 模块:

module "gitlab" {
  source = "./gitlab"
  kubeconfig = module.kubernetes.kubeconfig
}

并用作:

resource "gitlab_group_variable" "kubeconfig_var" {
  value     = base64encode(var.kubeconfig)
  ...
}

但是如何为多个文件实现相同的效果呢?

我看到count 也适用于数据,所以我可以定义:

data "template_file" "kubeconfig_templates" {
  count    = length(var.namespaces)
  template = "${file("${path.module}/templates/kubeconfig.tpl")}"
  vars     = {...}
}

但随后output 不支持count,并且我的强制循环“花式”解决方法似乎不起作用:

output "kubeconfigs" {
  value = [
     for namespace in var.namespaces :
     data.template_file.kubeconfig_templates[index(var.namespaces, namespace)].rendered
  ]
}

你知道如何处理这样的话题吗?

【问题讨论】:

  • 我也在查看fileset(),但可能存在依赖问题? (尝试在 Terraform 模块中创建文件之前在 GitLab 模块中创建变量)。
  • 我能问一下为什么您将渲染文件存储为 GitLab 变量而不是将它们存储为工件吗?这感觉像是一种反模式,因为您可能同时运行多个 terraform 管道,这可能会导致您的变量被覆盖,从而导致竞争条件。
  • 听起来您正在创建一个 yml 文件(您的渲染配置),您正在下游作业中使用该文件(可能用于部署到 k8s)。我建议您使用 local_file 资源将渲染的输出保存到本地文件,然后将其存储为工件。当您的下游作业需要部署到 k8s 时,您可以拉取该工件并运行它。在您的项目中使用变量将导致您运行的每个管道都使用这些变量 - 以这种方式在作业/管道之间传递值很可能不是预期用途,因为配置会在管道之间流血。
  • 我同意@Patrick 这个尖叫的反模式,感觉就像你正在将模型视图控制器 (MVC) 设计模式应用于 terraform 代码,你所有的模板都在一个模块上,然后你传递了那些到其他模块;这不是我会为 terraform 选择的设计……您只是在尝试模块,看看有什么可能,还是这是一个真实世界的用例? ... 最好将所有代码(或最小示例)添加到 GitHub 中,我们可以在其中查看此设计。
  • 是的,使用local_file 渲染模板并传递它会更容易,因为您可以遍历作为工件存在的文件。话虽如此,如果这是您真正想做的事情,最好在父配置中使用for_each 块。与其尝试在一个模块调用中循环(并因此遇到输出在这种情况下无法工作的事实),您将多次调用该模块 - 为您生成的每个文件调用一次。然后你会为你的 k8s 部署使用每个链接。

标签: terraform terraform-modules terraform-provider-kubernetes terraform-provider-gitlab


【解决方案1】:

感谢来自 cmets 的 @patric 输入,我已将“template_file”切换为“local_file”,这解决了我的问题。

新形式:

resource "local_file" "kubeconfigs" {
  count    = length(var.namespaces)
  filename = "${var.namespaces[count.index].name}_kubeconfig"

  content = templatefile("${path.module}/templates/kubeconfig.tpl", {
    ...
  })
}

output "generated_kubeconfigs" {
  value = local_file.kubeconfigs
}

传递给 GitLab 模块:

module "gitlab" {
  source = "./gitlab"
  kubeconfigs = concat(module.kubernetes_dev.generated_kubeconfigs,
                       module.kubernetes_stg.generated_kubeconfigs)
}

并用作:

resource "gitlab_group_variable" "group_variables_kubeconfigs" {
  count = length(var.kubeconfigs)
  value = base64encode(var.kubeconfigs[count.index].content)
  ...
}

【讨论】:

    猜你喜欢
    • 2020-05-16
    • 1970-01-01
    • 1970-01-01
    • 2021-10-07
    • 1970-01-01
    • 2019-05-20
    • 2020-09-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多