Terraform中基于JSON批量创建关联AWS资源的实现问题
实现Terraform关联多资源实例创建(解决count与for_each冲突)
需求
- 第一类资源:按JSON文件的每个条目创建
- 第二类资源:依赖第一类资源的ID,且每个JSON条目中的多个email值对应一个实例(即一个第一类资源对应多个第二类资源)
原始数据与基础配置
file.json内容
[ { "name": "one", "env": "dev", "org": "IT", "email": "one@gmail.com, two@gmail.com" }, { "name": "two", "env": "stg", "org": "HR", "email": "three@gmail.com, four@gmail.com, five@gmail.com" } ]
本地变量定义
locals { data = jsondecode(file("${path.module}/file.json")) }
第一类资源(原配置)
resource "aws_sagemaker_domain" "domain" { count = length(local.data) domain_name = local.data[count.index].name }
错误尝试与问题
原第二类资源配置混用count和for_each,触发报错:
resource "aws_sagemaker_user_profile" "user_profile" { count = length(local.data) domain_id = aws_sagemaker_domain.domain[count.index].id for_each = split(",", local.data[count.index].email) user_profile_name = each.value }
the count and for_each meta-arguments are mutually-exclusive, only one should be used to be explicit about the number of resources to be created.
正确实现方式
1. 预处理数据为扁平化结构
先将原始数据展开,每个email对应一个包含所属domain信息的条目,再转换为带唯一键的map:
locals { data = jsondecode(file("${path.module}/file.json")) # 扁平化:拆分每个domain的email,生成单独用户条目 flattened_users = flatten([ for domain in local.data : [ for email in split(", ", domain.email) : { domain_name = domain.name user_email = trimspace(email) } ] ]) # 转换为map,用"domain名-邮箱"作为唯一键,适配for_each user_profile_map = { for user in local.flattened_users : "${user.domain_name}-${user.user_email}" => user } }
2. 优化第一类资源(改用for_each更稳定)
替换count为for_each,用domain的name作为唯一标识,避免条目顺序变动导致资源错误重建:
resource "aws_sagemaker_domain" "domain" { for_each = { for d in local.data : d.name => d } domain_name = each.value.name }
3. 创建第二类资源
遍历预处理后的map,关联对应domain的ID:
resource "aws_sagemaker_user_profile" "user_profile" { for_each = local.user_profile_map domain_id = aws_sagemaker_domain.domain[each.value.domain_name].id user_profile_name = each.value.user_email }
说明
trimspace(email)用于清理split后email字符串的首尾空格,避免无效的用户名称- 用
domain_name关联资源比count.index更可靠,当JSON条目顺序变动时,不会导致资源错误重建
内容的提问来源于stack exchange,提问作者stayft
相关产品推荐
相关产品推荐

