TerraformでS3のウェブサイトホスティングを実装しようとしたら、バケットポリシーがAccess Denied

TerraformでS3のウェブサイトホスティング機能の実装を行っていた際、Access Deniedが発生して、うまくポリシーを設定できなかったので、共有します。


原因1
バケットのACLが`BucketOwnerPreferred`（バケット所有者優先）となっている。
→`BucketOwnerPreferred`から`BucketOwnerEnforced`（バケット所有者の強制）にすることで解決。
　バケットのACLが無効になったため。
　
https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/about-object-ownership.html


原因2
バケット更新しようとしている人が、バケットの所有者のちがう。
```
data "aws_caller_identity" "current" {}
```


エラー内容
```
│ Error: Error putting S3 policy: AccessDenied: Access Denied
│       status code: 403, request id: A6YSY8AX457ASAJ8, host id: 8/WHPzPHv2TZHQ4BfrXiHSFO+6Z28+IPTGsd5k47oIVP9bXzfjrDY1UCkkDkbTNIHQXJ5Mrs8+yAHICRdume+g==
│ 
│   with module.website.aws_s3_bucket_policy.main,
│   on ../modules/website/s3.tf line 30, in resource "aws_s3_bucket_policy" "main":
│   30: resource "aws_s3_bucket_policy" "main" {
│
```

現状
```
// s3

locals {
  demo_bucket_name = "website-test-bucket20230429"
}

resource "aws_s3_bucket" "main" {
  bucket = local.demo_bucket_name

  tags = {
    Name = local.demo_bucket_name
  }
}

resource "aws_s3_bucket_ownership_controls" "main" {
  bucket = aws_s3_bucket.main.id
  rule {
    object_ownership = "BucketOwnerPreferred"　# ここを変える。
  }
}

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

  block_public_acls       = false
  block_public_policy     = false
  ignore_public_acls      = false
  restrict_public_buckets = false
}
resource "aws_s3_bucket_policy" "main" {
  bucket = aws_s3_bucket.main.id
  policy = jsonencode({
    "Version" : "2012-10-17",
    "Statement" : [
      {
        "Sid" : "PublicReadGetObject",
        "Effect" : "Allow",
        "Principal" : "*",
        "Action" : "s3:GetObject",
        "Resource" : "${aws_s3_bucket.main.arn}/*"
      }
    ]
  })
}
resource "aws_s3_bucket_website_configuration" "main" {
  bucket                = aws_s3_bucket.main.id

  index_document {
    suffix = "index.html"
  }
}

```


解決後
```
// s3

locals {
  demo_bucket_name = "website-test-bucket20230429"
}

# アカウント情報を引っ張る。
data "aws_caller_identity" "current" {}

resource "aws_s3_bucket" "main" {
  bucket = local.demo_bucket_name

  tags = {
    Name = local.demo_bucket_name
  }
}

resource "aws_s3_bucket_ownership_controls" "main" {
  bucket = aws_s3_bucket.main.id
  rule {
    object_ownership = "BucketOwnerEnforced"　# ここが変わった。
  }
}

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

  block_public_acls       = false
  block_public_policy     = false
  ignore_public_acls      = false
  restrict_public_buckets = false
}
resource "aws_s3_bucket_policy" "main" {
  bucket = aws_s3_bucket.main.id
  policy = jsonencode({
    "Version" : "2012-10-17",
    "Statement" : [
      {
        "Sid" : "PublicReadGetObject",
        "Effect" : "Allow",
        "Principal" : "*",
        "Action" : "s3:GetObject",
        "Resource" : "${aws_s3_bucket.main.arn}/*"
      }
    ]
  })
}
resource "aws_s3_bucket_website_configuration" "main" {
  bucket                = aws_s3_bucket.main.id
  # ここにバケットの持ち主を追加。
  expected_bucket_owner = data.aws_caller_identity.current.id

  index_document {
    suffix = "index.html"
  }
}
```



以下サイトを参考
https://repost.aws/ja/knowledge-center/s3-access-denied-bucket-policy