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