首页 > 解决方案 > Terraform:循环目录以创建单个资源

问题描述

我正在尝试使用 Terraform 创建单个 GCP 工作流(此处为 Terraform 工作流文档)。为了创建工作流,我使用 YAML 中的工作流语法(也可以是 JSON)定义了所需的步骤和执行顺序。

我有大约 20 个不同的工作,每个工作都在.yaml同一个文件夹下的不同文件中,workflows/. 我只想遍历/workflows文件夹并拥有一个.yaml文件来创建我的资源。使用 Terraform 实现这一目标的最佳方法是什么?我读过,for_each但它主要用于循环创建多个资源而不是单个资源。

工作流/job-1.yaml

- getCurrentTime:
    call: http.get
    args:
        url: https://us-central1-workflowsample.cloudfunctions.net/datetime
    result: currentDateTime

工作流/job-2.yaml

- readWikipedia:
    call: http.get
    args:
        url: https://en.wikipedia.org/w/api.php
        query:
            action: opensearch
            search: ${currentDateTime.body.dayOfTheWeek}
    result: wikiResult

主文件

resource "google_workflows_workflow" "example" {
  name          = "workflow"
  region        = "us-central1"
  description   = "Magic"
  service_account = google_service_account.test_account.id
  source_contents = YAML FILE HERE

标签: terraform

解决方案


Terraform 有一个功能fileset,它允许配置对磁盘上可用的文件及其定义做出反应。您可以以此为起点,为 构建合适的表达式for_each

locals {
  workflow_files = fileset("${path.module}/workflows", "*.yaml")
}

由于远程系统的设计,您似乎还需要为每个工作流指定一个单独的名称,因此您可能决定将名称设置为与文件名相同但.yaml删除后缀,像这样:

locals {
  workflows = tomap({
    for fn in local.workflow_files :
    substr(fn, 0, length(fn)-5) => "${path.module}/workflows/${fn}"
  })
}

这使用for表达式将文件名集投影到从工作流名称(修剪文件名)到特定文件路径的映射中。结果将如下所示:

{
  job-1 = "./module/workflows/job-1.yaml"
  job-2 = "./module/workflows/job-2.yaml"
}

这现在满足 的要求for_each,因此您可以直接将其称为for_each表达式:

resource "google_workflows_workflow" "example" {
  for_each = local.workflows

  name            = each.key
  region          = "us-central1"
  description     = "Magic"
  service_account = google_service_account.test_account.id
  source_contents = file(each.value)
}

您的问题没有包含有关如何填充description参数的任何定义,因此我将其设置为硬编码"Magic",如您的示例中所示。为了用一些合理的东西填充它,你需要有一个额外的数据源,因为我上面写的已经充分利用了我们从扫描目录内容中获得的信息。


推荐阅读