CloudFront経由でS3の静的コンテンツにアクセスする手順を2ステップに分けて解説します。
また、Route53やACM、OAIも活用し、CloudFrontのドメインと独自ドメイン(のサブドメイン)をリンクさせ、HTTPSで接続するところまで設定します。
CloudFront+独自ドメインを使ってS3の静的コンテンツにアクセスする全体図

概要
CloudFront経由でS3の静的コンテンツにアクセスできるようにします。
また、CloudFrontのドメインと独自ドメインをリンクさせ、OAIも使用し
- S3に直接アクセスできない
- CloudFrontドメインからアクセス可能
- 独自ドメインのサブドメインからアクセス可能
といった形にしていきます。
前提
- S3バケットは作成済み(良ければこちらご参考に!)
- S3バケットのブロックパブリックアクセスをすべてオンの状態
- 独自ドメイン取得済み
独自ドメインを立てる(オプション)
ホストゾーン作成
最初に、Route53でホストゾーンを作成します。
- Route53コンソールを開き、左のメニューからホストゾーンを選択
- ホストゾーンの作成
- 取得済みのドメイン名を入力
- パブリックホストゾーンにチェックを入れてホストゾーンの作成を実行
NSレコードとSOAレコードができました。
サブドメインはあとで作成します。
証明書を発行
HTTPS接続のために、ACMで証明書を発行します。
証明書をリクエスト
- ACMコンソールを開く
- リージョンをバージニア北部us-east-1に変更する※重要※
- 証明書のリクエストを選択する
- パブリック証明書のリクエストをチェックし、証明書のリクエストを続行
- 取得済みのドメイン名と*.ドメイン名を入力して次へ※重要※
- DNSの検証を選択して次へ
- 必要ならばタグを入力し、確定とリクエストを実行
- 進行中のリクエストページで続行をクリック
追加直後は検証保留中になっていますが、早いと数分で発行済みにかわります。

なぜバージニア北部か
CloudFrontで指定するカスタムSSL証明書は米国東部(バージニア北部)リージョン(us-east-1)にある必要があります。
他のリージョンで証明書発行済みの場合は?
バージニア北部で同じドメイン名の証明書をリクエストしましょう!
こちらで回答されているように、複数のリージョンにて同じドメイン名の証明書を作成することができます。※証明書の移動や他アカウントに譲渡はできません。
この場合は、次に示すCNAMEレコードの作成は不要です。
証明書のリクエストだけすればOKです。
CNAMEレコードを追加

証明書リクエスト後のページで、Route53でのレコードの作成ボタンをクリックして追加します。
ボタンが無ければ手動で追加する必要があるので名前・種類・値をメモしておきましょう。
※画像は追加したあとのシーンなので、ボタンが非アクティブになってます。
そのあと、Route53でホストゾーンを確認すると、CNAMEというレコードが追加されていると思います。
[Route53でのレコードの作成]がない場合
該当のホストゾーンのページで、メモした名前、種類、値を使ってレコードを作成します。
- レコード名に名前から、末尾の「.ドメイン名.」を除いた文字列を入力
- レコードタイプはCNAMEを選択
- 値はそのままの値を入力
CloudFrontを立てる
ディストリビューション作成
CloudFrontディストリビューションを作成していきます。
※独自ドメインにリンクさせる場合は、【オプション】の操作も必須です。
- CloudFrontコンソールを開き、ディストリビューションを作成
- オリジンドメインで該当するS3バケットを選択
- オリジンパスは空欄のまま
- 名前に任意の値を入力
- S3バケットアクセスで「はい、OAIを使用します」をチェック
- オリジンアクセスアイデンティティ(OAI)で新しいOAIを作成を実行
- バケットポリシーで「はい、バケットポリシーを更新します」をチェック
- デフォルトのキャッシュビヘイビアでビューワープロトコルポリシーとしてHTTPS onlyをチェック
- ビューワーのアクセスを制限するをNo
- Cache policy and origin request policy (recommended)にチェックし
- キャッシュポリシーとしてCachingOptimized選択(任意で選択してください)
- 【オプション】設定の代替ドメイン名(CNAME)-オプションにて「項目を追加」
- 【オプション】リンクさせたいサブドメインを入力
- 【オプション】カスタムSSL証明書-オプションにて先ほどリクエストした証明書を選択
- ディストリビューションを作成を実行
各設定項目について、もっとよく知りたい方はこちらを参照してください。
OAIを作成し、S3のパブリックアクセスをすべてブロック+バケットポリシーを変更することで、S3へアクセス制限を設けることができます。
CloudFrontのドメイン名確認
CloudFrontコンソールで作成したディストリビューションを選択して開き、一般タブにてディストリビューションドメイン名を確認できます。
これがデフォルトで割り当たっているCloudFrontのドメイン名になります。
S3のバケットポリシー確認
対象のS3バケットのポリシーを確認すると以下のようなポリシーが追加されていると思います。
{
"Sid": "番号",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity CloudFrontのOAI"
},
"Action": "s3:GetObject",
"Resource": "S3バケットのARN/*"
}
サブドメインとリンクさせる(オプション)
サブドメインを作成し、CloudFrontと紐づけます。
- Route53コンソールを開き、先ほど作成したホストゾーンを開く
- レコードを作成を実行
- リンクさせたいサブドメインになるようにレコード名を入力
(例:media.laboliy.comにしたいので「media」と入力) - レコードタイプでAを選択
- 値のエイリアスをオン
- CloudFrontディストリビューションへのエイリアスを選択
- 先ほど作成したディストリビューションのドメイン名を選択
- ほかの項目はデフォルトのままで
- レコードを作成を実行
ディストリビューションのドメイン名がリストにない場合、デプロイ中の可能性があるので、少し待ってからやってみましょう。
アクセスの確認
お疲れ様でした✨
最後に、S3バケットに適当な画像をアップロードして、アクセスできるか確認してみます。
以下の3つのURLを適宜読み替えてブラウザに打ち込んでみてください。
(この記事の全体図の画像を例としています)
// S3直接 …… AccessDenied
https://s3.ap-northeast-1.amazonaws.com/バケット名/articles/202109/access_s3_via_cloudfront_with_auth.jpg
// CloudFront …… アクセス可能
https://CloudFrontのドメイン/articles/202109/access_s3_via_cloudfront_with_auth.jpg
// 独自ドメイン …… アクセス可能
https://media.laboliy.com/articles/202109/access_s3_via_cloudfront_with_auth.jpg