#概要
本記事では、S3+CloudFront+Route53を利用して、静的サイトを公開する実装手順を紹介します。ACMを使ってSSL証明書を発行し、httpsで公開します。
LP(ランディングページ)、ポートフォリオサイト、シンプルなサイトなどをインターネット上に公開する際に役立ちます。
##本記事のゴール
今回のゴールは、以下のhtml,ccs,画像だけのシンプルな静的Webサイトを、独自ドメインを使用してインターネット上に公開することです。
##事前準備
- AWSのアカウント
- 公開するファイル(html,css,imageなど)
#実装手順
- S3で静的Webサイトホスティングをする
- CloudFront経由でS3のファイルにアクセスする
- CloudFrontのOAIを使用して、S3への直接アクセスを制限する
- 独自ドメインを取得し、Route53へ設定する(freenomで無料ドメインを取得します)
- ACMでSSL証明書を発行する
- CloudFrontへSSL証明書を設定する
- Route53にCloudFrontのドメインを紐付ける
- 独自ドメインにアクセスしてブラウザで確認する
テスト目的の場合、今回の実装は無料でできます。(AWS無料利用枠の利用かつ条件を満たす場合のみ)
きちんと運用する場合だと料金はかかりますが、安価だと思います。
料金については、下記を参照のもと、自己責任でお願いします。
AWS で静的ウェブサイトをホスティングするときの合計コストは、使用状況によって異なります。 一般的に、AWS 無料利用枠の制限を超えた場合の費用は 1 か月あたり 1~3 USD です。 AWS 無料利用枠の対象で、制限の範囲内にある場合、静的ウェブサイトをホスティングする費用は 1 か月あたり約 0.50 USD です。詳細なコストの分析と請求額の見積もりについては、料金計算ツールをご利用ください。
引用:静的ウェブサイトをホスティングする
##S3で静的Webサイトホスティングをする
S3は、ストレージサービスだけでなく、静的Webサイトをホスティングできます。
静的Webサイトとは、シンプルなhtml,css,画像,JavaScriptなどで作られたサイトのことです。
バケットにURLを指定すると、誰でもサイトにアクセスできます。
###バケットを作成する
「バケット名」に任意のバケット名を入力しましょう。
今回はtest.co.jp
というバケット名を作成します。
###ブロックパブリックアクセスをOFFにする
※最終的にS3バケットへの直接アクセスではなく、CloudFront経由の独自ドメインでアクセスするように設定するので、後ほどS3のブロックパブリックアクセスはONします。現段階では、S3で静的WebサイトをホスティングするのでOFFにします。
その他は、デフォルト設定のままでOKなので、バケットを作成をクリックしましょう。
###ファイルをアップロードする
事前に作成したhtml,css,JavaScriptファイルなどを追加しましょう。
今回、画像は「images」フォルダに格納したので、フォルダの追加をクリックして追加しました。
html,css,画像などが追加されていることを確認しましょう。
確認ができたら、アップロードをクリックしましょう。
アップロードすると、追加したファイルがバケットに入ります。
アップロードが成功すると以下のような画面表示になります。
成功したら、右上の閉じるをクリックしましょう。
以下のように、アップロードしたファイルがバケット内に入っていることを確認しましょう。
###静的ウェブサイトホスティングを「有効」にする
S3を使用して、静的ウェブサイトのホスティングを有効にします。
一番下にスクロールし、静的ウェブサイトホスティングの「編集」をクリックしましょう。
※4XXエラーが発生すると表示されるエラードキュメントを指定する場合は、エラードキュメントにerror.htmlなどを入力しましょう。
###バケットポリシーを追加する
バケットポリシーとは、S3のバケットにアクセスの制限を設定することです。
誰が、何に対して、どうできるのか、できないのかを設定できます。
今回は、バケットへのパブリック読み取りアクセスを許可するバケットポリシーを追加します。これを許可すると、インターネット上から誰でもS3バケットにアクセスできるようになります。
パブリック読み取りアクセスを許可するには、以下のバケットポリシーをコピーし、エディターに貼り付けます。
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "PublicReadGetObject",
"Effect": "Allow",
"Principal": "*",
"Action": [
"s3:GetObject"
],
"Resource": [
"arn:aws:s3:::Bucket-Name/*"
]
}
]
}
ResourceのBucket-Nameは、自身で作成したバケット名を指定します。
今回は、test.co.jp
がバケット名です。
エディタにバケットポリシーを設定し、バケット名も確認したら変更の保存をクリックしましょう。
###バケットウェブサイトエンドポイントからURLを確認する
ここまで完了するとエンドポイント(インターネット上に公開されたURL)が発行されます。
URLをクリックして、静的サイトが表示されているか確認します。
「プロパティ」に移動し、「静的ウェブサイトホスティング」にURLが発行されているので、クリックしましょう。
このURLの内容は、http://【バケット名】.s3-website-【リージョン名】.amazonaws.com/
となっています。
静的サイトが表示されているか確認しましょう。
以下のように、今回公開するサイトが表示されたら成功です。
以上で、S3で静的Webサイトのホスティング作業が完了しました。
##CloudFront経由でS3のファイルにアクセスする
次に、S3バケットへ直接アクセスではなく、CloudFront経由でアクセスできるように設定します。
CloudFrontとは、Webコンテンツの配信が高速化し、安全性の高いコンテンツデリバリーネットワークです。(略してCDNと呼ばれます)
通常、ユーザーはWebサーバーにアクセスして見たいページを取得しますが、CloudFrontdでは、Webサーバーの中身をキャッシュするエッジサーバーを利用します。
エッジサーバーを利用すると、Webサーバーの負担が軽減されるので、レスポンスが高速化されます。
S3でホスティングしたWebサイトと紐付けてよく使われます。
CloudFrontを利用するメリットとS3との違いについて
「サービス」から**「CloudFront」**を起動しましょう。
###Distributionを作成する
Create Distributionをクリックしましょう。
-
Origin Domain Name
→作成したS3バケットを選択 -
Restrict Bucket Access
→Yes
S3バケットへのアクセスを拒否し、CloudFront経由でのみアクセス可能にする -
Origin Access Identity
→Create a New Identity
オリジンアクセスアイデンティティ(OAI)を作成する -
Grant Read Permissions on Bucket
→Yes, Update Bucket Policy
作成したOAIをS3のバケットポリシーに自動で記載してくれる
http通信だった場合に、httpsにリダイレクトされるように設定しましょう。
デフォルトのルートオブジェクトを設定しましょう。
S3の静的Webサイトホスティングのデフォルト設定は、index.html
を返しますが、CloudFrontのURLへアクセスする際のデフォルト設定では、index.html
は省略できないので、オブジェクトの名前の指定が必要です。
よって、URLのアクセス時にCloudFrontがindex.html
をオブジェクトとして返す設定を行います。
他は全てデフォルト設定のままでOKです。
Create Distributionをクリックしましょう。
Distributionが作成できたら、左のタブ1番上のDistributionsをクリックしましょう。
StatusがIn ProgressからDeployedになるのを待ちます。
Deployedになるまでには数分かかります。
###CloudFront経由のURLを確認する
StatusがDeployedになったら、Donation NameタブにあるURL(d3XXXXXX36XXXX.cloudfront.net
)をコピーし、ブラウザで確認しましょう。
以下のように、今回公開するサイトが表示されたら成功です。
以上でCloudFront経由でS3のファイルにアクセスする設定は完了となります。
##CloudFrontのOAIを使用して、S3への直接アクセスを制限する
CloudFrontのオリジン設定時に、S3からOAIを使用したCloudFront経由のアクセスを可能にしたので、S3バケットから直接アクセスするのを無効にする設定をします。
###ブロックパブリックアクセスをONにする
S3のバケットのブロックパブリックアクセスをONに設定することで安全な運用が行えます。
「S3」を起動し、アクセス許可のタブに移動しましょう。
ブロックパブリックアクセス(バケット設定)の編集をクリックしましょう。
パブリックアクセスをすべてブロックにチェックを入れたら、変更の保存をクリックしましょう。
モーダルが開くので、確認と入力ししましょう。
###S3バケットポリシーを編集する
現状のバケットポリシーを確認すると、以下のように先程のCloudFrontのオリジン設定時に、OAIを使用したS3へのバケットへのアクセスを許可する設定がすでに追加されています。
バケットポリシーの編集画面に遷移されます。
現状のポリシーを確認すると、"Sid": "PublicReadGetObject"
という静的WebサイトホスティングでS3バケットのリソースをパブリックへ公開するためのポリシーが設定されています。
このポリシーを削除することで、S3のバケットからの直接アクセスを無効にし、OAIを使用したCloudFront経由のアクセスが可能となります。
以下の範囲を削除しましょう。
もし、"Sid": "PublicReadGetObject"
が残った状態でブロックパブリックアクセスをONにすると、CloudFront経由でアクセスした場合、403エラー(閲覧権限なし)になります。
編集が完了したら下記、3点を確認しましょう。
- アクセス許可の概要︰非公開のバケットとオブジェクト
- ブロックパブリックアクセス(バケット設定)︰パブリックアクセスをすべてブロックが「ON」
-
バケットポリシー︰OAIを使用したCloudFront経由のアクセスが許可されたポリシー
以上でOAIを使用したCloudFront経由のアクセスを可能にするバケットポリシーの編集は完了になります。
試しに、S3のエンドポイントから直接アクセスしようとすると、403エラーになります。(こうなるのが正常です)
##独自ドメインを取得し、Route53へ設定する
###ドメインを取得する
ドメインはRoute53からも入手できますが、費用がかかります。
試験目的の場合は、freenomで無料ドメインを取得できます。
取得方法は割愛します。以下のサイトを参考にしてみましょう。
今回はtestfile.tk
という無料ドメインを取得しました。
###ホストゾーンを作成する
Route53とは、DNS(ドメインネームサービス)です。
インターネット上でドメインを管理・運用するために開発されたシステムのことを指します。
DNSは、https://example.com
みたいなURLをIPアドレス(123.456.789.123)に変換します。
ドメインの取得ができたり、Route53でアクセスしたいアドレスを使用したいS3のエンドポイントに紐付けます。
完了すると以下のように、NSレコードとSOAレコードが作成されます。
NSレコードが4件作成されるので、freenomのDNS設定をします。
freenom→Sevices→MyDomainに移動しましょう。
Manage Domainをクリックしましょう。
freenomのNameserverとして登録します。
Management Tools→Nameserverをクリックしましょう。
以上でドメインの設定とfreenomのDNS設定は完了です。
##ACMでSSL証明書を発行する
ACM(AWS Certificate Manager)とは、AWSウェブサイトとアプリケーションを保護するhttps通信に必要なSSL証明書の作成、更新などができます。
SSL証明書の作成は無料です。
AWS Certificate Manager とは何ですか?
SSL証明書とは、Secure Socket Layerの略です。
ウェブサイトの「運営者の実在性を証明」し、インターネット上でやりとりされるデータの「盗聴」「なりすまし」「改ざん」などを防止するために通信データの暗号化を行います。
SSL化のメリット
SSL化することで、悪質な不正アクセスの被害を防げます。
セキュリティ面を強化でき、アクセス権限をもたない人がサーバーや情報システムの内部に侵入しないように防止できます。
「サービス」から**「Certificate Manager」**を起動しましょう。
CloudFrontにACMで作成したSSL証明書を紐付けるためには、
リージョンを「米国東部 (バージニア北部) us-east-1」にする必要があります。
ビューワーと CloudFront との間で HTTPS を必須にするには、証明書をリクエストまたはインポートする前に AWS Certificate Manager コンソールで AWS リージョンを**米国東部 (バージニア北部) **に変更する必要があります。
引用:CloudFront で SSL/TLS 証明書を使用するための要件
リージョンを**「米国東部 (バージニア北部) (us-east-1)」**に変更し、今すぐ始めるをクリックしましょう。
###証明書を発行する
パブリック証明書のリクエストにチェック→証明書のリクエストをクリックしましょう。
取得したいSSL証明書のドメイン名を入力しましょう。
今回は、*.example.com
のようにワイルドカード証明書を発行する設定とします。ただし、*.example.com
で証明書を発行した場合、example.com
といったドメインは保護されません。また、複数のドメインを追加することも可能です。
入力したら、**「次へ」**をクリックしましょう。
DNSの検証にチェック→**「次へ」**をクリックしましょう。
タグ名は任意です。空欄でも問題ないです。
とくになければ、**「確認」をクリックしましょう。
ドメイン名と「DNS」を確認し、「確定とリクエスト」**をクリックしましょう。
検証状態は、「検証保留中」になります。
Route53でのレコード作成をクリックしましょう。
正常にCNAMEレコードがRoute53に追加されると**「成功」**と表示されます。
CNAMEレコードとは、ドメイン名に別名を指定するためのレコードです。
例えば、example.com
などの現在のレコードに対して、別のドメイン (example.jp
など)やサブドメイン (www.example.com
など) にマッピングします。
この時、www.example.com
をcanonical name(正式名)、example.com
をaliases(別名)と呼びます。
Route53を起動すると、以下のように検証用のCNAMEレコードが追加されています。
早ければ数分で**「発行済み」**になります。
※20分〜30分かかる場合もあるので、気長に待ちましょう。
以上でSSL証明書の発行は完了です。
##CloudFrontへSSL証明書を設定する
独自ドメインによるhttps接続の為、CloudFrontの設定をします。
CloudFront→Distribution→該当のDistributionIDをクリックしましょう。
###Distributionを編集する
「General」→Editをクリックしましょう。
-
**Alternate Domain Names (CNAMEs)**は、
www.testfile.tk
とします。https://www.testfile.tk
でのアクセスを可能にします。 -
Custom SSL Certificateにチェックします。
先程、ACMで作成した*.testfile.tk(fb1a5....
を指定します。
上記以外はそのままの設定でOKなので、**「Yes,Edit」**をクリックしましょう。
「Distributions」に戻るとCNAMEsタブに指定したドメインが表示されています。
StatusがIn ProgressからDeployedになるのを待ちます。
以下のようにStatusがDeployedになったら設定は完了です。
※Deployedになるまでは数分かかります。
以上でCloudFrontへSSL証明書を設定する作業は完了です。
##Route53にCloudFrontのドメインを紐付ける
今回は、www.testfile.tk
で公開するため、Route53のレコード設定をします。
###レコードを作成する
Route53→ホストゾーン→ドメイン名(testfile.tk
)をクリック→レコードを作成をクリックしましょう。
-
レコード名
→リダイレクト元のドメイン
(CloudFrontでSSL証明書を設定した際に入力したドメイン名) -
レコードタイプ
→A -
トラフィックのルーティング先
→エイリアスをONにする
→**「CloudFront ディストリビューションへのエイリアス」**を指定
→CloudFrontのDomain Nameを指定
入力ができたら、レコードを作成をクリックしましょう。
以上でRoute53へのドメイン名の紐付け作業は完了です。
##独自ドメインにアクセスしてブラウザで確認する
作成したドメイン(https://www.testfile.tk/
)をブラウザでアクセスして、静的サイトが表示されるか確認しましょう。
無事表示されたら、成功です!
※今は上記のURLでアクセスできません。
※テスト目的などの場合は、課金されないようにS3バケットの削除、CloudFrontのDistributionの削除、Route53のホストゾーンの削除(作成から12時間以内にホストゾーンを削除した場合は、月額0.5$の課金対象外です)など忘れずに実施しておきましょう。
##番外編
###S3バケットのオブジェクトをCloudFrontに即時反映させる方法
S3バケット内のオブジェクト(html,cssなど)を更新したいときに、オブジェクトをバケットにアップロードしても、CloudFrontには即時に反映されません。
なぜなら、CloudFrontはS3オブジェクトのキャッシュを24時間保持しているからです。
デフォルトでは、CloudFront は Amazon S3 からのレスポンスを 24 時間 (86,400 秒間のデフォルト TTL) キャッシュしています。リクエストが エッジロケーションに到着してから24 時間以内に Amazon S3 を提供した場合、Amazon S3 のコンテンツを更新したとしても、CloudFront はキャッシュされたレスポンスを使います。
引用:CloudFront が、Amazon S3 から古いコンテンツを提供し続けるのはなぜですか?
その場合の対処法は、CloudFrontのキャッシュをクリアすることでS3からオブジェクトを直接取得でき、ファイルが即時反映されます。
コンソールから「CloudFront」→対象のDistributionsを選択しましょう。
Invalidationsをクリックしましょう。
※「Invalidation」とは直訳で「無効化」という意味です。
Create Invalidationをクリックすると、モーダルが開きます。
Object PathsにキャッシュをクリアをしたいS3のオブジェクトのパスを指定しましょう。
削除したいオブジェクトのキャッシュをパスで指定します。
今回は、/*
と指定します。
これを指定すると、対象のS3バケット内全てのキャッシュがクリアされます。
データを指定したい場合などは、以下のように指定しましょう。
/index.html
/css/*
StatusがIn ProgressからCompletedに変われば、キャッシュの削除は完了です。
ブラウザからCoudFrontのURL(d3XXXXXX36XXXX.cloudfront.net
)にアクセスし、サイトが更新されたことを確認してみましょう。
独自ドメインの反映までには、時間がかかると思います。
自分の場合は3〜4時間かかりました。
※※注意事項※※
無料で 1 か月あたり 1,000 回のパスの無効化が許可されています。パスの無効化が 1 か月あたり 1000 回を超える場合は、「Amazon CloudFront の料金」にある「無効リクエスト」の覧をご参照ください。
引用:CloudFront が、Amazon S3 から古いコンテンツを提供し続けるのはなぜですか?
##参考サイト
今回実装するにあたって以下のサイトを参考にさせていただきました。
Amazon S3 での静的ウェブサイトの設定
CloudFrontを使用して、Amazon S3 でホストされた静的ウェブサイトを公開する
CloudFront + S3 + Route53で独自ドメインをSSL通信(https)設定をする
無料ドメイン(.tk)とRoute53を利用して0円でHTTPS環境を設定してみた