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

如何用Terraform遍历JSON数组创建AWS IAM用户?

解决Terraform遍历JSON用户列表创建IAM用户的语法错误

问题场景

我有一个包含用户和组列表的JSON文件(数组结构),想要通过Terraform在AWS IAM中批量创建用户,但执行terraform plan时遇到以下错误:

Error: Error in function call
│ 
│   on locals.tf line 3, in locals:
│    3:   json_data  = merge([for f in local.json_files : jsondecode(file("${path.module}/input/${f}"))]...)
│     ├────────────────
│     │ local.json_files is set of string with 1 element
│     │ path.module is "."
│ 
│ Call to function "merge" failed: arguments must be maps or objects, got "tuple".

JSON文件示例(偏好的原结构):

[
  { "name": "user1", "groups": ["Admins", "DevOps"], "policies": [] },
  { "name": "user2", "groups": ["DevOps"], "policies": [] }
]

原Terraform代码:

locals {
  json_files = fileset("${path.module}/input/", "*.json")
  json_data  = merge([for f in local.json_files : jsondecode(file("${path.module}/input/${f}"))]...)
}

resource "aws_iam_user" "create_new_users" {
  for_each = local.json_data
  name     = each.name
}

注:我曾将JSON改为键值对结构(如下)让代码正常运行,但更希望保留原数组结构:

{
  "user1": {"groups": ["Admins","DevOps"],"policies": []},
  "user2": {"groups": ["DevOps"],"policies": []}
}

对应的资源代码:

resource "aws_iam_user" "create_new_users" {
  for_each = local.json_data
  name     = each.key
}

解决方案

错误原因

merge函数仅接受映射(map)或对象(object)作为参数,但原JSON解析后得到的是元组(tuple/数组),直接传入merge会触发报错。同时Terraform的for_each仅支持映射或集合类型,因此需要将数组转换为以用户名为键的映射,才能满足使用要求。

修改后的Terraform代码

1. 调整局部变量定义

读取JSON数组并转换为以用户名为键的映射:

locals {
  json_files = fileset("${path.module}/input/", "*.json")
  # 读取所有JSON文件并合并为一个用户数组(支持多文件场景)
  user_list = flatten([
    for f in local.json_files : jsondecode(file("${path.module}/input/${f}"))
  ])
  # 将数组转换为以用户名为键的映射
  user_map = {
    for user in local.user_list : user.name => user
  }
}
  • flatten用于处理多JSON文件场景,将多个文件的数组合并为一个大数组
  • for user in local.user_list : user.name => user 遍历用户数组,生成键为用户名、值为用户完整对象的映射

2. 更新IAM用户资源

使用转换后的user_map作为for_each的数据源:

resource "aws_iam_user" "create_new_users" {
  for_each = local.user_map
  name     = each.key # 也可以用 each.value.name,结果一致
}

3. 可选:批量关联用户到IAM组

如果需要同时将用户加入指定组,可以添加以下资源:

resource "aws_iam_user_group_membership" "user_groups" {
  for_each = local.user_map
  user     = each.key
  groups   = each.value.groups
}

说明

  • 原修改JSON结构的方案可行,是因为直接生成了Terraformfor_each支持的映射类型;而保留原数组结构的关键是通过Terraform的for表达式完成数组到映射的转换。
  • 需确保JSON中每个用户的name字段唯一,否则转换映射时会出现键冲突,Terraform会直接报错提示重复键。

内容的提问来源于stack exchange,提问作者Stephan Du Toit

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 05:03:36