2

我正在创建 TF 模块,它下载指定的 yaml 文件,然后使用 yamls 作为 k8s configmaps 中数据字段的源。我有一个可行的解决方案来创建具有一个数据键值对(yaml 文件)的多个配置映射,但还需要为每个配置映射添加对多个键值对(yaml 文件)的支持。

主文件

data "http" "config-map" {
  for_each = var.cloud-configmap

  url = format("https://%s", each.value.url)

  request_headers = {
    Accept = "text/plain"
  }
}

resource "kubernetes_config_map" "configmap" {
  for_each = var.cloud-configmap

  metadata {
    name = each.value.name
    namespace = each.value.namespace
  }

  data = {
    "${each.value.data-keyname}" = data.http.config-map[each.key].body
  }
}

变量.tf

variable "cloud-configmap" {
  type = map(object({
    url = string
    name = string
    namespace = string
    data-keyname = string
  }))
  default = {
    "cm1" = {
      url = "someurl.com/file1.yaml"
      name = "cm-name"
      namespace = "test"
      data-keyname = "file1.yml"
    },
    "cm2" = {
      url = "someurl.com/file2.yaml"
      name = "cm-name2"
      namespace = "default"
      data-keyname = "file2.yml"
    }
  }
}

到目前为止,这段代码可以正常工作,但我想将 variables.tf 文件更改为:

variable "cloud-configmap" {
  type = map(object({
    name = string
    namespace = string
    cm-files = list(object({
      url = string
      data-keyname = string 
    }))
  }))
  default = {
    "cm1" = {
      name = "cm-name"
      namespace = "testnamespace"
      cm-files = [{
        url = "someurl.com/file1.yaml"
        data-keyname = "file1.yml"
      },
      {
        url = "someurl.com/file2.yaml"
        data-keyname = "file2.yml"
      }]
    },
    "cm2" = {
      name = "cm-name2"
      namespace = "default"
      cm-files = [{
        url = "someurl.com/file3.yaml"
        data-keyname = "file3.yml"
      },
      {
        url = "someurl.com/file4.yaml"
        data-keyname = "file4.yml"
      }]
    }
  }
}

在此更改之后,我不知道如何遍历对象cm-files的嵌套列表以在数据字段中创建具有多个键值对的配置映射。任何帮助或指示将不胜感激!

4

1 回答 1

2

你会在这个嵌套的 for 循环中做很多事情。鉴于您的可变约束,这是我能够提出的。

  • 将您更新variables.tf到原始问题中的所需状态。该解决方案将该输入用作要求

  • 将您的资源更新http为此。请注意,这将使您的初始设置失败terraform plan,因为这些是虚拟 url,并且 Terraform 在构建此资源时会尝试发出请求。测试 url 外观的一个好方法是locals {}我在这个片段中也有示例块。这个 locals 块不是必需的,但说明了 URL 是如何创建的。

data "http" "config-map" {
  for_each = toset(flatten([
    for cm in var.cloud-configmap : [
      for cm-file in cm.cm-files :
        cm-file.url
    ]
  ]))

  url = format("https://%s", each.key)

  request_headers = {
    Accept = "text/plain"
  }
}

# EXAMPLE showing how the URLs are created
locals {
  urls = toset(flatten([
    for cm in var.cloud-configmap : [
      for cm-file in cm.cm-files :
        format("https://%s", cm-file.url)
    ]
  ]))
}
output "urls" { value = local.urls }
  • 将您的资源更新kubernetes_config_map为此:
resource "kubernetes_config_map" "configmap" {
  for_each = var.cloud-configmap

  metadata {
    name = each.value.name
    namespace = each.value.namespace
  }

  data = {
    for cm-file in each.value.cm-files :
      cm-file.url => cm-file.data-keyname
  }
}

请注意,在每种情况下都使用了 for 循环,并且在这种http情况下 for_each 与 for 嵌套。

于 2021-01-04T23:11:28.140 回答