Terraform AWS IAM角色模块重构:多策略输入报错排查
解决Terraform IAM模块接收Terragrunt传入多策略的JSON格式问题
问题根源
你遇到的"policy包含无效JSON策略:不允许前导空格字符"错误,本质是因为:
- 用
list(string)类型接收策略时,传入的格式化JSON(带缩进、换行)会保留多余空格,AWS IAM策略引擎会将这些空格视为非法字符 - 直接用字符串传递JSON时,无法自动处理格式问题,导致验证失败
解决方案
重构模块时,调整变量结构、自动处理JSON格式,同时实现1个IAM角色关联1-10个策略的需求,具体步骤如下:
1. 修正变量定义
将原有的list(string)类型变量,改为带名称的结构化列表,方便for_each唯一标识每个策略,同时支持传入HCL对象或JSON字符串:
# variables.tf variable "iam_policies" { type = list(object({ name = string # 策略唯一名称,用于for_each和资源命名 policy = any # 支持传入HCL对象或格式化JSON字符串 })) description = "传入的IAM策略列表,最多支持10个" validation { condition = length(var.iam_policies) <= 10 && length(var.iam_policies) >= 1 error_message = "策略数量必须在1-10个之间。" } } variable "iam_role_name" { type = string description = "IAM角色名称" }
2. 处理JSON格式并创建IAM策略
使用jsonencode()函数自动将策略内容转换为AWS接受的紧凑JSON格式,同时用策略名称作为for_each的键,避免索引带来的资源重建问题:
# main.tf # 创建IAM托管策略 resource "aws_iam_policy" "custom" { for_each = { for p in var.iam_policies : p.name => p } name = each.value.name description = "Custom policy: ${each.value.name}" # 用jsonencode处理,不管传入的是HCL对象还是格式化字符串,都转成合法JSON policy = jsonencode(each.value.policy) } # 创建IAM角色 resource "aws_iam_role" "main" { name = var.iam_role_name assume_role_policy = jsonencode({ Version = "2012-10-17" Statement = [ { Action = "sts:AssumeRole" Effect = "Allow" Principal = { Service = "ec2.amazonaws.com" # 根据实际场景修改信任主体 } } ] }) } # 关联策略到角色 resource "aws_iam_role_policy_attachment" "custom" { for_each = aws_iam_policy.custom role = aws_iam_role.main.name policy_arn = each.value.arn }
3. Terragrunt调用示例
在Terragrunt配置中,可以灵活传入HCL对象或格式化JSON字符串:
# terragrunt.hcl terraform { source = "../path/to/your/iam-module" } inputs = { iam_role_name = "my-app-role" iam_policies = [ # 传入HCL对象(推荐,更易维护) { name = "s3-read-access" policy = { Version = "2012-10-17" Statement = [ { Effect = "Allow" Action = "s3:GetObject" Resource = "arn:aws:s3:::my-bucket/*" } ] } }, # 传入格式化JSON字符串 { name = "lambda-invoke-access" policy = <<EOF { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "lambda:InvokeFunction", "Resource": "arn:aws:lambda:us-east-1:123456789012:function:my-function" } ] } EOF } ] }
关键说明
jsonencode()会自动移除多余空格、换行,确保生成的JSON符合AWS IAM的格式要求,彻底解决前导空格问题- 用策略名称作为
for_each键,当策略顺序调整时不会触发资源重建,比用列表索引更稳定 - 变量验证规则确保策略数量在1-10个之间,符合需求
内容的提问来源于stack exchange,提问作者Oleksadr S
相关产品推荐
相关产品推荐

