Vue + AWS(S3 + CF) でシンプルにPWAアプリを公開する

最近趣味で作成した [Enjoy Coffee](https://enjoy-coffee.nioufuku.net) は、 Vue.js + PWA を AWS(S3 + CloudFront) でリリースしたので、その手順をまとめておこうと思います。

## 目次
1. 前提条件
2. ACM でSSL証明書を作る
3. S3 のバケットを用意する
4. CloudFront を設定する
5. Route 53 にドメインの設定をする
6. Vue アプリを S3 にアップロード
7. まとめ

## 1. 前提条件
本記事は、以下を前提に記載しています。

- AWS のアカウントは作成済み
- 公開するドメインはあらかじめ Route 53 で管理している
- Vue.js + PWA のサンプルは準備できている


## 2. ACM(AWS Certificate Manager) でSSL証明書を作る
今回はHTTPSで公開したかったので、まず ACM でSSL証明書を作ります。
各所で記載されていますが、 CloudFront で参照するSSL証明書はリージョンを **米国東部(バージニア北部)** にしておく必要がありますので、注意が必要です。
(既に用意できている場合はスキップしてください)

1. AWS マネジメントコンソールで Certificate Manager を開く
2. リージョンを **米国東部(バージニア北部)** にする
3. 「証明書のリクエスト」をクリックして手順を進める
4. デフォルトの「パブリック証明書のリクエスト」にチェックを入れたまま 証明書のリクエスト で手順を進める
5. リリースで使うドメインを「ドメイン名(ex: example.xxxxxx.net)」に入力して 次へ
6. Route 53 で検証を進めるため、デフォルトの「DNSの検証」にチェックを入れたまま 確認
7. 内容を確認して 確定とリクエスト で手順を進める
8. 入力したドメインの左側の三角マークを押すと、「Route 53でのレコードの作成」をクリックすると自動で検証用のレコードをRoute 53に登録してくれるので、クリック！
9. 検証が完了すると自動でSSL証明書が作成されて「発行済み」になります(自分の場合はたいてい10分程度で終わります)

最近はとてもこのサービスにお世話になってます。

## 3. S3 のバケットを用意する
Vue アプリを保存するバケットを用意します。

1. AWS マネジメントコンソールで S3 を開く
2. 「バケットを作成する」で手順を進める
3. 「1 名前とリージョン」バケット名は任意(ex: example.xxxxxx.net)で、リージョンはお好み？(自分は東京リージョンを使ってます)を、 次へ
4. 「2 オプションの設定」は必要に応じて設定してください(サンプルレベルならスルーで進められます)
5. 「3 アクセス許可の設定」特別許可が必要なければ何もせずに 次へ でバケットを作成
6. バケット一覧から作ったバケットのバケット名をクリックして「プロパティ」を開く
7.  「Static website hosting」の無効あたりをクリックして「このバケットを使用してウェブサイトをホストする」にチェックして、
8. インデックスドキュメントに「index.html」を入力して保存する

Lambdaを利用することで6〜8を不要にする方法もありますが、今回は割愛します。

## 4. CloudFront を設定する
作成した S3 のバケットを CF 経由でアクセスするように設定をしていきます。
(S3のリクエスト数を減らせますね)

1. AWS マネジメントコンソールで CloudFront を開く
2. 「Create Distribution」で手順を進める
3. Web の方の「Get Started」で手順を進める
4. Origin Domain Name に先程作成した S3 を指定する(このとき Origin ID もセットされます、 Origin Path はスルー)
5. Restrict Bucket Access を「Yes」に変更し、 Origin Access Identity を「Create a New Identity」に変更する
6. Grant Read Permissions on Bucketを「Yes, Update Bucket Policy」にする(5と6でCF側からS3のアクセス設定を良い感じにしてもらいます)
7. 常時HTTPSにしたかったので、Default Cache Behavior Settings の Viewer Protocol Policy を「Redirect HTTP to HTTPS」に変更(こちらは任意)
8. Distribution Settings の Alternate Domain Names(CNAMEs) にリリースで使う「ドメイン名(ex: example.xxxxxx.net)」を入力
9. SSL Certificate を Custom SSL Certificate にチェックを入れ、先程作成したSSL証明書を選択
10. Default Root Object に「index.html」を入力して、「Create Distribution」をクリックして作成 ※作成完了まで20分程度かかります
11. AWS マネジメントコンソールの Cloud Front の Distributions(画面左上) を選択して一覧を表示し、作成した Distribution の Domain Name をコピっておく(次で使います)

自分は開発用の環境はキャッシュのTTLを0にしたりしています。
その他必要に応じて適宜修正してください。

## 5. Route 53 にドメインの設定をする
いよいよ公開する設定を進めます。

1. AWS マネジメントコンソールで Route 53 を開く
2. Hosted zones で今回使用するドメインを管理しているゾーンを開く
3. 「Create Record Set」で Name にリリースで使う レコード名(ex: example) を入力、 Alias を「Yes」にして Alias Target に先程の Distribution の Domain Name を入力して「Create」

あとはドメイン名を引けるようになるのを待つのみです。

## 6. Vue アプリを S3 にアップロード
ドメイン名が引けるようになるまでに、Vue アプリを S3 にアップロードします。
Vue アプリは

```
$ npm run build
```
でビルド済みとします。

自分は手元の環境に aws-cli を入れて

```
$ aws s3 cp dist s3://example.xxxxxx.net --recursive
```
のような感じでアップロードしています。(本当はデプロイツールでいい感じにするべき。。。)

## 7. まとめ
リリース後はバージョンアップのタイミングで6の手順と同じくアプリをアップロードし、 CloudFront の Invalidations でキャッシュをクリアしてあげるとバージョンアップ版がリリースできる流れになります。
ちなみに Vue アプリ以外でもこの S3 + CloudFront の仕組みは全然活用できるので、自分はブログをこの方法で運用していたりします。

おそらく Vue アプリから WebAPI を呼び出すようなことをし始めるとこれだけの仕組みでは足りないと思いますので、その辺りは自分がやり始めたときに記事にできればと(いつになるか。。。)

今回のまとめはサンプルレベルになりますので、S3やらCF周りは各運用に合わせてチューニングをしながら使っていただいた方が良いかと思います。
本記事の設定を使う場合はあくまでも自己責任でよろしくお願いしますm(_ _)m