S3+CloudFront+Route 53を使った静的コンテンツ配信

福岡拠点の野田です。

WordPressで運用していた個人サイトをメンテしなくなったので、S3とCloudFrontとRoute 53を使って静的コンテンツ配信方式に切り替えてみました。手順の大きな流れは以下のようになります。

  1. S3にコンテンツを配置
  2. CloudFrontを設定
  3. Route53でCloudFrontへ振り分け

S3 にコンテンツを配置

まずは、wget で既存サイトを取得します。

[/crayon]

日本向けに配信することを考え、 S3 の東京リージョンにて新規バケットを作成して、上記取得したファイルを配置します。

S3における設定ですが、アクセス権限の設定を行います。静的コンテンツとして公開するため、以下のバケットポリシーのブロックをオフにすることで外部からのアクセスを行えるようにします。

  • 新規のパブリックバケットポリシーまたはアクセスポイントポリシーを介して付与されたバケットとオブジェクトへのパブリックアクセスをブロックするオフ
  • 任意のパブリックバケットポリシーまたはアクセスポイントポリシーを介したバケットとオブジェクトへのパブリックアクセスとクロスアカウントアクセスをブロックするオフ

バケットポリシーは、以下のようなCloudFrontからの接続を許可する設定を行いますが、CloudFront側から設定ができるため、ひとまずスキップで大丈夫です。

[/crayon]

CloudFrontを設定

Create DistributionでCDNを新規作成します。

  1. Web/RTMPの選択でWebを選択
  2. Origin Domain NameにS3のバケットを選択
  3. Origin Pathは空欄でOK
  4. Origin IDは任意のIDを設定(S3-バケット名みたいな感じで設定しました)
  5. Restrict Bucket Accessは、YES
  6. Origin Access Identityは、 Create a New Identity。
  7. Grant Read Permissions on Bucketは Yes, Update Bucket Policy (これが先ほどのS3バケットポリシーに反映されますので、一応S3側でも設定されているか確認)
  8. Viewer Protocol Policyは、Redirect HTTP to HTTPS (httpからhttpsリダイレクト)
  9. Allowed HTTP Methodsは、GET/HEADのみで対応(CORSを考えるとOPTIONSまでやってもいいかもしれません)
  10. Compress Objects Automaticallyは、true(圧縮化。転送量削減)
  11. Price Classはベストパフォーマンス
  12. AWS WAF Web ACLは、None
  13. Alternate Domain Namesは割り当てるドメイン名を改行区切りで入力。
  14. 証明書については、独自ドメインで割り当てる場合、ACMに登録したものを選択。
  15. 残りはデフォルトで登録

Distribution作成後、 GeneralタブでEditボタンを押下して、以下を設定します。

  1. Default Root Objectにindex.htmlを設定

続いて Restrictionsタブを選択して、GeoRestrictionをEditします。

今回は、日本のみを対象とします。全世界を対象とするとコストと直結します。1日1000円以上かかってもいい!どんな攻撃もどんとこい!という方以外は、対象を絞ったほうが良いと思います(私もこれで当初1日放置して1000円かかってしまい冷や汗、急遽制限を追加しました)。

Route53でCloudFrontへ振り分け

仕上げにRoute53からCloudFrontへ振り分けします。A(IPv4アドレス)およびAAAA(IPv6アドレス)のエイリアス指定でCloudFrontにつなげることができます。

まとめ

Cloudは設定をミスると高額な請求が発生してしまうリスクはありますが、うまく使えば個人で使っても安く運用することができます。最近では予算設定や請求が高額になりそうなときにアラートも出せる機能もありますので、そうしたものを組み合わせて、安全に運用すると良いと思います。先月からの運用の感じだとアクセス数次第なところがありますが、100円~300円/月ぐらいで運用できそうな感じでした。

初心者にはおすすめはしませんが、興味ある方は是非チャレンジしてみてください。