You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Terraform字符串映射转对象映射:错误修复与代码优化

问题描述

需要将Terraform变量中扁平的Parameter Store键值对映射,转换为按「客户+环境」分组的嵌套对象结构。

原始variables.tf内容:

variable "parameters" {
  description = "Parameter Store key/values"
  type = map(string)
  default = {
    "/customer1/prod/keycloak/password" = "password123"
    "/customer1/prod/keycloak/realm" = "default"
    "/customer1/prod/keycloak/url" = "https://customer1-sso.app.something.cloud/auth"
    "/customer1/prod/keycloak/userid" = "f:48c1ce1f:monitoring"
    "/customer1/uat/keycloak/password" = "password123"
    "/customer1/uat/keycloak/realm" = "uat"
    "/customer1/uat/keycloak/url" = "https://customer1-sso.npr.app.something.cloud/auth"
    "/customer1/uat/keycloak/userid" = "f:d48d4452:monitoring"
    "/customer1/uat2/keycloak/password" = "password123"
    "/customer1/uat2/keycloak/realm" = "uat2"
    "/customer1/uat2/keycloak/url" = "https://customer1-sso.npr.app.something.cloud/auth"
    "/customer1/uat2/keycloak/userid" = "f:5fe762fd:monitoring"
    "/customer2/prod/keycloak/password" = "password123"
    "/customer2/prod/keycloak/realm" = "default"
    "/customer2/prod/keycloak/url" = "https://customer2-sso.app.something.cloud/auth"
    "/customer2/prod/keycloak/userid" = "f:a053a488:monitoring"
    "/customer2/uat/keycloak/password" = "password123"
    "/customer2/uat/keycloak/realm" = "uat"
    "/customer2/uat/keycloak/url" = "https://customer2-sso.npr.app.something.cloud/auth"
    "/customer2/uat/keycloak/userid" = "f:225118c6:monitoring"
    "/customer2/uat2/keycloak/password" = "password123"
    "/customer2/uat2/keycloak/realm" = "uat2"
    "/customer2/uat2/keycloak/url" = "https://customer2-sso.npr.app.something.cloud/auth"
    "/customer2/uat2/keycloak/userid" = "f:9d8b2d30:monitoring"
  }
}

期望转换后的目标结构:

{
  "customer1_prod" = {
    customer = "customer1"
    password = "password123"
    realm    = "default"
    url      = "https://customer1-sso.app.something.cloud/auth"
    userid   = "f:48c1ce1f:monitoring"
  }
  "customer1_uat" = {
    customer = "customer1"
    password = "password123"
    realm    = "uat"
    url      = "https://customer1-sso.npr.app.something.cloud/auth"
    userid   = "f:d48d4452:monitoring"
  }
  # 其他分组...
}

之前尝试的代码存在两个错误:

  • 每个分组对象仅显示2个字段,而非预期的5个(customer、password、realm、url、userid)
  • 错误生成keycloak = "xxx"字段,正确应为userid = "xxx"
解决方案

错误原因分析

  1. 字段缺失:原代码内层循环逻辑冗余,导致merge时未正确聚合同组的所有键值对;
  2. 键名错误:原代码用split("/", full_key)[3]取到的是路径中的keycloak段,而非最后一段的属性名(如password、userid)——路径/customer/env/keycloak/attr拆分后,数组索引4才是目标属性名。

修正后的简洁实现

使用Terraform的groupby函数直接分组,配合合并逻辑完成转换:

locals {
  customers = {
    for group_key, items in groupby(var.parameters, key => join("_", slice(split(key, "/"), 1, 3))) :
    group_key => merge(
      { customer = split("_", group_key)[0] },
      { for item in items : split(item.key, "/")[4] => item.value }
    )
  }
}

output "all_customers" {
  value = local.customers
}

module "dd_synthetic_browser" {
  source = "./modules/dd_synthetic_browser"
  customers = local.customers
}

代码逻辑说明

  1. 分组:通过groupby函数,按customer_env格式的键对原始参数进行分组;
  2. 构造基础对象:每个分组先生成包含customer字段的基础对象;
  3. 转换属性键:遍历分组内的每个参数,提取路径最后一段作为属性键(如password、userid),对应参数值;
  4. 合并对象:用merge将基础对象和属性键值对合并,得到完整的分组对象。

内容的提问来源于stack exchange,提问作者Brian G

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 08:05:00