はじめに
最近 CloudFront と S3 を組み合わせて、静的コンテンツを S3 で配置するアーキテクチャが増えてきているような気がします。
元々 ALB 後ろの EC2 に保存していた画像とかを、S3 に転換配置することによって、EC2 へのアクセス負担軽減効果が得られるではないでしょうか。
今回は CloudFront の後ろに、S3 と ALB を両方組み合わせて、構築してみました。
構成図
構成図は下記となります。簡単に説明させていただきます。
1.前提条件として、Route 53でドメインを取得済みであること。
2.ユーザー→CloudFront→ALB はhttpsでのアクセスとなります。
3.CloudFrontに cloudfront.XXXXX.comというサブドメインを設定します。
4.ALBにalb.XXXXX.comというサブドメインを設定します。
5.S3とALBはそれぞれ CloudFront の OAI として設定されております。
6.外部から直接 S3 内のオブジェクトへのアクセスは不可です。
7.外部から直接 ALB 用のサブドメインへのアクセスは不可です。
8.外部からは CloudFront を通してのみ、ALB と S3 内の資材にアクセスすることが出来ます。
9.ACM で証明書を発行しており、それぞれ CloudFront と ALB に関連付けしています。
1.EC2作成と配置
今回私が使用しているEC2は Amazon Linux 2 です。

「ユーザーデータ」に、下記のコマンドを入力し、EC2 が起動後に nginx をインストールしておきます。

# !/bin/bash
amazon-linux-extras install epel -y
yum install nginx -y
systemctl start nginx
systemctl enable nginx
EC2が起動後に、nginx 配下で dadada ディレクトリを作成し、htmlファイルを配置しておきます。
sh-4.2$ cd /usr/share/nginx/html
sh-4.2$ pwd
/usr/share/nginx/html
sh-4.2$ sudo mkdir dadada
sh-4.2$ cd dadada
sh-4.2$ pwd
/usr/share/nginx/html/dadada
sh-4.2$ sudo vi index.html
sh-4.2$ sudo systemctl restart nginx
sh-4.2$ cat index.html
<!DOCTYPE html>
<html>
<head>***************************************************************************************************
<link rel=""shortcut icon"" href=""#"" />
<meta charset=""utf-8"" />
<title>Page Title</title>
</head>
<body>
<h1>CloudFront-ALB-EC2 Test Page <br>Hello World!</h1>
<p>***************************************************************************************************</p>
</body>
</html>"
2.ACMで証明書を作成
今回作成するACM証明書は、二つリージョン内にあります。
・CloudFront用証明書:バージニア北部リージョン側で*.xxxxx.com証明書を作成
・ALB用証明書:東京リージョン側で*.xxxxx.com証明書を作成
まず最初はバージニア北部リージョン側で作成しておきます。
ACMの証明書作成画面で証明書のリクエストを押下し、証明書のリクエストを押下します。

ここに*.xxxxx.comを入力します。(xxxxx.comはドメイン名)

Route 53 でのレコードの作成を押下し、追加しておいてください。

しばらくすると、バージニア北部リージョン側で、状況が発行済みに変更されていれば完了です。

同じように、東京リージョン側で*.xxxxx.com証明書を作成しておいてください。
作成完了後はこんな感じです。

3.ALBを作成
Application Load Balancerを作成します。
EC2→ロードバランサー画面で作成します。

名前欄に、適宜に入力をしてください。
リスナー欄には、HTTPSの443を選択してください。

証明書タイプにACMから証明書を選択する(推奨)をクリックし、先ほど東京リージョンのACMで作成された証明書を選択してください。

セキュリティーグループは、HTTPS 443ポートを全部開放とします。

ターゲットグループに新しいターゲットグループを選択の上、名前は適宜ご入力ください。

EC2を選択し、登録済みの追加をクリックし、ALBを作成してください。

Route 53画面を開き、新規のレコードを追加します。
・レコード名に、ALB用のサブドメイン名を記入します。
・レコードタイプは、Aレコードを選択します。
・エイリアスをオンの上、先ほど作成されたALBを選択してください。
上記項目が選択しおわったら、レコードを作成をクリックします。

ALBのリスナールールは、下記のように変更設定をしておいてください。
・IF ホストがalb.xxxxx.com THEN 転送先 ec2-test: 1 (100%)
グループレベルの維持設定: オフ
・IF それ以外の場合はルーティングされないリクエスト THEN 固定レスポンスを返す 503
Content-Type:text/plain
レスポンス本文:Error Page
(未満...)
ここで、ALBのサブドメインで直接アクセスをしてみたところ、無事に反映されていますね!

4.S3 を作成
以前私が直接CloudFormationでS3を作成したことがあるので、下記のURLにご参考していただいて、作成していただければと思います。
| 項目 | 設定 |
|---|---|
| デフォルトの暗号化(SSE-S3) | 有効 |
| バージョニング機能 | 有効 |
| ブロックパブリックアクセス(バケット設定) | 有効 |
S3作成完了後に、S3でlalalaというフォルダを作成します。

作成完了後に、下記のhtmlファイルをS3へアップロードしておきます。
<!DOCTYPE html>
<html>
<head>***************************************************************************************************
<link rel="shortcut icon" href="#" />
<meta charset="utf-8" />
<title>Page Title</title>
</head>
<body>
<h1>CloudFront-ALB-S3 Test Page <br>Hello S3!</h1>
<p>***************************************************************************************************</p>
</body>
</html>
5.CloudFront作成と設定
CloudFront の Distributions 画面で、Create distributionsを押下します。

・Origin domainに先ほど作成していたS3を選択してください。
・S3 bucket accessにYes use OAIを選択します。
・Create new OAIをクリックします。
・Bucket policyにYes, update the bucket policyを選択します。

Route 53画面を開き、新規のレコードを追加します。
・レコード名に、CloudFront用のサブドメイン名を記入します。
・レコードタイプは、Aレコードを選択します。
・エイリアスをオンの上、CloudFrontのDistribution domain nameを記入します。
上記項目が選択しおわったら、レコードを作成をクリックします。

・Alternate domain name (CNAME) - optionalに、先ほど作成したCloudFrontのサブドメイン名を記入します。
・Custom SSL certificate - optionalに、バージニア北部リージョンで作成したACM証明書を選択します。
以上選択し終わったら、保存を押下します。

CloudFront画面で、Create originを押下します。

(★★★★★ここ超重要★★★★★)
・Origin domainはALBのサブドメイン名を記入します!!!!!!!!!
ALBのDNS名ではないので、くれぐれもご注意ください!!!!!!!!
・ProtocolはHTTPS onlyを選択します。

(★★★★★ここ超重要★★★★★)
Add headerを押下し、お好みのヘッダーを追加してください。
今回私は適当に入れてあります。
記入後に、メモをしておいてください。

Behaviors で、Create behaviorsを押下します。

・Pate patternに、ALB用のパスである/dadada/*を入力します。
・Origin and origin groupsに、先ほど作成したALBのoriginを選択します。
・Viewer protocol policyに、HTTPS onlyを選択します。

ALBのリスナールールを開き、下記のように編集をします。
先ほど好みで入力していたヘッダーネームを、ALBのルール内に埋め込みます。
・IF HTTP ヘッダー laslkdfsidfjoisanfiowen が2348732u85oisdnfsnfd
ホストがalb.xxxxx.com
THEN 転送先
ec2-test: 1 (100%)
グループレベルの維持設定: オフ
・IF それ以外の場合はルーティングされないリクエスト THEN 固定レスポンスを返す 503
Content-Type:text/plain
レスポンス本文:Error Page
(未満...)

6.疎通確認
ALBのサブドメインでアクセスすると、アクセス不可となります。

CloudFrontのサブドメインから、/lalala/index.htmlをアクセスすると、S3配下のファイルにアクセスできていることを確認できております。

CloudFrontのサブドメインから、/dadada/index.htmlをアクセスすると、EC2のnginx配下のファイルにアクセスできていることを確認できております。

S3バケットのポリシーが更新されていることを確認できました。

S3内のオブジェクトのURLへ直接アクセスすると、アクセス不可が確認できました。


上記をまとめると、
| 項目 | 設定 |
|---|---|
| CloudFrontのサブドメインからS3へアクセス | 可能 |
| CloudFrontのサブドメインからALBへアクセス | 可能 |
| ALBのサブドメインへのアクセス | 不可 |
| S3のオブジェクトURLへのアクセス | 不可 |
これで確認ができました!
7.注意事項
CloudFrontは作成後から反映するまでは、時間がかかる場合はありますので、もし設定直後にうまく反映されていない場合は、焦らずに待ちましょう~
本記事は誰かにお役に立てれば幸いです!
宜しくお願い致します。














