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

Terraform动态块配置Assume Role Policy失败问题求助

Terraform动态配置Assume Role Policy的Principals问题解决

问题概述

创建AWS IAM角色的Assume Role Policy时,硬编码principals块可正常运行,但通过tfvars传入动态值并使用动态块配置时,系统无法识别对应值,导致策略生成异常。

现有代码

variables.tf

variable "assume_role" {
  description = "Assume example"
  type = map(object({
    sid     = string
    effect  = string
    actions = list(string)
    principals = map(string)
  }))
}

main.tf

data "aws_iam_policy_document" "assume-role-policy" {
  dynamic "statement" {
    for_each = var.assume_role
    content {
      actions = lookup(statement.value, "actions")
      effect  = lookup(statement.value, "effect")
      sid     = lookup(statement.value, "sid")

      # 硬编码方式可正常运行
      # principals {
      #   type        = "Service"
      #   identifiers = ["glue.amazonaws.com"]
      # }

      dynamic "principals" {
        for_each = lookup(statement.value, "principals", {})
        content {
          type        = lookup(principals.value, "type")
          identifiers = lookup(principals.value, "identifiers")
        }
      }
    }
  }
}

resource "aws_iam_role" "instance" {
  name               = "instance_role_example"
  assume_role_policy = data.aws_iam_policy_document.assume-role-policy.json
}

inn.tfvars

assume_role = {
  assume = ({
    sid     = "1010"
    effect  = "Allow"
    actions = ["sts:AssumeRole"]
    principals = {
      type        = "Service"
      identifiers = "glue.amazonaws.com"
    }
  })
}

问题原因

  1. 变量类型定义错误:principals被定义为map(string),但IAM策略中一个Statement可包含多个Principal,且identifiers要求为列表类型,而非单个字符串。
  2. 动态块遍历对象错误:动态块principals的for_each遍历的是单个map对象,而非可迭代的集合(如列表),Terraform无法从单个map生成正确的块内容。
  3. tfvars配置不符合要求:identifiers被赋值为字符串,不符合AWS IAM策略文档中必须为列表的格式。

解决方案

1. 修改变量类型定义(variables.tf)

将principals改为列表嵌套对象的类型,支持多个Principal,同时明确identifiers为列表:

variable "assume_role" {
  description = "Assume example"
  type = map(object({
    sid         = string
    effect      = string
    actions     = list(string)
    principals  = list(object({
      type        = string
      identifiers = list(string)
    }))
  }))
}

2. 调整动态块遍历逻辑(main.tf)

直接遍历statement.value.principals列表,简化取值逻辑:

data "aws_iam_policy_document" "assume-role-policy" {
  dynamic "statement" {
    for_each = var.assume_role
    content {
      actions = statement.value.actions
      effect  = statement.value.effect
      sid     = statement.value.sid

      dynamic "principals" {
        for_each = statement.value.principals
        content {
          type        = principals.value.type
          identifiers = principals.value.identifiers
        }
      }
    }
  }
}

3. 修正tfvars配置(inn.tfvars)

将principals改为列表格式,identifiers改为列表:

assume_role = {
  assume = ({
    sid     = "1010"
    effect  = "Allow"
    actions = ["sts:AssumeRole"]
    principals = [
      {
        type        = "Service"
        identifiers = ["glue.amazonaws.com"]
      }
    ]
  })
}

验证

修改完成后,执行terraform plan即可看到生成的Assume Role Policy包含正确的Principal配置,执行terraform apply可成功创建IAM角色。

内容的提问来源于stack exchange,提问作者Leonardo Arango

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 03:45:38