🚀

【Terraform】CloudFrontのログ用S3はACLを有効にしておく必要がある

2025/01/04に公開

Terraform で CloudFront を構築したときに、アクセスログ用 S3 バケットを作成しました。

その過程でACL 関係のエラーが出たため、記事に残しておきます。

ゴール

Terraform を使用して、CloudFront のアクセスログを S3 バケットに保存するようにしたい

現在の CloudFront と S3 の定義

アクセスログ周りの設定のみ抜粋しています

# CloudFrontを定義
resource "aws_CloudFront_distribution" "main" {

  ...

  # アクセスログの設定
  logging_config {
    bucket = aws_s3_bucket.CloudFront_log.bucket_domain_name
    # Cookieをログに含めるか
    include_cookies = false
    prefix = "CloudFront/"
  }
}

# CloudFrontのアクセスログ格納用バケット
resource "aws_s3_bucket" "CloudFront_log" {
  bucket = "bucket_name"
}

エラーの内容を確認

terraform apply したところ、以下のエラーが出ました。

| Error: creating CloudFront Distribution: InvalidArgument: The S3 bucket that you specified for CloudFront logs does not enable ACL access: bucket-name.s3.amazonaws.com
│       status code: 400, request id: 2d97ae7f-d295-4bb5-b8c9-72cfd857c977
│
│   with aws_CloudFront_distribution.main,
│   on CloudFront.tf line 2, in resource "aws_CloudFront_distribution" "main":2: resource "aws_CloudFront_distribution" "main" {

DeepL さんに翻訳してもらうと

InvalidArgument(無効な引数)です: CloudFront のログに指定した S3 バケットが ACL アクセスを有効にしていない

ということらしい。

S3 バケットの ACL を有効にしないといけない??

もう少し深く調べてみる

https://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/AccessLogs.html#AccessLogsBucketAndFileOwnership

こちらの AWS ドキュメントをみても、

2023 年 4 月以降、CloudFront 標準ログに使用される新しい S3 バケットの S3 アクセスコントロールリスト (ACL) を有効にする必要があります。

とありますね。

ACL の種類は下記を参照ください

https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/acl-overview.html#canned-acl

外部のユーザーがアクセスログを見る機会は今回考えないので、private の ACL を設定していきます。

ソースコード修正

Terraform のドキュメント内に private ACL のサンプルコードがあったので、そのまま使います

https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_acl#with-private-acl

ログ格納用 S3 バケットを下記のように定義します。

# CloudFrontのアクセスログ格納用バケット
resource "aws_s3_bucket" "CloudFront_log" {
  bucket = "bucket_name"
}

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

# ACLを設定
resource "aws_s3_bucket_acl" "CloudFront_log" {
  depends_on = [ aws_s3_bucket_ownership_controls.CloudFront_log ]

  bucket = aws_s3_bucket.CloudFront_log.id
  acl    = "private"
}

これで無事に terraform apply が通ったので、動作確認をしていきます。

動作確認

CloudFront のドメインにアクセスし、ログ格納用の S3 バケットを確認してみると。。。

こんな感じでアクセスログが保存されていると思います。

ちなみに、ファイルの中身はこんな感じ。

#Version: 1.0
#Fields: date time x-edge-location sc-bytes c-ip cs-method cs(Host) cs-uri-stem sc-status cs(Referer) cs(User-Agent) cs-uri-query cs(Cookie) x-edge-result-type x-edge-request-id x-host-header cs-protocol cs-bytes time-taken x-forwarded-for ssl-protocol ssl-cipher x-edge-response-result-type cs-protocol-version fle-status fle-encrypted-fields c-port time-to-first-byte x-edge-detailed-result-type sc-content-type sc-content-len sc-range-start sc-range-end
2023-05-31	13:30:52	NRT57-P2	618	106.72.141.98	GET	d1kd24m158ozez.CloudFront.net	/index.html	200	-	Mozilla/5.0%20(Windows%20NT%2010.0;%20Win64;%20x64)%20AppleWebKit/537.36%20(KHTML,%20like%20Gecko)%20Chrome/113.0.0.0%20Safari/537.36	-	-	Miss	pggzE1uGfDC1vR-mofZufqeqrEkXAHmnmmLYNmfWziY-7mIrY0K7ow==	d1kd24m158ozez.CloudFront.net	https	458	0.045	-	TLSv1.3	TLS_AES_128_GCM_SHA256	Miss	HTTP/2.0	-	-	18811	0.045	Miss	text/html	273	-	-
2023-05-31	13:30:52	NRT57-P2	495	106.72.141.98	GET	d1kd24m158ozez.CloudFront.net	/favicon.ico	403	https://d1kd24m158ozez.CloudFront.net/index.html	Mozilla/5.0%20(Windows%20NT%2010.0;%20Win64;%20x64)%20AppleWebKit/537.36%20(KHTML,%20like%20Gecko)%20Chrome/113.0.0.0%20Safari/537.36	-	-	Error	RDpLPtfQWNG3711a5cJ8bGPlNa7q5F8RElnIa5CfC8IXja7_F5H_0w==	d1kd24m158ozez.CloudFront.net	https	143	0.077	-	TLSv1.3	TLS_AES_128_GCM_SHA256	Error	HTTP/2.0	-	-	18811	0.077	Error	application/xml	-	-	-

参考

https://dev.classmethod.jp/articles/CloudFront-access-log-dont-choose-no-acl-s3-bucket/

Discussion