Terraform为aws_iam_policy条件添加语句时遇缺失分隔符错误
Terraform动态添加IAM策略语句报错修复
问题场景
尝试为aws_iam_policy资源条件性添加第二条KMS权限语句,编写的Terraform代码如下:
variable "s3_buckets" { type = list(string) description = "list of s3 buckets" } variable "kms_key_arns" { type = list(string) description = "List of the ARNs of KMS keys" default = [] } resource "aws_iam_policy" "aws_iam_policy_s3" { name = "s3_policy" policy = jsonencode({ Version = "2012-10-17" Statement = [ { Effect = "Allow" Action = [ "s3:GetObject", "s3:ListBucket" ] Resource = var.s3_buckets }, dynamic "second_statement" { for_each = length(var.kms_key_arns) > 0 ? [1] : [] content { Effect = "Allow" Action = [ "kms:Encrypt", "kms:Decrypt", "kms:ReEncrypt*", "kms:GenerateDataKey*", "kms:DescribeKey" ] Resource = var.kms_key_arns } } ] }) }
执行时抛出如下错误:
Error: Missing item separator │ │ on ..\..\..\..\modules\lambda\main.tf line 59, in resource "aws_iam_policy" "aws_iam_policy_s3": │ 49: Statement = [ │ 50: { │ 51: Effect = "Allow" │ 52: Action = [ │ 53: "s3:GetObject", │ 54: "s3:ListBucket" │ 55: ] │ 56: Resource = var.s3_buckets │ 57: }, │ 58: │ 59: dynamic "statement" { │ │ Expected a comma to mark the beginning of the next item.
使用版本:Terraform v1.5.5(windows_386)、provider registry.terraform.io/hashicorp/aws v5.12.0
错误原因
dynamic块是Terraform的HCL块语法,仅用于生成HCL结构(比如资源内的嵌套块),但jsonencode()函数接受的是Terraform表达式(如列表、对象),不能在jsonencode的对象定义中直接使用dynamic块。Terraform解析时会把dynamic当成列表中的非法元素,从而抛出分隔符缺失的错误。
修复方案
改用列表拼接的方式,通过条件判断动态生成第二个语句,再与原S3语句列表合并。修正后的代码如下:
variable "s3_buckets" { type = list(string) description = "list of s3 buckets" } variable "kms_key_arns" { type = list(string) description = "List of the ARNs of KMS keys" default = [] } resource "aws_iam_policy" "aws_iam_policy_s3" { name = "s3_policy" policy = jsonencode({ Version = "2012-10-17" Statement = concat( # 固定的S3权限语句 [ { Effect = "Allow" Action = ["s3:GetObject", "s3:ListBucket"] Resource = var.s3_buckets } ], # 条件性添加KMS权限语句:当kms_key_arns非空时添加 length(var.kms_key_arns) > 0 ? [ { Effect = "Allow" Action = [ "kms:Encrypt", "kms:Decrypt", "kms:ReEncrypt*", "kms:GenerateDataKey*", "kms:DescribeKey" ] Resource = var.kms_key_arns } ] : [] ) }) }
代码说明
- 使用
concat()函数将固定语句列表和动态生成的语句列表合并 - 通过三元表达式
length(var.kms_key_arns) > 0 ? ... : []判断:当kms_key_arns有值时,返回包含KMS语句的列表;否则返回空列表,实现条件性添加
内容的提问来源于stack exchange,提问作者LP13
相关产品推荐
相关产品推荐

