You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 08:29:57