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"
解决方案
错误原因分析
- 字段缺失:原代码内层循环逻辑冗余,导致
merge时未正确聚合同组的所有键值对; - 键名错误:原代码用
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 }
代码逻辑说明
- 分组:通过
groupby函数,按customer_env格式的键对原始参数进行分组; - 构造基础对象:每个分组先生成包含
customer字段的基础对象; - 转换属性键:遍历分组内的每个参数,提取路径最后一段作为属性键(如password、userid),对应参数值;
- 合并对象:用
merge将基础对象和属性键值对合并,得到完整的分组对象。
内容的提问来源于stack exchange,提问作者Brian G
相关产品推荐
相关产品推荐

