Terraform配置aws_iam_role内联策略报无效JSON策略错误
报错根因
核心问题是对file()函数读取到的成品JSON字符串额外调用了jsonencode(),造成策略内容被双重JSON编码,AWS IAM服务端收到的是带转义符的纯字符串,而非结构化的合法策略JSON对象,因此触发无效策略报错。
file()方法读取本地.json策略文件时,返回值本身就是符合JSON语法的字符串,完全匹配IAM策略参数的格式要求- 外层嵌套
jsonencode()会将上述JSON字符串作为普通文本值再次序列化,最终传入参数的内容会变成被转义包裹的字符串(例如原始内容{"a":"b"}会被编码为"{\"a\":\"b\"}"),不符合IAM对策略的结构要求 - 你观察到
assume_role_policy用相同写法可以正常运行,是因为部分版本的AWS Provider对信任策略的校验存在容错逻辑,不代表该写法正确,实际上当前信任策略的配置也存在同样的双重编码问题,只是未触发校验拦截。
修复方法
直接移除两处多余的jsonencode()包装即可,修正后的配置如下:
resource "aws_iam_role" "test_role" { name = "my_test_role" assume_role_policy = file("..//Policies//policy_assume_role.json") inline_policy { name = "inline_s3_policy" policy = file("..//Policies//policy_s3_bucket.json") } }
补充说明
如果后续需要向策略中动态传入变量、拼接资源ARN,才需要使用jsonencode(),这种场景下不要直接读取静态JSON文件,而是将策略定义为可序列化的HCL结构,示例写法:
resource "aws_iam_role" "test_role" { name = "my_test_role" assume_role_policy = file("..//Policies//policy_assume_role.json") inline_policy { name = "inline_s3_policy" policy = jsonencode({ Version = "2012-10-17" Statement = [ { Effect = "Allow" Action = ["s3:ListBucket", "s3:GetObject"] Resource = ["${var.s3_bucket_arn}", "${var.s3_bucket_arn}/*"] } ] }) } }
内容的提问来源于stack exchange,提问作者Ryan
相关产品推荐
相关产品推荐

