OACを使用してCloudFrontからS3にアクセスする

# はじめに

この記事のゴールは、CloudFrontのOACを用いてS3に接続し、S3のオブジェクトをCloudFront経由で配信することです。

# 全体の流れ

1. プライベートなS3バケット作成
2. 作成したS3バケットにオブジェクト追加
3. CloudFrontのディストリビューション作成（OAC設定）
4. S3バケットにCloudFrontのOACからのオブジェクト取得を許可するポリシー追加
5. CloudFrontのディストリビューションドメインからS3のオブジェクトにアクセスできることを確認

# 前提のお話

## OACとは

正式名称は「Origin Access Control」で、CloudFrontからS3へ接続する際に使用されるコンポーネントです。
OACが出る前は、「Origin Access Identity(OAI)」が使用されていましたが、このOAIではSSE-KMSで暗号化されたバケットには使用できないなどいくつかの制限がありました。
OACはそのようなOAIでは制限されていたことにも対応できるようになっており、AWS公式でもOACの使用が推奨されています。

# 本題

## 1. プライベートなS3バケット作成

![スクリーンショット 2024-02-28 11.46.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3687813/ecdaa56e-067d-7095-676f-66193ee708da.png)

各項目の設定値は以下のようにしました。
ACLを無効にして、パブリックアクセスをすべてブロックすることでプライベートなバケットにしています。
今回、暗号化はSSE-S3を設定していますが、OACはSSE-KMSにも対応していますので、SSE-KMSも選択可能です。

|項目|設定値|
|:-|:-|
|オブジェクト所有者|ACL無効|
|このバケットのブロックパブリックアクセス設定|すべてブロック|
|バケットのバージョニング|無効|
|デフォルトの暗号化|SSE-S3|

## 2. 作成したS3バケットにオブジェクト追加

今回は、`index.html` と `error.html` という2つのHTMLファイルをアップロードしました。

![スクリーンショット 2024-02-28 12.01.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3687813/b5a8558a-cc22-7f2b-fac2-5c7b5ce9669c.png)

## 3. CloudFrontのディストリビューション作成（OAC設定）

オリジンドメインに先ほど作成したS3バケットを指定します。
そして、オリジンアクセスで「Origin access control settings」を選択します。
「Create new OAC」からOACを作成（※）して、それを指定します。

今回は、この他の設定項目はすべてデフォルト値としました。
ちなみに、この作成画面でもOAIは「Legacy access identities」と表記されていますね。

※CloudFrontコンソールのサイドメニュー「セキュリティ > オリジンアクセス」から事前にOACを作成することも可能です。

![スクリーンショット 2024-02-28 12.07.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3687813/7a62ee01-ab3c-d245-3757-4a018d0cc8cd.png)

## 4. S3バケットにCloudFrontのOACからのオブジェクト取得を許可するポリシー追加

CloudFrontディストリビューションを作成すると、下の画像のようにアラートバーが表示されます。
アラートバー内の「ポリシーをコピー」をクリックすると、S3バケットに設定するポリシー（JSON文字列）をコピーできます。
コピーできれば、次にアラートバー内のリンクをクリックするとS3バケット設定画面に遷移します。

![スクリーンショット_2024-02-28_13_27_04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3687813/ac943c0e-c102-d071-ceb7-93f2c466a285.png)

遷移先のS3バケット設定画面でバケットポリシーを編集し、先ほどコピーしたポリシーをペーストします。このポリシーを確認すると、先ほど作成したディストリビューションからのみGetObjectが許可されていることがわかります。

![スクリーンショット 2024-02-28 13.27.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3687813/0310c9b6-a587-d66c-1d2f-282b2bc76a9b.png)

## 5. CloudFrontのディストリビューションドメインからS3のオブジェクトにアクセスできることを確認

S3バケットにアップロードした2つのHTMLファイルにアクセスできます。

![スクリーンショット 2024-02-28 13.37.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3687813/8268e213-819b-e7c4-b230-72894919326f.png)

![スクリーンショット 2024-02-28 13.37.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3687813/9d533532-db1e-3d32-6b9a-072692464b9f.png)

# 最後に

特に面倒な行程もなく、簡単に構築できました。
今回はS3バケットの暗号化にSSE-S3を使用しており、OAIを使用することも可能です。
せっかくならOACで対応可能になったSSE-KMSを使用しても良かったんですが...。

また、[今回構築したCloudFront+S3環境を使用してCloudFrontの署名付きCookieについてまとめた記事](https://qiita.com/DaichiAndoh/items/738cf75b015a7d2b50c8)もありますので、もしご興味があればこちらもご覧ください。

最後まで読んでいただきありがとうございました。

# 参考ページ

本記事作成にあたり参考にさせていただきました。
ありがとうございました。

* https://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/private-content-restricting-access-to-s3.html
* https://aws.amazon.com/jp/blogs/news/amazon-cloudfront-introduces-origin-access-control-oac/
* https://dev.classmethod.jp/articles/amazon-cloudfront-origin-access-control/