使用 Terraform 创建 S3 存储桶 ACL 和 S3 策略时访问被拒绝

Mar*_*ark 10 amazon-s3 amazon-web-services terraform terraform-provider-aws

我正在尝试使用 Terraform 创建 S3 存储桶,但不断收到“访问被拒绝”错误。

\n

我有以下 Terraform 代码:

\n
resource "aws_s3_bucket" "prod_media" {\n  bucket = var.prod_media_bucket\n  acl = "public-read"\n}\n\nresource "aws_s3_bucket_cors_configuration" "prod_media" {\n  bucket = aws_s3_bucket.prod_media.id  \n\n  cors_rule {\n    allowed_headers = ["*"]\n    allowed_methods = ["GET", "HEAD"]\n    allowed_origins = ["*"]\n    expose_headers  = ["ETag"]\n    max_age_seconds = 3000\n  }  \n}\n\nresource "aws_s3_bucket_acl" "prod_media" {\n    bucket = aws_s3_bucket.prod_media.id\n    acl    = "public-read"\n}\n\n\nresource "aws_iam_user" "prod_media_bucket" {\n  name = "prod-media-bucket"\n}\n\nresource "aws_s3_bucket_policy" "prod_media_bucket" {\n    bucket = aws_s3_bucket.prod_media.id\n    policy = jsonencode({\n    Version = "2012-10-17"\n    Statement = [\n      {\n        Principal = "*"\n        Action = [\n          "s3:*",\n        ]\n        Effect = "Allow"\n        Resource = [\n          "arn:aws:s3:::${var.prod_media_bucket}",\n          "arn:aws:s3:::${var.prod_media_bucket}/*"\n        ]\n      },\n      {\n        Sid = "PublicReadGetObject"\n        Principal = "*"\n        Action = [\n          "s3:GetObject",\n        ]\n        Effect   = "Allow"\n        Resource = [\n          "arn:aws:s3:::${var.prod_media_bucket}",\n          "arn:aws:s3:::${var.prod_media_bucket}/*"\n        ]\n      },\n    ]\n  })\n}\n\nresource "aws_iam_user_policy" "prod_media_bucket" {\n  user = aws_iam_user.prod_media_bucket.name\n  policy = aws_s3_bucket_policy.prod_media_bucket.id\n}\n\nresource "aws_iam_access_key" "prod_media_bucket" {\n  user = aws_iam_user.prod_media_bucket.name\n}\n
Run Code Online (Sandbox Code Playgroud)\n

每当我运行时,terraform apply我都会收到以下错误:

\n
\xe2\x95\xb7\n\xe2\x94\x82 Error: error creating S3 bucket ACL for prod-media-8675309: AccessDenied: Access Denied\n\xe2\x94\x82       status code: 403, request id: XNW2R0KWFYB3KB9R, host id: CuBMdZSaJJgu+0Rprzlptt7oRsjMxBNNHJPhFq98ROGC9l9BUmfmv5YxYZuxf/V3GJBoiGJKJkg=\n\xe2\x94\x82\n\xe2\x94\x82   with aws_s3_bucket_acl.prod_media,\n\xe2\x94\x82   on s3.tf line 18, in resource "aws_s3_bucket_acl" "prod_media":\n\xe2\x94\x82   18: resource "aws_s3_bucket_acl" "prod_media" {\n\xe2\x94\x82\n\xe2\x95\xb5\n\xe2\x95\xb7\n\xe2\x94\x82 Error: Error putting S3 policy: AccessDenied: Access Denied\n\xe2\x94\x82       status code: 403, request id: XNW60T7SQXW1Y4SV, host id: AyGS46L37yIcI4JwddrjHo4GRF7T9JrnfD8TGNdUhpO5uLOWBbgY3+c4opoQTFc2jRdHtXwkqO8=\n\xe2\x94\x82\n\xe2\x94\x82   with aws_s3_bucket_policy.prod_media_bucket,\n\xe2\x94\x82   on s3.tf line 28, in resource "aws_s3_bucket_policy" "prod_media_bucket":\n\xe2\x94\x82   28: resource "aws_s3_bucket_policy" "prod_media_bucket" {\n\xe2\x94\x82\n
Run Code Online (Sandbox Code Playgroud)\n

运行 Terraform 的帐户具有对所有资源的管理员访问权限。

\n
resource "aws_s3_bucket" "prod_media" {\n  bucket = var.prod_media_bucket\n  acl = "public-read"\n}\n\nresource "aws_s3_bucket_cors_configuration" "prod_media" {\n  bucket = aws_s3_bucket.prod_media.id  \n\n  cors_rule {\n    allowed_headers = ["*"]\n    allowed_methods = ["GET", "HEAD"]\n    allowed_origins = ["*"]\n    expose_headers  = ["ETag"]\n    max_age_seconds = 3000\n  }  \n}\n\nresource "aws_s3_bucket_acl" "prod_media" {\n    bucket = aws_s3_bucket.prod_media.id\n    acl    = "public-read"\n}\n\n\nresource "aws_iam_user" "prod_media_bucket" {\n  name = "prod-media-bucket"\n}\n\nresource "aws_s3_bucket_policy" "prod_media_bucket" {\n    bucket = aws_s3_bucket.prod_media.id\n    policy = jsonencode({\n    Version = "2012-10-17"\n    Statement = [\n      {\n        Principal = "*"\n        Action = [\n          "s3:*",\n        ]\n        Effect = "Allow"\n        Resource = [\n          "arn:aws:s3:::${var.prod_media_bucket}",\n          "arn:aws:s3:::${var.prod_media_bucket}/*"\n        ]\n      },\n      {\n        Sid = "PublicReadGetObject"\n        Principal = "*"\n        Action = [\n          "s3:GetObject",\n        ]\n        Effect   = "Allow"\n        Resource = [\n          "arn:aws:s3:::${var.prod_media_bucket}",\n          "arn:aws:s3:::${var.prod_media_bucket}/*"\n        ]\n      },\n    ]\n  })\n}\n\nresource "aws_iam_user_policy" "prod_media_bucket" {\n  user = aws_iam_user.prod_media_bucket.name\n  policy = aws_s3_bucket_policy.prod_media_bucket.id\n}\n\nresource "aws_iam_access_key" "prod_media_bucket" {\n  user = aws_iam_user.prod_media_bucket.name\n}\n
Run Code Online (Sandbox Code Playgroud)\n

请帮助确定导致此错误的原因。

\n

Mar*_*cin 30

您的代码中存在一些问题:

  1. acl属性aws_s3_bucket已弃用,不应使用。
  2. 你没有aws_s3_bucket_ownership_controls
  3. 你没有aws_s3_bucket_public_access_block
  4. 你缺少相关的depends_on
  5. aws_iam_user_policy无法使用aws_s3_bucket_policy.prod_media_bucket.id(甚至不清楚你想在这里完成什么,所以我从下面的代码中删除了它)。

工作代码是:


resource "aws_s3_bucket" "prod_media" {
  bucket = var.prod_media_bucket
}

resource "aws_s3_bucket_cors_configuration" "prod_media" {
  bucket = aws_s3_bucket.prod_media.id  

  cors_rule {
    allowed_headers = ["*"]
    allowed_methods = ["GET", "HEAD"]
    allowed_origins = ["*"]
    expose_headers  = ["ETag"]
    max_age_seconds = 3000
  }  
}

resource "aws_s3_bucket_acl" "prod_media" {
    bucket = aws_s3_bucket.prod_media.id
    acl    = "public-read"
    depends_on = [aws_s3_bucket_ownership_controls.s3_bucket_acl_ownership]
}

resource "aws_s3_bucket_ownership_controls" "s3_bucket_acl_ownership" {
  bucket = aws_s3_bucket.prod_media.id
  rule {
    object_ownership = "BucketOwnerPreferred"
  }
  depends_on = [aws_s3_bucket_public_access_block.example]
}

resource "aws_iam_user" "prod_media_bucket" {
  name = "prod-media-bucket"
}

resource "aws_s3_bucket_public_access_block" "example" {
  bucket = aws_s3_bucket.prod_media.id

  block_public_acls       = false
  block_public_policy     = false
  ignore_public_acls      = false
  restrict_public_buckets = false
}

resource "aws_s3_bucket_policy" "prod_media_bucket" {
    bucket = aws_s3_bucket.prod_media.id
    policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Principal = "*"
        Action = [
          "s3:*",
        ]
        Effect = "Allow"
        Resource = [
          "arn:aws:s3:::${var.prod_media_bucket}",
          "arn:aws:s3:::${var.prod_media_bucket}/*"
        ]
      },
      {
        Sid = "PublicReadGetObject"
        Principal = "*"
        Action = [
          "s3:GetObject",
        ]
        Effect   = "Allow"
        Resource = [
          "arn:aws:s3:::${var.prod_media_bucket}",
          "arn:aws:s3:::${var.prod_media_bucket}/*"
        ]
      },
    ]
  })
  
  depends_on = [aws_s3_bucket_public_access_block.example]
}
Run Code Online (Sandbox Code Playgroud)

  • 谢谢@Marcin,我已经实现了其他要求,但建议 `depends_on = [ aws_s3_bucket_public_access_block.example ]` 节省了我的时间。 (3认同)
  • 非常干净漂亮+1 (2认同)