如何遍历 Terraform 中的嵌套对象列表
How to iterate through nested list of objects in Terraform
我正在创建 TF 模块,它下载指定的 yaml 文件,然后使用 yaml 作为 k8s configmaps 中数据字段的源。我有使用一个数据键值对(yaml 文件)创建多个 configmap 的有效解决方案,但还需要为每个 configmap 添加对多个键值对(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
}
}
variables.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 {}
块,我在这个代码段中也有。此本地块不是必需的,但说明了 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。
我正在创建 TF 模块,它下载指定的 yaml 文件,然后使用 yaml 作为 k8s configmaps 中数据字段的源。我有使用一个数据键值对(yaml 文件)创建多个 configmap 的有效解决方案,但还需要为每个 configmap 添加对多个键值对(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
}
}
variables.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 {}
块,我在这个代码段中也有。此本地块不是必需的,但说明了 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。