Terraform模块中如何实现带可选Condition的IAM策略语句?
问题解决:Terraform模块中IAM策略Condition条件不生效的修复方案
核心问题分析
你当前的代码中,dynamic "condition"块的for_each逻辑存在错误:当传入单个condition对象时,Terraform无法直接迭代单个对象(for_each要求可迭代的集合类型,比如列表或映射),导致Condition条件被忽略。此外,代码也未考虑多Condition的场景。
修复方案
1. 修正IAM策略文档的动态Condition块
修改data "aws_iam_policy_document"中的dynamic "condition"部分,确保无论是单个Condition对象还是多个Condition的列表,都能被正确迭代:
data "aws_iam_policy_document" "lambda_policy_document" { for_each = { for index, value in local.iam_inline_policy : value.sid => value } statement { sid = each.value.sid effect = each.value.effect actions = each.value.action resources = each.value.resource dynamic "condition" { # 处理单个Condition对象或多Condition列表的情况 for_each = can(each.value.condition) ? ( type(each.value.condition) == list(object({ test = string variable = string values = list(string) })) ? each.value.condition : [each.value.condition] ) : [] content { test = condition.value.test variable = condition.value.variable values = condition.value.values } } } }
2. 完善输入变量的类型定义
为了让模块输入更规范,避免类型错误,更新iam_inline_policy变量的类型定义,明确支持单个Condition对象或多Condition列表:
variable "iam_inline_policy" { type = list(object({ sid = string effect = string action = list(string) resource = list(string) # 可选字段,支持单个Condition对象或多个Condition的列表 condition = optional( union( object({ test = string variable = string values = list(string) }), list(object({ test = string variable = string values = list(string) })) ) ) })) description = "IAM inline policy statements for the Lambda role" }
验证场景
修改后,以下三种输入场景都能正确生成策略:
- 无Condition的语句(如你示例中的
AllowPutEvents) - 单个Condition的语句(如你示例中的
AllowPutUserItem) - 多Condition的语句:
{ sid = "AllowMultiConditionAction" effect = "Allow" action = ["s3:PutObject"] resource = ["arn:aws:s3:::my-bucket/*"] condition = [ { test = "StringEquals" variable = "s3:prefix" values = ["uploads/"] }, { test = "NumericLessThanEquals" variable = "s3:object-size" values = ["10485760"] } ] }
内容的提问来源于stack exchange,提问作者Nevo
相关产品推荐
相关产品推荐

