技術課の水垣です。こんにちは。
今日はちょっと盲点だった構成について書こうと思います。
通常であれば、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で使うって固定観念に完全に囚われてました・・・
構成図
青色の網掛け部分が今回の設定対象になります。
S3バケット
- バケットを作成します(名前は任意でOK)
- 設定はデフォルトのまま(静的サイトホスティングは不要です)
- HTMLファイルを格納します
- 今回は画像とテキストを表示するindex.htmlを作成しました
- ページ内で表示する画像はBase64エンコードして、HTMLファイルに埋め込んでます
IAM Role
- API GatewayがS3バケットにアクセスするための実行ロールを作成します
- ユースケースの選択でAPI Gatewayを選択して作成したロールに、
AmazonS3ReadOnlyAccess
をアタッチします
API Gateway
S3の前段に配置するAPI Gatewayを作成します
- REST API
- アクション > メソッドの作成 > GET
- 統合タイプ:AWSサービス
- AWSリージョン:S3バケットを作成したリージョンを指定
- AWSサービス:Simple Storage Service(S3)
- HTTPメソッド:GET
- アクションの種類:パス上書きの使用
- パス上書き:S3バケット名/格納したHTMLファイル名
- 実行ロール:作成したIAM Role ARN
- コンテンツの処理:パススルー
- 作成後に以下の設定を行います
- メソッドレスポンスのステータス200で返す本文を
application/json
からtext/html
に変更します - これにより、HTMLが返るようになります
- メソッドレスポンスのステータス200で返す本文を
- デプロイしてエンドポイントを確認します
表示してみる
API GatewayのエンドポイントURLにブラウザからアクセスすると、S3に格納したHTMLページが表示されます。
API Gatewayにカスタムドメイン&ACM発行のSSL証明書をあてる
- 作成したAPI Gatewayにカスタムドメイン&SSL証明書をあててみます
- 注意としては、以下の2点になります
- ACMの証明書はAPI Gatewayと同じリージョンで発行したものが対象になります
- 作成する際のドメイン名は
Route53のレコードセットを作成する際のドメイン名と同じ
にする必要があります
カスタムドメイン名
APIマッピング
- カスタムドメインを作成後に、画面下部の
APIマッピング
からマッピングの設定を行います - API:作成したAPI Gateway
- ステージ:デプロイ時のステージを指定
- パス:あれば(今回はないので設定は不要)
Route53
- 対象のホストゾーンに対象のドメイン名でレコードセットを作成します
- タイプ:A - IPv4アドレス
- エイリアス:はい
- エイリアス先:作成したAPI GatewayのAPI(カスタムドメインの設定後に表示される値)
表示してみる
無事、カスタムドメイン&HTTPSで表示されましたね。
誰かの役に立てば幸いです。ではまた。