CloudFrontを使わずにS3をカスタムドメイン+HTTPS化してみる

記事タイトルとURLをコピーする

技術課の水垣です。こんにちは。

今日はちょっと盲点だった構成について書こうと思います。 通常であれば、S3に格納した静的ページのHTTPS化やカスタムドメイン対応をするには AWS CloudFront を利用するかと思います。ググれば方法はいくらでも出てきますし、定番ですよね。
これを CloudFrontをを利用せずに実現してみようと思います。ただし、静的サイトホスティングではなく、あくまでHTMLを出力する方法です。

なんで、こんなことをやったのか

あるSPAのWebサービスで、以下を実現しようとしてちょっと悩んでいました。

  • Route53のヘルスチェック&DNSフェイルオーバー機能を利用
  • SPAアプリケーションをホスティングするCloudFront(カスタムドメイン・HTTPS)に障害が発生した場合に、メンテナンス用ページを表示させる

普通であれば、Route53に同じドメイン名でプライマリ(CloudFront)・セカンダリ(S3静的サイトホスティング済み)のレコード構成なのですが、S3の静的サイトホスティングだとHTTPのみなのでページが表示されませんでした。
ここはRoute53がよしなにやってくれるのかと思いましたが、どうやらそうでもなく。

じゃあHTTPS化をするためにCloudFrontを置くかって思いましたが、そもそもCloudFrontの障害用なので意味ないよねと・・・

どうしようかと思っていた時に上長との会話の中で「API GatewayのバックエンドにS3が設定できるんじゃね?」って言われたときに、「おおおっ!」てなった次第です。
API GatewayはLambdaで使うって固定観念に完全に囚われてました・・・

構成図

青色の網掛け部分が今回の設定対象になります。 f:id:swx-mizugaki:20200825120542p:plain

S3バケット

  • バケットを作成します(名前は任意でOK)
  • 設定はデフォルトのまま(静的サイトホスティングは不要です
  • HTMLファイルを格納します
    • 今回は画像とテキストを表示するindex.htmlを作成しました
    • ページ内で表示する画像はBase64エンコードして、HTMLファイルに埋め込んでます

IAM Role

  • API GatewayがS3バケットにアクセスするための実行ロールを作成します
  • ユースケースの選択でAPI Gatewayを選択して作成したロールに、AmazonS3ReadOnlyAccess をアタッチします

API Gateway

S3の前段に配置するAPI Gatewayを作成します

  • REST API

f:id:swx-mizugaki:20200825114146p:plain

  • アクション > メソッドの作成 > GET
    • 統合タイプ:AWSサービス
    • AWSリージョン:S3バケットを作成したリージョンを指定
    • AWSサービス:Simple Storage Service(S3)
    • HTTPメソッド:GET
    • アクションの種類:パス上書きの使用
    • パス上書き:S3バケット名/格納したHTMLファイル名
    • 実行ロール:作成したIAM Role ARN
    • コンテンツの処理:パススルー

f:id:swx-mizugaki:20200825114224p:plain

  • 作成後に以下の設定を行います
    • メソッドレスポンスのステータス200で返す本文を application/json から text/html に変更します
    • これにより、HTMLが返るようになります

f:id:swx-mizugaki:20200825114304p:plain

  • デプロイしてエンドポイントを確認します

f:id:swx-mizugaki:20200825114334p:plain

表示してみる

API GatewayのエンドポイントURLにブラウザからアクセスすると、S3に格納したHTMLページが表示されます。 f:id:swx-mizugaki:20200825114356p:plain

API Gatewayにカスタムドメイン&ACM発行のSSL証明書をあてる

  • 作成したAPI Gatewayにカスタムドメイン&SSL証明書をあててみます
  • 注意としては、以下の2点になります
    • ACMの証明書はAPI Gatewayと同じリージョンで発行したものが対象になります
    • 作成する際のドメイン名は Route53のレコードセットを作成する際のドメイン名と同じ にする必要があります

docs.aws.amazon.com

カスタムドメイン名

f:id:swx-mizugaki:20200825114546p:plain

APIマッピング

  • カスタムドメインを作成後に、画面下部の APIマッピング からマッピングの設定を行います
  • API:作成したAPI Gateway
  • ステージ:デプロイ時のステージを指定
  • パス:あれば(今回はないので設定は不要)

f:id:swx-mizugaki:20200825114607p:plain

Route53

  • 対象のホストゾーンに対象のドメイン名でレコードセットを作成します
  • タイプ:A - IPv4アドレス
  • エイリアス:はい
    • エイリアス先:作成したAPI GatewayのAPI(カスタムドメインの設定後に表示される値)

f:id:swx-mizugaki:20200825114711p:plain

表示してみる

f:id:swx-mizugaki:20200825114729p:plain

無事、カスタムドメイン&HTTPSで表示されましたね。

誰かの役に立てば幸いです。ではまた。