S3+cloudFrontのWebホスト
特徴
S3を利用したWebホストには、S3単体でWebホストする方法と、CloudFrontと S3を組み合わせて使う方法があります。それぞれ以下のような特徴があります。
S3単体 | ・価格が安い ・httpプロトコルのみ ・カスタムドメインの利用、レスポンスヘッダーの変更は可能 |
CloudFrontを使う | ・CloudFront利用分の価格が追加される ・httpsプロトコルが使える ・設定がやや複雑になる ・レスポンス速度が上がる ・カスタムドメインの利用、レスポンスヘッダーの変更は可能 |
構成
S3とCloudFrontを使った静的Webホスティングの構成は、CloudFormationのテンプレートが用意されているのでこれを使うことで簡単に構築することができます。
このテンプレートでは以下のような構成で作成されます。

- S3での静的Webホスティング
コンテンツ保持用とログ用の2つのバケットが作成されます。 - CloudFrontでの高速配信
高速な配信のためにCloudFront ディストリビューションを利用します。S3にはCloudFrontを通したアクセスのみを許可するOAI(origin access identitiy)を使います。 - ACMの証明書を使ったHTTPSアクセス
カスタムドメインに対して、AWS Certificate Manager (ACM) で SSL/TLS 証明書を作成し、CloudFormationにアタッチされます。 - lambda@Edgeでセキュリティヘッダを追加
サーバーのレスポンスにセキュリティヘッダが追加されます。
料金
今回の構成で静的Webホスティングをする場合、以下の料金がかかります。一般的には全体で月3USD程度に収まるでしょう。アカウント作成後1年間は無料枠も利用できます。
S3
最初の 50 TB/月 | 0.025USD/G |
Route53
ホストゾーン | 0.50USD |
エイリアスへのクエリ | 無料 |
CloudFront
転送10 TB まで | 0.114 US |
HTTPS リクエスト(1万件あたり) | 0.0120 USD |
SIMPLE MONTHLY CULCULATORからコストの見積もりをすることができます。
構築方法
S3+CloudFrontの構成はCloudFormationのテンプレートを利用します。構築前に前提条件として必要な操作があるため、以下の手順で進めます。
- ドメインの取得とRoute53の設定
- CloudFormationの実行
- コンテンツの入れ替え
ドメインの取得とRoute53の設定
CloudFrormationの実行前にドメインの取得、route53のゾーンの作成がされていることが前提条件となっています。
まず、カスタムドメインとして使用するドメインを取得し、Route53にホストゾーンを作成しておきます。
- ドメインの取得(Freenom)
- ホストゾーンの作成(Route53)
- ネームサーバーの設定(Route53/Freenom)
ドメインの取得(Freenom)
今回はfreenomeで無料ドメインを利用します。使いたいドメインに応じて適宜お名前ドットコムなどを利用してください。
使いたいドメインを検索します。ml / ga / などのドメインが無料です。
執筆当時、トップレベルドメインまで含めて検索(sample-domainではなくsample-domain.gaなど)しないとドメインが取得できないバグがありました。

ホストゾーンの作成(Route53)
AWSコンソールからRoute53のコンソールに移動し、ホストゾーンを作成します。

取得したドメインを「ドメイン名」の欄に入力してゾーンを作成します。

ネームサーバーの設定(Route53/Freenom)
ゾーンを作成すると自動的にNSレコードとSOAレコードが作成されます。NSレコードの行にあるネームサーバーをコピして、freenomからこれらのネームサーバーを参照するように設定します。

Freenomのサイトに戻り、Service>MyDomainsから先ほど取得したドメインを表示し、「ManageDomain」からドメインについての設定画面を表示します。

Management Tools > Nameserversに進み、「Use custom nameservers」を選択して先ほどRoute53のNSレコードから取得したネームサーバーを入力します。

ドメインの設定は一度ここまでで完了です。S3バケットの設定を行った後でレコードの設定をします。
CloudFormationの実行
S3+CloudFrontの構成を作成するCloudFormationのテンプレートを利用します。以下からCloudFrormationのテンプレートが利用できます。
CloudFormationでS3+CloudFrontの静的Webホスティングの構成を作成する

設定は簡単で、サブドメインとドメインを入力して実行するだけです。

コンテンツの入れ替え
現段階で設定したドメインにアクセスすると、デフォルトのページが表示されます。

S3に「amazon-cloudfront-secure-static-site-s3bucketroot-{ランダム文字列}」という名前のコンテンツ用のバケットが作成されています。中身を自分のサイト用に入れ替えて使います。
トラブルシューティング
CDNで提供されているbootstrapやjqueryを利用しようとすると、以下のようなエラーが出ることがあります。
Refused to load the stylesheet ‘https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css’ because it violates the following Content Security Policy directive: “style-src ‘self'”. Note that ‘style-src-elem’ was not explicitly set, so ‘style-src’ is used as a fallback.
このエラーを解消するため、CloudFrontに関連付けられているレスポンスヘッダーをつけるためのLamnda@edgeの設定を変更します。
CloudFormationによって作成された「static-web-hosting-with-cloud-f-LambdaEdgeFunction-{ランダム文字列}」という名前のlambda関数を以下のように設定を変更しました。
headers['content-security-policy'] = [{key: 'Content-Security-Policy', value: "default-src 'self'; img-src 'self'; script-src 'self' 'unsafe-inline' data: code.jquery.com; style-src 'self' https://stackpath.bootstrapcdn.com/; object-src 'none'"}];

CSP(Content-Security-Policy)の設定については以下を参考にしてください。
Mozilla Web Docs
Lambda@Edgeのファンクションを変更する際には、以下の手順を行う必要があります。
- コードの変更・デプロイ
lambda関数「コード」タブよりコードを変更し、デプロイボタンを押して変更を確定します。 - 新しいバージョンの作成
lambda関数「バージョン」タブより変更を新しいバージョンとしてリリースします。 - cloudFrontの関連付けの変更
CloudFrontディストリビューション 「behaviors」タブからすでに作成済みにbehaviorを選択して編集します。Edge Function Associationsより関連づけられているlambdaのバージョンを新しいものに変更します。 - キャッシュの削除
CloudFrontディストリビューション 「Invalidation」タブからキャッシュを削除します。
コメント