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

创建组织级多区域CloudTrail时遇S3桶策略异常错误排查

问题描述

我正在创建组织级(org level trail)多区域CloudTrail及用于存储日志的S3桶,参考AWS官方文档配置S3桶策略,KMS密钥已授权CloudTrail执行kms:GenerateDataKey*, kms:DescribeKey, kms:Decrypt操作。

以下是我的Terraform代码:

resource "aws_kms_key" "cloudtrail_kms_key" {
  description         = "KMS key for Cloudtrail S3 Bucket"
  enable_key_rotation = true
  multi_region        = true
}

resource "aws_kms_key_policy" "cloudtrail_kms_key_policy" {
  key_id = aws_kms_key.cloudtrail_kms_key.key_id
  policy = jsonencode({
    Version = "2012-10-17",
    Id      = "cloudtrail-kms-key-policy",
    Statement : [
      {
        Sid       = "Enable IAM User Permissions"
        Effect    = "Allow"
        Principal = { AWS = "arn:aws:iam::${var.aws_account_id}:root" }
        Action    = "kms:*"
        Resource  = "*"
      },
      {
        Sid    = "Permitted KMS Key Services"
        Effect = "Allow"
        Principal = {
          Service = ["cloudtrail.amazonaws.com"]
        }
        Action   = ["kms:GenerateDataKey*", "kms:DescribeKey", "kms:Decrypt"]
        Resource = "*",
        "Condition" : {
          "StringEquals" : {
        "aws:SourceArn" : "arn:aws:cloudtrail:${var.aws_region}:${var.aws_account_id}:trail/${var.trail_name}"
      },
      "StringLike": {
         "kms:EncryptionContext:aws:cloudtrail:arn": "arn:aws:cloudtrail:*:${var.aws_account_id}:trail/*"
      }
        }
      }
    ]
  })
}

resource "aws_cloudtrail" "trail" {
  depends_on                 = [aws_s3_bucket_policy.cloudtrail_bucket_policy]
  name                       = var.trail_name
  s3_bucket_name             = aws_s3_bucket.cloudtrail_bucket.id
  is_organization_trail      = true
  is_multi_region_trail      = true
  kms_key_id                 = aws_kms_key.cloudtrail_kms_key.arn
  enable_log_file_validation = true
}

resource "aws_s3_bucket" "cloudtrail_bucket" {
  bucket = "${var.bucket_name}"
}

resource "aws_s3_bucket_ownership_controls" "cloudtrail_bucket_ownership_controls" {
  bucket = aws_s3_bucket.cloudtrail_bucket.id
  rule {
    object_ownership = "BucketOwnerEnforced"
  }
}

# 参考IAM策略文档配置
data "aws_iam_policy_document" "cloudtrail_bucket_policy" {
  statement {
    sid    = "AWSCloudTrailAclCheck"
    effect = "Allow"

    principals {
      type        = "Service"
      identifiers = ["cloudtrail.amazonaws.com"]
    }

    actions   = ["s3:GetBucketAcl"]
    resources = [aws_s3_bucket.cloudtrail_bucket.arn]
    condition {
      test     = "StringEquals"
      variable = "aws:SourceArn"
      values   = ["arn:aws:cloudtrail:${var.aws_region}:${var.aws_account_id}:trail/${var.trail_name}"]
    }
  }

  statement {
    sid    = "AWSCloudTrailWrite"
    effect = "Allow"

    principals {
      type        = "Service"
      identifiers = ["cloudtrail.amazonaws.com"]
    }

    actions   = ["s3:PutObject"]
    resources = ["${aws_s3_bucket.cloudtrail_bucket.arn}/AWSLogs/${var.aws_account_id}/*"]

    condition {
      test     = "StringEquals"
      variable = "s3:x-amz-acl"
      values   = ["bucket-owner-full-control"]
    }
    condition {
      test     = "StringEquals"
      variable = "aws:SourceArn"
      values   = ["arn:aws:cloudtrail:${var.aws_region}:${var.aws_account_id}:trail/${var.trail_name}"]
    }
  }

  statement {
    sid    = "AllowOrganizationTrailToPutObjects"
    effect = "Allow"

    principals {
      type        = "Service"
      identifiers = ["cloudtrail.amazonaws.com"]
    }

    actions   = ["s3:PutObject"]
    resources = ["${aws_s3_bucket.cloudtrail_bucket.arn}/AWSLogs/${var.organization_id}/*"]

    condition {
      test     = "StringEquals"
      variable = "s3:x-amz-acl"
      values   = ["bucket-owner-full-control"]
    }
    condition {
      test     = "StringEquals"
      variable = "aws:SourceArn"
      values   = ["arn:aws:cloudtrail:${var.aws_region}:${var.aws_account_id}:trail/${var.trail_name}"]
    }
  }
}

resource "aws_s3_bucket_policy" "cloudtrail_bucket_policy" {
  bucket = aws_s3_bucket.cloudtrail_bucket.id
  policy = data.aws_iam_policy_document.cloudtrail_bucket_policy.json
}

但始终遇到以下错误:

Error: creating CloudTrail Trail (org-logs): operation error CloudTrail: CreateTrail, https response error StatusCode: 400, RequestID: 42aed73c-100f-43cb-b094-cd5d615bde1e, InsufficientS3BucketPolicyException: 
Incorrect S3 bucket policy is detected for bucket: cloudtrail-production-us-west-2-042518407502-ls (Service: AWSCloudTrail; Status Code: 400; Error Code: InsufficientS3BucketPolicyException; Request ID: 422be9b4-75da-4a97-8012-a80b99a9942a; Proxy: null)

补充说明:我确实在委托管理员账户中部署,这一点没有问题。请问哪里配置错误?


问题分析与修复

你的S3桶策略存在两个关键问题:

  • AWSCloudTrailAclCheck语句缺少组织级Trail的权限:组织级CloudTrail的ARN格式是arn:aws:cloudtrail:*:${var.aws_account_id}:orgtrail/${var.trail_name},当前策略只匹配了普通Trail的ARN,导致权限检查失败。
  • 多区域Trail的源ARN匹配限制过严:多区域Trail发起请求时,源ARN的区域可能和你指定的var.aws_region不一致,使用StringEquals会拒绝跨区域的合法请求,需要改用StringLike匹配任意区域。

修正后的S3桶策略文档

将data "aws_iam_policy_document" "cloudtrail_bucket_policy"替换为以下内容:

data "aws_iam_policy_document" "cloudtrail_bucket_policy" {
  statement {
    sid    = "AWSCloudTrailAclCheck"
    effect = "Allow"

    principals {
      type        = "Service"
      identifiers = ["cloudtrail.amazonaws.com"]
    }

    actions   = ["s3:GetBucketAcl"]
    resources = [aws_s3_bucket.cloudtrail_bucket.arn]
    condition {
      test     = "StringLike"
      variable = "aws:SourceArn"
      values   = [
        "arn:aws:cloudtrail:*:${var.aws_account_id}:trail/${var.trail_name}",
        "arn:aws:cloudtrail:*:${var.aws_account_id}:orgtrail/${var.trail_name}"
      ]
    }
  }

  statement {
    sid    = "AWSCloudTrailWrite"
    effect = "Allow"

    principals {
      type        = "Service"
      identifiers = ["cloudtrail.amazonaws.com"]
    }

    actions   = ["s3:PutObject"]
    resources = [
      "${aws_s3_bucket.cloudtrail_bucket.arn}/AWSLogs/${var.aws_account_id}/*",
      "${aws_s3_bucket.cloudtrail_bucket.arn}/AWSLogs/${var.organization_id}/*"
    ]

    condition {
      test     = "StringEquals"
      variable = "s3:x-amz-acl"
      values   = ["bucket-owner-full-control"]
    }
    condition {
      test     = "StringLike"
      variable = "aws:SourceArn"
      values   = [
        "arn:aws:cloudtrail:*:${var.aws_account_id}:trail/${var.trail_name}",
        "arn:aws:cloudtrail:*:${var.aws_account_id}:orgtrail/${var.trail_name}"
      ]
    }
  }
}

优化说明

  • 合并了原本分开的写入权限语句,减少配置冗余;
  • 用StringLike匹配任意区域的源ARN,适配多区域Trail的跨区域请求;
  • 同时包含trail/和orgtrail/两种ARN格式,覆盖组织级Trail的权限检查需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 06:30:09