Terraform使用for_each替代count实现多GCP项目批量开启多API
基于for_each实现GCP多项目批量启用API的Terraform方案
核心逻辑:通过setproduct生成项目与API的所有笛卡尔积组合,再将组合转换为带唯一键的map供for_each使用,完全替代原count实现,同时符合官方弃用复数google_project_services资源后推荐的单资源管理API的规范。
完整实现(关联已有google_project资源场景)
适配你现有逻辑中关联google_project.customer_projects资源的场景:
locals { # 生成项目标识与API的全量组合,可通过toset包装参数自动去重 project_api_combinations = setproduct(var.my_projects, var.apis_customer_projects) # 转换为for_each可用的map,唯一键格式为「项目标识:API名称」,保证全局唯一 project_api_map = { for combo in local.project_api_combinations : "${combo[0]}:${combo[1]}" => { project_key = combo[0] api_name = combo[1] } } } resource "google_project_service" "customer_projects" { for_each = local.project_api_map project = google_project.customer_projects[each.value.project_key].project_id service = each.value.api_name # 可选配置:禁用API时自动删除依赖服务,避免操作报错 disable_dependent_services = true # 可选配置:销毁Terraform资源时保留API启用状态,按需开启 disable_on_destroy = false }
简化场景(直接传入项目ID列表)
如果var.my_projects本身就是已存在的项目ID列表,不需要关联google_project资源管理项目本身,可以简化为以下实现:
locals { project_api_map = { for combo in setproduct(var.my_projects, var.apis_customer_projects) : "${combo[0]}:${combo[1]}" => { project_id = combo[0] api_name = combo[1] } } } resource "google_project_service" "customer_projects" { for_each = local.project_api_map project = each.value.project_id service = each.value.api_name }
相比原count实现的优势
- 不会因为
var.my_projects或var.apis_customer_projects的元素顺序变化、中间插入/删除元素导致资源意外重建,for_each基于唯一键识别资源实例,变更更可控 - 资源实例ID格式为
google_project_service.customer_projects["项目标识:API名"],排查问题时可以直接识别对应的项目和服务,可读性更强 - 符合官方推荐的单API单资源管理逻辑,避免了弃用的
google_project_services资源容易误删非Terraform管理API的问题
内容的提问来源于stack exchange,提问作者Teosch
相关产品推荐
相关产品推荐

