微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何遍历 Terraform 中的嵌套对象列表

如何解决如何遍历 Terraform 中的嵌套对象列表

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

main.tf

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 以在数据字段中创建具有多个键值对的 configmap。任何帮助或指示将不胜感激!

解决方法

在本节中,您将使用嵌套的 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 嵌套在一起。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。