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

使用Terraform重命名S3 Bucket时删除对象遇AccessDenied问题

问题:Terraform重命名S3 Bucket时删除版本化对象出现AccessDenied错误

尝试通过Terraform重命名S3 Bucket时,操作会自动删除现有Bucket并创建新Bucket,但出现大量AccessDenied错误:

│ Error: emptying S3 Bucket (my-bucket): 
|   deleting S3 Bucket (my-vuxkwr) objects: 1000 errors occurred:
│ * deleting: S3 object (AWSLogs/123456789/elasticloadbalancing/us-west-2/2024/03/15/123456789_elasticloadbalancing_us-west-2_app.my-api.log.gz) version (abcde_fghij.klmno): 
| AccessDenied: Access Denied
# omitted the rest of the AccessDenied errors

我的S3 Bucket Terraform配置如下:

data "aws_caller_identity" "current" {}
data "aws_elb_service_account" "main" {}

locals {
  bucket_arn  = "arn:aws:s3:::${var.bucket_name}"
}

resource "aws_s3_bucket" "main" {
  bucket = var.bucket_name

  force_destroy = true
  
  tags = var.tags
}

resource "aws_s3_bucket_logging" "main" {
  bucket = aws_s3_bucket.main.id

  target_bucket = var.s3_access_logs_bucket_name
  target_prefix = "${var.bucket_name}/"
}

resource "aws_s3_bucket_versioning" "main" {
  bucket = aws_s3_bucket.main.id

  versioning_configuration {
    status = "Enabled"
  }
}

resource "aws_s3_bucket_server_side_encryption_configuration" "main" {
  bucket = aws_s3_bucket.main.id

  rule {
    apply_server_side_encryption_by_default {
      sse_algorithm     = "AES256"
    }
  }
}

resource "aws_s3_bucket_policy" "main" {
  bucket = aws_s3_bucket.main.id
  policy = data.aws_iam_policy_document.bucket_policy.json

  depends_on = [
    aws_s3_bucket.main
  ]
}

data "aws_iam_policy_document" "bucket_policy" {
  statement {
    sid = "RequireSSL"

    effect = "Deny"

    principals {
      type        = "*"
      identifiers = ["*"]
    }

    actions = ["s3:*"]

    resources = [
      local.bucket_arn,
      "${local.bucket_arn}/*",
    ]

    condition {
      test     = "Bool"
      variable = "aws:SecureTransport"
      values = [
        "false"
      ]
    }
  }

  statement {
    sid = "AwsElbServiceAccount"
    actions = [
      "s3:PutObject"
    ]
    resources = [
      "${aws_s3_bucket.main.arn}/*"
    ]
    principals {
      type        = "AWS"
      identifiers = [data.aws_elb_service_account.main.arn]
    }
  }
}

resource "aws_s3_bucket_ownership_controls" "main" {
  bucket = aws_s3_bucket.main.id

  rule {
    object_ownership = "BucketOwnerEnforced"
  }

  depends_on = [
    aws_s3_bucket.main
  ]
}

resource "aws_s3_bucket_public_access_block" "main" {
  bucket = aws_s3_bucket.main.id

  block_public_acls       = true
  block_public_policy     = true
  ignore_public_acls      = true
  restrict_public_buckets = true
}

当前执行Terraform的角色相关权限配置:

data "aws_iam_policy_document" "provision_s3_bucket" {
  statement {
    sid       = "S3Bucket"
    actions   = [
        "s3:DeleteObject", 
        "s3:DeleteObjects",
      ]
    resources = [
        "arn:aws:s3:::*",
      ]
  }
}

明明已经配置了所有S3资源的对象删除权限,为何还会出现AccessDenied错误?


解答

核心原因:版本化Bucket需要专属的删除权限

你的Bucket开启了版本化(aws_s3_bucket_versioning状态为Enabled),对于版本化Bucket中的对象,删除具体对象版本需要的是s3:DeleteObjectVersion和s3:DeleteObjectVersions权限,而非普通的s3:DeleteObject或s3:DeleteObjects。

当前角色仅配置了普通删除权限,这类权限只能用于非版本化Bucket的对象删除,或是给版本化Bucket的对象创建删除标记(Delete Marker),但无法真正删除已存在的对象历史版本。而Terraform的force_destroy = true在清空版本化Bucket时,会尝试删除所有对象版本,因此触发权限不足的错误。

额外验证:Bucket Policy的SSL限制

另外需要确认Terraform执行时是否使用HTTPS连接:你的Bucket Policy中有RequireSSL规则,拒绝所有非HTTPS的S3操作。如果Terraform调用AWS API时用了HTTP,也会触发AccessDenied,但从错误信息看,核心问题还是版本化权限缺失——错误明确指向删除特定对象版本。

解决方法

  1. 补充版本化对象删除权限
    更新角色的IAM策略,添加针对版本化对象的删除权限:
data "aws_iam_policy_document" "provision_s3_bucket" {
  statement {
    sid       = "S3Bucket"
    actions   = [
        "s3:DeleteObject", 
        "s3:DeleteObjects",
        "s3:DeleteObjectVersion",
        "s3:DeleteObjectVersions"
      ]
    resources = [
        "arn:aws:s3:::*",
      ]
  }
}
  1. 临时关闭版本化(仅测试场景推荐)
    如果不需要保留对象历史版本,可以先将Bucket版本化状态设为Suspended,等待Terraform清空Bucket后再重新开启。但此操作会丢失所有历史版本,生产环境不建议使用。

  2. 确认SSL连接配置
    确保Terraform执行环境的AWS配置使用HTTPS(默认已开启,但如果自定义了endpoint需要检查),避免触发Bucket Policy的SSL拒绝规则。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 14:39:52