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

Terraform创建CloudTrail时触发AccessDeniedException权限问题求助

CloudTrail创建报错:AccessDeniedException排查与修复

问题概述

使用Terraform创建CloudTrail并将日志存储到S3桶,部署角色为管理员角色,但执行terraform apply时触发以下错误:

Error: creating CloudTrail Trail (audit-logs): operation error CloudTrail: CreateTrail, https response error StatusCode: 400, RequestID: abdc7ed4-22c4-4462-9ff9-4f8bda32e509, api error AccessDeniedException: Access Denied: You do not have permission to operate on this resource.

配置代码

Provider配置

terraform {
  required_version = "~> 1.3, < 1.6"
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"
    }
  }
}

资源配置

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

resource "aws_kms_key_policy" "cloudtrail_kms_key_policy" {
  key_id = aws_kms_key.cloudtrail_kms_key.id
  policy = jsonencode({
    Version = "2012-10-17",
      Id      = "test",
      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"]
            AWS     = "arn:aws:iam::${var.aws_account_id}:root"
          }
          Action   = ["kms:GenerateDataKey*", "kms:Decrypt"]
          Resource = "*",
           "Condition" : {
             "StringEquals" : {
               "aws:SourceArn" : "arn:aws:cloudtrail:${var.aws_region}:${var.aws_account_id}:trail/${var.trail_name}"
           }  
         }
       }
     ]
  })
}

resource "aws_s3_bucket" "cloudtrail_bucket" {
  bucket = "${var.bucket_name}-${var.aws_region}-${var.aws_account_id}-ls"
}

resource "aws_s3_bucket_server_side_encryption_configuration" "cloudtrail_bucket_sse_configuration" {
  bucket = aws_s3_bucket.cloudtrail_bucket.id

  rule {
    apply_server_side_encryption_by_default {
      kms_master_key_id = aws_kms_key.cloudtrail_kms_key.arn
      sse_algorithm     = "aws:kms"
  }
}

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

resource "aws_s3_bucket_versioning" "cloudtrail_bucket_versioning" {
  bucket = aws_s3_bucket.cloudtrail_bucket.id
  versioning_configuration {
    status = "Enabled"
  }
}

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}/prefix/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}"]
    }
  }
}

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
}

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
  s3_key_prefix              = "AWSLogs"
  is_organization_trail      = true
  is_multi_region_trail      = true
  kms_key_id                 = aws_kms_key.cloudtrail_kms_key.arn
  enable_log_file_validation = true
}

错误原因分析与修复方案

1. S3桶策略路径不匹配

CloudTrail配置的s3_key_prefix是AWSLogs,但桶策略中写入权限的资源路径错误地添加了prefix/前缀,导致CloudTrail没有对应路径的写入权限。

修复:将桶策略中的资源路径修改为与s3_key_prefix一致:

resources = ["${aws_s3_bucket.cloudtrail_bucket.arn}/${aws_cloudtrail.trail.s3_key_prefix}/${var.aws_account_id}/*"]

或者直接写死匹配:

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

2. KMS密钥策略条件限制(Trail未创建时ARN不存在)

创建Trail时,Trail的ARN尚未生成,KMS策略中aws:SourceArn的条件会阻止CloudTrail服务访问密钥,导致权限被拒。

修复:

  • 暂时移除aws:SourceArn条件,待Trail创建完成后再添加;
  • 或替换为aws:SourceAccount条件,仅限制账号:
"Condition" : {
  "StringEquals" : {
    "aws:SourceAccount" : "${var.aws_account_id}"
  }  
}
  • 或给部署的管理员角色添加KMS的GenerateDataKey*和Decrypt权限。

3. SSE配置语法错误

原代码中aws_s3_bucket_server_side_encryption_configuration资源缺少闭合括号,会导致S3桶加密配置创建失败,间接引发权限问题。

修复:补充缺失的闭合括号:

resource "aws_s3_bucket_server_side_encryption_configuration" "cloudtrail_bucket_sse_configuration" {
  bucket = aws_s3_bucket.cloudtrail_bucket.id

  rule {
    apply_server_side_encryption_by_default {
      kms_master_key_id = aws_kms_key.cloudtrail_kms_key.arn
      sse_algorithm     = "aws:kms"
    } # 补充apply_server_side_encryption_by_default的闭合
  } # 补充rule的闭合
} # 补充资源的闭合

4. 组织级Trail权限缺失

若设置了is_organization_trail = true,需确保:

  • 当前账号属于AWS组织;
  • 管理员角色拥有organizations:EnableAWSServiceAccess和cloudtrail:CreateTrail权限;
  • 已启用CloudTrail作为组织服务,可通过Terraform添加以下资源:
resource "aws_organizations_aws_service_access_principal" "cloudtrail" {
  service_principal = "cloudtrail.amazonaws.com"
}

并在CloudTrail资源中添加depends_on = [aws_organizations_aws_service_access_principal.cloudtrail]。

内容的提问来源于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 20:44:54