【问题标题】:How to iterate through nested list of objects in Terraform如何遍历 Terraform 中的嵌套对象列表
【发布时间】:2021-04-10 15:06:51
【问题描述】:

我正在创建 TF 模块,它会下载指定的 yaml 文件,然后将 yamls 用作 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 以在数据字段中创建具有多个键值对的配置映射。任何帮助或指点将不胜感激!

【问题讨论】:

    标签: terraform terraform-provider-kubernetes


    【解决方案1】:

    在这一节中,您将使用嵌套的 for 循环做很多事情。考虑到您的变量约束,这是我能想到的。

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

    • 将您的 http 资源更新为此。请注意,这将使您的初始 terraform plan 失败,因为这些是虚拟 url,并且 Terraform 在构建此资源时会尝试发出请求。 测试 url 外观的一个好方法是示例 locals {} 块,我在这个 sn-p 中也有。这个 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 嵌套。

    【讨论】:

    • 谢谢,这很有帮助,一切正常。刚刚将最后一行调整为:cm-file.data-keyname => data.http.config-map[cm-file.url ].body 获取 configmap 中的 yaml 文件的正文。
    猜你喜欢
    • 2019-08-08
    • 2021-11-27
    • 2020-12-27
    • 2022-01-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多