AWSでサーバーレスな開発用HTTPSシングルページアプリケーションを立ち上げる方法


本記事について

シングルページアプリケーションを作っていて、外部には公開したくないが、ローカル以外のサーバーに置いて配信テストをしたいことがあったので、その時の構築メモです。

要件

静的配信だし、S3を使えばサーバー立てなくてもAWSのサービスだけでできそうな感じだったので、下記のようなものを想定しました。

  • サーバーレス(AWSのサービスを利用する・インスタンスを立ち上げない)
  • httpsで静的配信
  • http通信は不可
  • キャッシュしない(アップした更新をすぐに確認できるようにするため)
  • サブディレクトリによるルーティング可能
  • IPアドレスによるアクセス制限

手順

HTTPS静的配信

S3にファイルを置いて、Static website hostingすればいいのかなと考えていたのですが、https配信するにはCloudFrontを使う必要がありました。
また、CloudFrontで配信すれば、S3をStatic website hostingで公開する必要はなかったです。

CloudFrontのDistributionsページから[Create Distribution]-[Web]-[Get Started]と進んで配信を作成します。

Origin Settings

Origin Settings

  • Origin Domain Name
    • 公開するバケットを選択します
  • Origin Path
    • どのサブディレクトリ配下を公開するかを指定します。「/」から始まり、最後の「/」は不要です。
  • Restrict Bucket Access
    • CloudFrontを使って公開する場合、S3を公開する必要はありません。「Yes」にします。
  • Origin Access Identity
    • Identityが必要なのですが、作成していない場合「Create a New Identity」で作成します。
  • Grant Read Permissions on Bucket
    • よしなに権限設定してくれるので「Yes」にします。

Default Cache Behavior Settings

Default Cache Behavior Settings (1/2)

  • Viewer Protocol Policy
    • HTTPS配信のみを行いたいので「Redirect HTTP to HTTPS」にします。

Default Cache Behavior Settings (2/2)

  • Object Caching
    • 開発用サイトなので、ファイルをアップしたらすぐに確認したく、キャッシュをしない設定にするため「Customize」を選択します。
    • Minimum TTL・Maimum TTL・Default TTL
      • キャッシュ時間の設定。キャッシュしないので「0」にします.

Distribution Settings

Distribution Settings (1/2)

  • AWS WAF Web ACL
    • ここでIP制限をかけることができます。後からでも設定できるので「None」にしておきます。

Distribution Settings (2/2)

  • Default Root Object
    • シングルページアプリケーションの配信HTMLのファイル名を指定します。

「Create Disctibution」ボタンを押して配信を作成します。
結構時間がかかります。おそらく、想像しているより時間がかかり、動いているのかと途中心配になるかもしれませんが、忘れたころに完了します。

サブディレクトリによるルーティング

シングルページアプリケーションだと、サブディレクトリでルーティングを行うことがあるかと思います。

初期設定のままだと、サブディレクトリにファイルは無いためエラーがでてしまいます。
なので、エラーではなく配信ページを呼び出すように設定します。

先程作成した配信の詳細を開いて[Error Pages]-[Create Custom Error Response]ボタンを押して、エラー毎の挙動を追加します。

Custom Error Response

  • HTTP Error Code
    • 「404」を選択します。
  • Customize Error Response
    • エラーページではなく、配信ページを表示するため「Yes」を選択します。
  • Response Page Path
    • アプリケーションの配信HTMLファイル名を指定します。
  • HTTP Response Code
    • 「200」を選択します。

エラーコード「403」も同様に作成します。

これで、サブディレクトリにアクセスするとエラーではなく、配信ページが呼び出されるようになります。

ブラウザキャッシュ時間の設定

CloudFrontで設定したキャッシュ時間はCloudFrontのキャッシュ時間で、ブラウザのキャッシュ時間ではありません。
CloudFrontのキャッシュ時間を0にしても、ブラウザでキャッシュが有効になっていると、アクセスしても更新されません。
ですので、別途ブラウザのキャッシュを無効にする必要があります。

ブラウザがそのファイルをどれくらいキャッシュしておくかは、ファイル取得時のヘッダーの「Cache-Control」で判断し、値が「no-chache, no-store」だとブラウザはそのファイルをキャッシュしません。

CloudFrontで「Cache-Control」を設定するには、S3に置かれた大本のファイルの「メタデータ」に設定します。

S3 メタデータ

ただ、これを手動で1ファイル毎に設定するのは手間なので、AWS CLIでファイルをS3にアップする時に、フォルダごと設定するようにしました。

aws s3 cp --recursive --metadata-directive "REPLACE" \
    --cache-control "no-cache, no-store" \
    $LOCAL_PATH "s3://${UP_PATH}/"

IPアドレスによるアクセス制限

AWSのWAFでアクセス制限の設定(=ACL)を作成して、それをCloudFrontの配信に割当ます。

配信の詳細で、[General]-[Edit]-[AWS WAF Web ACL]で作成したACLを指定します。

AWS WAF Web ACL

ACLの作成は難しくはないのですが、手順が多いので、ここではIPアドレス制限のACLの作成についてザックリとだけ説明します。

  • [IP addresses]で許可するIPアドレスを作成する
  • [Rules]で指定IPアドレスにマッチした時のルール「When a request [does] [originate from an IP address in] [上記で作成したIPアドレス]」を作成する
  • [ACL]で上記のルールを追加し、「Action」を「Allow」、「Default action」を「Block」とする

以上で、CloudFrontが作成したURLにアクセスすると、S3にアップした「index.html」を起点としたSPAが読み込まれるようになります。

元記事