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" } }) }
问题原因
- 变量类型定义错误:
principals被定义为map(string),但IAM策略中一个Statement可包含多个Principal,且identifiers要求为列表类型,而非单个字符串。 - 动态块遍历对象错误:动态块
principals的for_each遍历的是单个map对象,而非可迭代的集合(如列表),Terraform无法从单个map生成正确的块内容。 - 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
相关产品推荐
相关产品推荐

