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

Terraform部署CloudWatch Logs目标策略出现参数异常错误的原因

问题:CloudWatch Logs目标策略部署报错「InvalidParameterException: Only one principal block is supported」

错误信息

Error: putting CloudWatch Logs Destination Policy (exp-mgt-connect-kinesis-destination): operation error CloudWatch Logs: PutDestinationPolicy, https response error StatusCode: 400, RequestID: 9ed8bf2f-715a-49eb-aee3-b928f7a3955a, InvalidParameterException: Only one principal block is supported.
│
│ with aws_cloudwatch_log_destination_policy.destination_policy,
│ on main.tf line 128, in resource "aws_cloudwatch_log_destination_policy" "destination_policy":
│ 128: resource "aws_cloudwatch_log_destination_policy" "destination_policy"

对应Terraform代码

resource "aws_kinesis_firehose_delivery_stream" "kinesis_firehose_stream" {
  name        = "exp-mgt-${var.s3_bucket_prefix}-delivery-stream"
  destination = "extended_s3"

  extended_s3_configuration {
    role_arn       = aws_iam_role.firehose_role.arn
    bucket_arn     = "arn:aws:s3:::${var.s3_bucket_name}"
    buffering_size = 64
    prefix         = var.s3_bucket_prefix
  }
}

resource "aws_iam_role" "cwl_to_firehose_role" {
  name = "CWLtoKinesisFirehoseRole"

  # Trusted entities
  assume_role_policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        "Effect": "Allow",
        "Principal": {
           "Service": "logs.us-east-1.amazonaws.com"
        },
        "Action": "sts:AssumeRole"
      }
    ]
  })
}

resource "aws_iam_role_policy" "inline_cloudwatch_policy" {
  name     = "Permissions-Policy-For-CWL"
  role     = aws_iam_role.cwl_to_firehose_role.id

  policy = jsonencode({
    Version: "2012-10-17",
    Statement: [
        {
          Sid: "FirehoseAccess1",
          Effect: "Allow",
          Action: "firehose:ListDeliveryStreams",
          Resource: "*"
        },
        {
          Sid: "Passrole",
          Effect: "Allow",
          Action: "iam:PassRole",
          Resource: aws_iam_role.cwl_to_firehose_role.arn
        },
        {
          Sid: "FirehoseAccess2",
          Effect: "Allow",
          Action: [
                "firehose:DescribeDeliveryStream",
                "firehose:PutRecord",
                "firehose:PutRecordBatch"
            ],
          Resource: aws_kinesis_firehose_delivery_stream.kinesis_firehose_stream.arn
        }
    ]
  })
}

resource "aws_cloudwatch_log_destination" "exp_mgt_destination" {
  name       = "exp-mgt-${var.s3_bucket_prefix}-kinesis-destination"
  role_arn   = aws_iam_role.cwl_to_firehose_role.arn
  target_arn = aws_kinesis_firehose_delivery_stream.kinesis_firehose_stream.arn
}

data "aws_iam_policy_document" "destination_policy" {
  statement {
    effect = "Allow"
    actions = [
      "logs:PutSubscriptionFilter",
    ]

    resources = [
      aws_cloudwatch_log_destination.exp_mgt_destination.arn,
    ]
  }
}

resource "aws_cloudwatch_log_destination_policy" "destination_policy" {
  destination_name = aws_cloudwatch_log_destination.exp_mgt_destination.name
  access_policy    = data.aws_iam_policy_document.destination_policy.json
}

报错原因

问题出在data "aws_iam_policy_document" "destination_policy"这个数据块:

  • 你没有显式指定Principal(权限主体),Terraform的aws_iam_policy_document在未定义Principal时,会默认添加包含当前AWS账户ID的Principal块,但生成的格式不符合CloudWatch Logs目标策略的要求。
  • CloudWatch Logs的目标策略有强制限制:仅支持单个Principal块,且必须明确指定有权创建订阅过滤器的实体(比如账户根用户、IAM角色/用户,或者特定服务)。自动生成的默认Principal格式触发了AWS API的校验错误。

解决方法

修改data "aws_iam_policy_document" "destination_policy",添加明确的单个Principal块,示例如下:

# 先添加获取当前账户ID的数据源(如果需要允许当前账户操作)
data "aws_caller_identity" "current" {}

data "aws_iam_policy_document" "destination_policy" {
  statement {
    effect = "Allow"
    actions = [
      "logs:PutSubscriptionFilter",
    ]

    resources = [
      aws_cloudwatch_log_destination.exp_mgt_destination.arn,
    ]

    # 明确指定允许当前AWS账户根用户操作(根据你的场景调整)
    principals {
      type        = "AWS"
      identifiers = ["arn:aws:iam::${data.aws_caller_identity.current.account_id}:root"]
    }

    # 如果你需要允许CloudWatch Logs服务本身操作,可替换为以下配置
    # principals {
    #   type        = "Service"
    #   identifiers = ["logs.us-east-1.amazonaws.com"]
    # }
  }
}

显式定义单个Principal块后,生成的策略就能符合CloudWatch Logs的要求,解决报错问题。

内容的提问来源于stack exchange,提问作者Brian G

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 18:33:16