AWS S3 での静的サイト公開

単に S3 で静的ウェブサイトを公開するだけならほとんど設定は要らないのですが、SSL を利用する場合 CloudFront を使うする必要があります。また、S3 はリクエスト回数と転送量によって課金されるため、大量のリクエストがあるとそれに対しても課金されます。また、例えば bot やクローラ等から大量のアクセスがあった場合、一瞬で無料枠を使い果たして課金が始まってしまう可能性もあります。

なお、以下の作業は 2017 年 6 月 14 日現在での無料枠の範囲外の作業を含みます。

概要

作業の流れとしては、

  1. S3 で bucket 作成・ファイルの追加
  2. Certificate Manager で SSL 証明書を作成
  3. CloudFront で distribution を作成・設定
  4. Route 53 にドメインを登録・設定

という感じになろうかと思います。

S3

S3 を直接独自ドメインで公開する場合は bucket 名をドメイン名と同じにする必要があるようですが、ここでは一旦 CloudFront を通すからか特に制約はないようにも見えます。まあだからといって変える必要はないというか、むしろドメイン名で取っておいた方が分かり安いのでそのままドメイン名で取得します。

S3 を直接公開する場合は「静的サイトのホスティング」を ON にしますが、ここでは直接公開はせず CloudFront 経由で公開するため OFF のままにしておきます。

Certificate Manager

ここで SSL 証明書を取得します。

Certificate Manager は様々なリージョンが選択できますが、CloudFront で使用できるのは米国東部 (バージニア北部) のものだけです。

AWS Certificate Manager に統合されるサービス – AWS Certificate Manager

CloudFront で ACM 証明書を使用するには、米国東部(バージニア北部) リージョンで証明書をリクエストまたはインポートする必要があります。

また、うっかりミスったことは、当然のことではありますが「頭に “*.” を付けても、サブドメイン無しのドメイン (zone apex) は含まれない」のにも関わらず *. 付きのドメインで申請した証明書を zone apex に対して使ってしまったことです。つまり、example.com の証明書は *.example.com ではなくきちんと example.com のものを用いないといけません。すべてのドメインをカバーする場合、ドメイン名と追加の名前にそれぞれ二パターン登録する感じかなあ、と思います。

CloudFront

Cloud と Front の間にはスペースが入りません。

CloudFront は、作成したり設定してから適用・完了するまでしばらく時間がかかります。Status が in progress から deploy に変われば完了です。

SSL 証明書を用いる場合はこの CloudFront を試用する必要があります。また、これを用いるとキャッシュを使うことができます。これによって、大量のリクエストがあった場合でも S3 へのリクエストを減らすことができ、料金を減らすことが出来ます。

Distribution の作成

  • RTMP ではなく Web の方で作成します。
  • Origin Domain Name は公開したい S3 の bucket のエンドポイントを選択します
  • Restrict Bucket Access は Yes にします
    • これによって、bucket ーのアクセスを CloudFront 経由に限定するための設定ができるようになります
    • Origin Identitiy を新たに作るため、Create a New Identity を作成します
      • これは S3 にアクセスするためのユーザ (a special CloudFront user – an origin access identity -) だそうです
  • Viewer Protocol Policy は適当に設定しますが、今回私はすべての接続を HTTPS としたいため Redirect HTTP to HTTPS としました
    • HTTPS Only にした場合、HTTP でアクセスされたものは弾かれます
  • Alternate Domain Names (CNAMEs) には設定したいドメイン(当該のドメイン)を指定します
  • SSL Certificate は Custom SSL Certificate を選択し、先ほど作成した SSL 証明書のうち適切なもの(設定したいドメインのもの)を指定します
  • Custom SSL Client Support は 

    • All Clients には $600/month と、うっかり間違って選択したら相当悲しくなりそうな単語が書いてあります
  • Default Root Object は index.html のようなデフォルトのファイルを指定します
  • Logging は on にしておきました

Error Pages の設定

次に Error Pages を設定します。これを設定しないとエラーのキャッシュが行われません。

例えば、存在するファイルへのアクセスがあった場合、CloudFront は S3 にアクセスし、その内容をキャッシュして返します。次のアクセスではキャッシュした内容が用いられるので、S3 へのアクセスは発生しません。

一方、存在しないファイルのアクセスがあった場合、CloudFront は S3 にアクセスしてファイルがないことを確認し 404 Not Found を返します。しかしこの結果はキャッシュされないので、次のアクセスでも同様に S3 へのリクエストが発生します。

面倒な bot や、robot.txt を設置していない場合などはこれらのファイルへのアクセスが大量に行われるため、結果的に大量に S3 へのリクエストが発生してしまいます。

とりあえず適当に、404 Not Found と 403 Forbidden を設定しておきました。オリジナルのエラーページを設定していない場合、Customize Error Response を No にしておきます。

Route 53

ここでの設定は本来の DNS の設定を行う必要がありますので、例えばさくらのネームサーバ等簡便なものでの書き方とは違うところもあります。

私は今まではさくらのネームサーバを利用していましたが、これを期に Route 53 へ移行しました。さくらと違い SOA も自由に設定できます。すなわち、例えば negative caching TTL を自由に設定する事もできます。

ここで A レコードと AAAA レコードを追加します。このとき、設定の Alias を yes にすると Alias Target を指定する事ができるようになります。ここから、当該 CloudFront のエンドポイントを指定します。S3 の bucket 名をドメインと同じものにしているばあいはこれも表示されますが、こちらを選択してはいけません。

さくらのネームサーバ等との違い

さくらのネームサーバ等と大きく違っていることの一つが、相対ドメイン(不完全ドメイン名)での指定ができるかどうかです。例えば、example.com において、foo.example.com. の CNAME に bar.example.com. を指定するばあい、さくらのネームサーバでは相対パスは補完され bar と書くだけで指定できます。また、ORIGIN と同じドメインは @ で指定するため、example.com. は @ となります。しかし、ここではすべて FQDN で指定する必要があります。

また、FQDN 末尾の .  が省略されていても正しく登録できるようですので、どうやら自動で末尾に . が補完され FQDN になる仕様のようです。

費用

Route 53 は 1 ドメインあたり月額 0.50 ドルがかかります。

また、問い合わせのクエリごとにも課金されますが、AWS 内のサービスのエンドポイントへのエイリアスの場合は無料のようです。

料金 – Amazon Route 53 | AWS

Elastic Load Balancing、Amazon CloudFront ディストリビューション、AWS Elastic Beanstalk 環境、および Amazon S3 ウェブサイトバケットにマッピングされているエイリアスレコードをクエリする場合、クエリは無料です。

おわり

  • S3 のエンドポイントでアクセスして弾かれること
  • CloudFront のアドレスでアクセスして表示されること
  • 設定したドメインで正しく表示されること
  • SSL 証明書の警告が出ていないこと
  • HTTP のアクセスが HTTPS へリダイレクトされていること

を確認できたので終わりです。

S3 の料金や、Route 53 のクエリごとにかかる料金はごく僅かで、Route 53 のドメインごとにかかる料金もごく僅かですから、静的なウェブサイトのみを公開する場合はとても便利そうですね。