AWS
S3
HTTP
HTTPS
CloudFront

CloudFront を利用し HTTP/HTTPS をサーバレスでリダイレクトする

何をしたいか

サイトを移転するときなど、既存の URL へのアクセスを新しい URL へリダイレクトしたいときがある。
S3 でのリダイレクトがお手軽だが、HTTPS のリダイレクトができないのが弱点である。
かといって、SSL 接続を終端させるためだけに ELB + EC2 の構成を用意するのも手間。

そこでこの、

  • HTTP だけでなく、HTTPS でのリダイレクトも行いたい
  • サーバレスで行いたい

という要求を満たすために、CloudFront + S3 の構成でリダイレクトを行う。

前提

  • リダイレクト元に HTTP および HTTPS どちらのアクセスが来ても良いようにする
  • パスはカットしてリダイレクトしたい

手順

S3 バケットの作成、設定

バケットの作成

リダイレクト設定を行うバケットを作成する。
直接表には出ないバケットであるため、名前は何でも良い。

Static website hosting の設定

プロパティ => Static website hosting を開き、以下の設定をする。
ここで設定したリダイレクトのレスポンスが CloudFront を通じて返される。
今回は、www.google.com にリダイレクトしている。

  • インデックスドキュメント
    • index.html
      • 指定がないとエラーになるため。ファイルは無くて良い
  • エラードキュメント
    • (空白)
  • リダイレクトルール
    • <ReplaceKeyWith/> によって、どのようなパスでもカットされてリダイレクトされる
<RoutingRules>
    <RoutingRule>
        <Redirect>
           <HostName>www.google.com</HostName>
           <ReplaceKeyWith/>
        </Redirect>
    </RoutingRule>
</RoutingRules> 

※ 「リクエストをリダイレクトする」を利用しても良いが、その場合はパスがカットされない

ACM 証明書の発行

リダイレクト元の FQDN の SSL 証明書を発行する。
ドキュメント(証明書のリクエスト)に沿って発行すれば問題ないが、リージョンは「バージニア北部」を選択して発行する。
(「東京」などで発行すると、CloudFront の証明書選択画面に出てこずにハマる)

CloudFront の設定

CloudFront のディストリビューションを作成する。
ほぼほぼデフォルトで良いが、以下の設定は行う。

  • Origin Domain Name
    • 上で作成した S3 のエンドポイント(http:// で始まるアドレス)を指定する(プルダウンで出てくるバケット名ではない
      • CloudFront => S3 に http アクセスし、返ってきたリダイレクトレスポンスをクライアントに返すため
      • エンドポイントは Static website hosting の設定画面で確認できる
  • Viewer Protocol Policy
    • Redirect HTTP to HTTPS
      • HTTP できたリクエストも、HTTPS に直した上でリダイレクトする
      • HTTP は HTTP のままリダイレクトしたい場合は、HTTP and HTTPS にする
  • Alternate Domain Names(CNAMEs)
    • リダイレクト元のドメイン名を入れる
  • SSL Certificate
    • Custom SSL Certificate
      • バージニア北部」で発行していない場合はプルダウンで選択できないので注意

Create Distribution を押したら、Deploy されるまで待つ。
Deploy されたら、DNS レコードを書き替える前に、"Domein Name" 欄にある CloudFront のエンドポイントを利用し、テストすると良い。

  • 参考: リダイレクト元が example.com の場合
curl --head -v -H "Host: example.com" https://d2********.cloudfront.net
# 301 が返ってくれば OK

DNS レコードの書換え

Route53 を利用している場合は、リダイレクト元のドメイン名の Alias レコードに、作成した CloudFront のディストリビューションを指定する。
それ以外の DNS サービスを利用している場合は、CNAME レコードに CloudFront ディストリビューションのエンドポイントを指定する。