0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

AWS SPAをALB+S3でセキュアに公開!

0
Posted at

image.png

はじめに

SPA(Vue.js / React など)を AWS で公開する場合、S3 + CloudFront が定番構成ですが、以下のような要件では悩みが出てきます。

  • 社内向け / 特定ネットワーク向けに公開したい
  • ALB 配下に API と SPA をまとめたい
  • CloudFront を使わず ALB で制御したい
  • /xxx/yyy へのアクセスも SPA の index.html で処理したい

本記事では、ALB + S3(静的コンテンツ)構成で SPA(Vue.js)を公開 し、さらに ALB のルールで / や任意パスを /index.html に変換 する方法をまとめます。

全体構成

[ Client (Browser) ]
        |
        |  https://test.co.jp
        v
[ Application Load Balancer ]
        |
        |  Forward
        v
[ Target Group (S3) ]
        |
        v
[ S3 Bucket (Vue.js build成果物) ]

ポイント

  • CloudFront は使わない
  • ALB から S3 に直接静的ファイルを配信
  • SPA 用に ALB のルールで index.html にトランスフォーム
  • HTTPS は ALB で終端

手順

1. Vue.js をビルドする

まずは SPA を通常通りビルドします。

> npm run build

生成物(例):

dist/
 ├─ index.html
 ├─ js/
 ├─ css/
 └─ assets/

2. S3 バケットを作成し、静的ファイルを配置

  • S3 バケットを作成
  • 静的ウェブサイトホスティングは使わない
  • ALB からアクセスするため、公開設定は不要
S3 Bucket
 └─ index.html
 └─ js/
 └─ css/

3. ALB から S3 へアクセスできるようにする

ALB から S3 に直接配信するため、以下を設定します。

3-1. ALB 用の IAM ロールを作成

  • s3:GetObject を許可
  • 対象バケットを指定
{
  "Effect": "Allow",
  "Action": "s3:GetObject",
  "Resource": "arn:aws:s3:::your-bucket-name/*"
}

3-2. ターゲットグループを作成(S3)

  • タイプ:IP
  • プロトコル:HTTPS
  • ポート:443

ALB から S3 へは HTTPS + S3 のエンドポイント を利用します。

4. ALB を作成(HTTPS)

  • Application Load Balancer
  • リスナー:443
  • ACM 証明書を設定(test.co.jp)

5. ALB のルールで S3 にフォワードする

基本ルール

IF
  Host is test.co.jp
THEN
  Forward to S3 Target Group

6. SPA 用に「/ → /index.html」へトランスフォームする

ここがこの記事の 一番のポイント です。

SPA は以下のような URL を直接叩かれると、

https://test.co.jp/dashboard
https://test.co.jp/user/123

S3 に実ファイルが存在せず 404 になる 問題があります。
これを ALB のルールで解決します。

ALB リスナールール例

IF
  Path is /
THEN
  Redirect to /index.html

さらに SPA 向けの応用(任意パス対応)

IF
  Path is /*
THEN
  Forward to S3
  AND
  Rewrite path to /index.html

これにより、

  • /
  • /dashboard
  • /user/123

すべて index.html が返却され、
Vue Router 側でルーティング可能になります。

7. 動作確認

ブラウザで以下を確認します。

すべて Vue.js の画面が表示されれば成功!

おわりに

HTMLを含める全て(/api/*はもちろん)を ALB を通す事によりセキュアに構築する事は、アプリケーションで考える事が減るので、とても良いと思いました。

今回は"認証"を省いているので、次回は Cognito を含めて記事を書きたいと思います!


参考(感謝)

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?