如何通过map(map(object))变量为多个IAM角色创建多Terraform策略?
问题分析与解决方案
错误原因
你硬编码引用statement.role1.first.value是完全错误的:
dynamic "statement"块的for_each = var.policy是遍历外层的角色Map(比如role1),此时statement代表的是单个角色对应的内层Statement集合,不存在role1这个属性。- 你的需求是每个角色对应一个独立IAM策略,每个策略包含该角色下的所有Statement,但原代码只生成了一个策略,且遍历逻辑完全不符合嵌套Map的结构。
修正后的代码
variable.tf(保持不变)
variable "policy" { description = "Policy statement example" type = map(map(object({ sid = string effect = string actions = list(string) resources = list(string) })) ) default = { "key" = { "key" = { actions = [ "value" ] effect = "value" resources = [ "value" ] sid = "value" } } } }
main.tf(修正遍历逻辑)
# 为每个角色生成专属的策略文档 data "aws_iam_policy_document" "role_policy" { for_each = var.policy dynamic "statement" { # 遍历当前角色下的所有Statement for_each = each.value content { sid = statement.value.sid effect = statement.value.effect actions = statement.value.actions resources = statement.value.resources } } } # 为每个角色创建对应的IAM策略 resource "aws_iam_policy" "role_policy" { for_each = var.policy name = "${each.key}-policy" description = "IAM策略:${each.key}" policy = data.aws_iam_policy_document.role_policy[each.key].json }
var.tfvars(保持不变)
policy = { role1 ={ first = ({ sid = "1010" effect = "Allow" actions = ["EC2:*", "iam:*"] resources = ["*"] }), second = ({ sid = "2020" effect = "Allow" actions = ["logs:*","glue:*"] resources = ["*"] })} }
关键修正点
- 双层遍历逻辑:
- 外层通过
for_each = var.policy遍历所有角色,为每个角色单独生成策略文档和IAM策略资源。 - 内层在策略文档中通过
for_each = each.value遍历当前角色下的所有Statement,自动生成Policy中的多条语句。
- 外层通过
- 正确引用属性:直接通过
statement.value.xxx获取Statement的属性,无需lookup(你的变量定义中所有属性都是必填项)。
内容的提问来源于stack exchange,提问作者Leonardo Arango
相关产品推荐
相关产品推荐

