terraform - Terraform - 用于不同属性编号的嵌套循环
问题描述
描述
我有以下输入结构 (*.tfvars.json)
{
"projects":[
{
"name":"Project 1",
"gitlab":{
"variables":[
{
"name":"Variable 1",
"value":"Value 1"
}
]
}
}
]
}
解析为以下 tf 变量:
variable "projects" {
type = list(
object({
name = string
gitlab = object({
variables = list(
object({
name = string
value = string
})
)
})
}
项目的数量以及每个项目中的变量数量可能会有所不同,因此定义为列表。
首先,我使用简单的“计数”元参数创建项目(gitlab 提供程序):
resource "gitlab_project" "projects" {
count = length(var.projects)
name = var.projects[count.index].name
(...)
}
但后来我正在努力创建项目的变量。
问题
使用 "count" 不起作用,因为它不支持嵌套;
所以我发现的另一种方法是使用 for-each 循环。
我已经展平了地图:
locals {
project_variables = flatten([
for project in var.projects : [
for variable in project.gitlab.variables : {
project_name = project.name
variable = variable
}
]
])
}
但它仍然没有给我任何东西,因为我没有看到使用唯一属性(如名称)检索创建的项目 ID 的选项,并且项目 ID 是创建变量资源所必需的:
resource "gitlab_project_variable" "project_variables" {
project = gitlab_project.projects[...].id
key = ""
value = ""
}
这似乎是一个相当简单的要求(只是一个使用第一个循环迭代器作为索引来检索项目 ID 的嵌套循环),但我找到的解决方案要么不涵盖这种特殊情况(具有未定义/可变数量的循环中的参数),或者过于复杂......
你们能分享一下如何用 terraform-newbie 解决这样的问题吗?
解决方案
你是对的,你必须扁平化你的projects
,但以不同的方式:
variable "projects" {
type = list(
object({
name = string
gitlab = object({
variables = list(
object({
name = string
value = string
})
)
})
}))
default = [
{
"name":"Project 1",
"gitlab":{
"variables":[
{
"name":"Variable 1",
"value":"Value 1"
}
]
}
},
{
"name":"Project 2",
"gitlab":{
"variables":[
{
"name":"Variable 2",
"value":"Value 2"
},
{
"name":"Variable 3",
"value":"Value 3"
}
]
}
},
]
}
locals {
project_names = distinct([for project in var.projects: project.name])
project_variables = merge([
for project in var.projects:
{
for variable in project["gitlab"]["variables"]:
"${project.name}-${variable.name}" => {
project_name = project["name"]
var_name = variable.name
var_value = variable.value
}
}
]...) # do NOT remove the dots
}
这将给出:
project_variables = {
"Project 1-Variable 1" = {
"project_name" = "Project 1"
"var_name" = "Variable 1"
"var_value" = "Value 1"
}
"Project 2-Variable 2" = {
"project_name" = "Project 2"
"var_name" = "Variable 2"
"var_value" = "Value 2"
}
"Project 2-Variable 3" = {
"project_name" = "Project 2"
"var_name" = "Variable 3"
"var_value" = "Value 3"
}
然后:
resource "gitlab_project" "projects" {
for_each = toset(local.project_names)
name = each.key
(...)
}
resource "gitlab_project_variable" "project_variables" {
for_each = local.project_variables
project = gitlab_project.projects[each.value.project_name].id
key = each.value.var_name
value = each.value.var_value
}
推荐阅读
- c++ - Qt 连接事件到非 QObject 类型
- c - 如何在现实世界中以毫秒为单位测量时间?
- sql - spring data jpa中如何通过不同的列和列数获取数据?
- java - 基于 XSD 的二进制序列化
- google-app-maker - 如何获取用户的名字和姓氏?
- firebase - 如何解决:错误:无法列出 Firebase 项目。有关更多信息,请参阅 firebase-debug.log
- python - 如何将以下数据结构转换为分层数据结构
- sql - SQL 中的动态数据透视:转换失败
- javascript - 条件表单输出 - 使用反应表单
- git - `git log -p`:显示差异或生成补丁?