Terraform嵌套循环实现可变属性数量的GitLab项目变量创建
解法
方案1(推荐,规避列表顺序变更导致的资源意外重建)
调整项目资源为for_each创建
将原count创建gitlab项目的逻辑改为用项目名作为唯一键的for_each实现,生成可通过项目名直接索引的资源map:
resource "gitlab_project" "projects" { for_each = { for p in var.projects : p.name => p } name = each.value.name # 其余原有项目配置保持不变 }
生成分层键的扁平化变量映射
将原扁平化逻辑调整为输出全局唯一键的map,适配gitlab_project_variable的for_each要求:
locals { project_variables = { # 用「项目名/变量名」作为全局唯一键,避免重复 for item in flatten([ for project in var.projects : [ for variable in project.gitlab.variables : { project_name = project.name var_key = variable.name var_value = variable.value } ] ]) : "${item.project_name}/${item.var_key}" => item } }
循环创建项目变量
直接通过项目名匹配对应项目ID即可:
resource "gitlab_project_variable" "project_variables" { for_each = local.project_variables project = gitlab_project.projects[each.value.project_name].id key = each.value.var_key value = each.value.var_value # 可按需补充protected、masked等变量属性配置 }
方案2(保留原有count创建项目的逻辑)
如果不想改动现有项目创建逻辑,可在扁平化时携带原项目的列表索引,通过索引匹配项目ID:
locals { project_variables = flatten([ # 遍历项目时同时取索引 for proj_idx, project in var.projects : [ for variable in project.gitlab.variables : { project_index = proj_idx var_key = variable.name var_value = variable.value } ] ]) } resource "gitlab_project_variable" "project_variables" { count = length(local.project_variables) project = gitlab_project.projects[local.project_variables[count.index].project_index].id key = local.project_variables[count.index].var_key value = local.project_variables[count.index].var_value }
注意该方案如果修改var.projects的列表顺序、增删非末尾的项目,会触发索引偏移,可能导致大量无关资源意外重建,仅适合项目列表不会调整顺序的场景。
内容的提问来源于stack exchange,提问作者jarobar435
相关产品推荐
相关产品推荐

