CloudFrontログを別のAWSアカウントのS3バケットに出力する

CloudFrontログを別のAWSアカウントのS3バケットに出力する手順をまとめました。
2019.06.30

西澤です。もう1年程前のことだったのですが、CloudFrontログを別のAWSアカウントのS3バケットに出力する方法について調べることがあり、ブログに書けていなかったので、改めて振り返りつつ記事に残すことにしました。

やりたいこと

AWSアカウントAが所有しているCloudFrontのログを、AWSアカウントBのS3バケットに出力する為の手順について調査しました。

予備知識

サービスの歴史的な経緯なのか、世界中にエッジロケーションがあるという都合からなのか、CloudFrontのアクセスログを出力するバケットでは、バケットポリシーやIAMによる制御ができないのか、バケットACLへの許可設定が必要となります。

CloudFrontがログを書き込むときには、awslogsdelivery(awsdatafeedsとの記載だったこともあるようです)というIDでS3バケットにアクセスされますので、こちらの正規ユーザIDに対して、書き込み許可を与える必要があります。正規ユーザID(Canonical User ID)というのは、あまり耳慣れない方も多いのではないかとおもいますが、他のサービスとは許可設定の方式が違う点にご注意ください。

設定手順

上記を踏まえて、以下のような順番で設定を行います。AWS Management Consoleから設定を行う場合、設定変更時にバケットに対してACL権限追加を試みるような動きのようです。"やりたいこと"に書いた通り、CloudFrontの持ち主がA、そのログの出力先であるS3バケットの持ち主がBと想定して、以下に手順をまとめました。

1. AWSアカウントAのCanonical User IDを確認

Canonical User IDは、S3コンソールのACL設定から参照するか、ListBucket APIを利用します。AWS CLIだとこんな感じで確認することができます。

$ aws s3api list-buckets --query "Owner"
{
    "DisplayName": "cm-awsteam-nishizawa.tetsunori",
    "ID": "e7ddxxxx5523xxxxba1axxxxb7efaxxxx1b25xxxx1aaaxxxxba93xxxxca8fa"
}

2. AWSアカウントBの出力先ログバケットにてアクセス許可

AWSアカウントBのバケットACL設定にて、前項の手順で確認したAWSアカウントAのCanonical User IDに対して、バケットのアクセス権限の読み取り、書き込みを許可しておきます。

3. AWSアカウントAのCloudFrontディストリビューションにてログ出力設定

AWSアカウントAでCloudFrontのディストリビューションにてログ出力設定を行います。Bのログバケット名([ログバケット名].s3.amazonaws.com)を指定して保存します。

Loggingが既にOnだった場合には、一旦Offにした後、改めてOnにする必要があるようですが、この操作をすることで、AWSマネージメントコンソールから、対象ログバケットに対してCanonical User IDへのアクセス許可設定が自動的に追加されます。

4. AWSアカウントBのバケットACL確認

正常に設定が完了すると、BのログバケットのBucketACLに、CloudFrontログ(awsdatafeeds=固定のCanonical User ID)からのFullControl許可が自動的に追加されます。

まとめ

今回の手順を確認したことで、結果的にAWSマネージメントコンソール側で内部的に行ってくれている処理の内容についての理解が深まりました。いろいろなマネージドサービスのログがありますが、必要な初期設定がそれぞれ少しずつ違ったりするので、注意した方が良さそうです。

どこかの誰かのお役に立てば嬉しいです。