Vue.js、AWS Amplifyおよびboto3でサンプルアプリを作ってみる（第二回：Amplifyとバックエンドリソース編）

前回はVue.jsと関連コンポーネント一式をセットアップし、動確するところまで完了。
第二回となる今回は、AWS Amplifyを使ってバックエンドリソースを作成するのと、`git push`をトリガーとしてCICDパイプラインを一周させるところまでをやってみる。

前回の内容はこちら。
[Vue.js、AWS Amplifyおよびboto3でサンプルアプリを作ってみる（第一回：Vue.jsセットアップ編）](https://qiita.com/itsuki3/items/b864116beb0f44d84e37)


## （今回）やりたいこと
- AWS Amplifyをセットアップする
- AWSバックエンドリソースをCLIで作ってみる
- AmplifyによるCICDパイプラインを回してみる

## そもそもAWS Amplifyとは
AmplifyはWeb/モバイルアプリをラクに作るためのサービスで、用途は大きく三つ。

- AWSバックエンドリソースを簡単に作り、使う。
    - 通常、WebアプリをホストするにはS3（コンテンツホスティング）を始めCloudFront（CDN）、Route 53（DNS）、ACM（証明書）、Cognito（認証）、DynamoDB（NoSQL）、API Gateway（API）、Lambda（関数）等々をしかるべくセットアップする必要がある。
    - Amplifyの場合、Amplify CLIを使って`amplify XXX`とするだけで、目的に沿ったサービスを勝手に構成してメンテしてくれる。ラク。 
- ツールを使う。
    - 大概の設定や操作はCLI（[Amplify CLI](https://docs.amplify.aws/cli)）で、ビルド設定や独自ドメイン設定・ログ追跡など地味に面倒な作業はWebコンソールでできる。ラク。
    - CICDパイプラインをマネージドで用意してくれる。CodePipelineやCodeBuildを自動構成するのかと思ったら、少なくとも表にはそれらのリソースは出てこなかった。メンテフリーということで、これもラク。
- フロントエンド開発支援機能を使う。
    - [ライブラリ](https://docs.amplify.aws/lib/q/platform/js)や[UIコンポーネント](https://docs.amplify.aws/ui/q/framework/vue)が提供されている。GraphQLも使える。
    - 前にも書いた通り自分は初学者なので、このあたりは今回それほど深入りしていない。例えばライブラリは使っていない（代わりにaxios + API Gatewayを介してAWSサービスにアクセスする）し、UIコンポーネントはElement UIを先に知ったのでそっちで作ってしまった。

## Step by Step

### 1. Amplify CLIのインストール
まずはCLIをインストールする。

```
% npm install -g @aws-amplify/cli
```

Amplify CLIについては[公式](https://docs.amplify.aws/start/getting-started/installation/q/integration/vue)の他、以下も参考にさせていたきました（感謝）。
[AWS Amplify CLIの使い方〜インストールから初期セットアップまで〜](https://qiita.com/Junpei_Takagi/items/f2bc567761880471fd54)

### 2. Amplifyの認証/認可設定
CLIをインストールしたら、プロジェクトルートに移動した上で、AWSアカウントを使うための認証/認可設定をする。
AWS CLIなどと同じで、IAMを使って認証/認可を行う。より正確には、

- 認証：署名バージョン4（SigV4）、いわゆるアクセスキー/シークレットキーによる署名
- 認可：IAMポリシー

...で行う。ここでやることは、そのためのIAMのセットアップとキーの保存。

```
% cd ~/SPA/my-amplify-app
% amplify configure
```

詳細は上記の記事や公式に詳しいので、ここでは省略。

### 3. バックエンドの初期化
AmplifyがAWSのバックエンドリソースを操作するための初期設定をする。
CICDのためのビルドコマンドなどもここで、言語と一緒に指定する模様。

```
% amplify init
```

実行すると色々なプロンプトが出るので、しかるべく設定すると、ビルド設定（amplify.ymlに相当）やS3バケット、IAMロールなどが出来上がる。後で出てくる定数定義用ファイル`src/aws-exports.js`も、このタイミングで作成されるようだ。
完了したら以下のコマンドで現況確認。

```
% amplify status
```

ここまで進めば、バックエンドリソースの作成の準備は完了。

### 4. バックエンドリソースの構成
AWSバックエンドリソースは、いずれも`amplify add XXX`で構成する。
主だったものは以下。

|コマンド|概要|関連するAWSサービス|
|:---|:---|:---|
|amplify add auth|認証用リソース|Cognito|
|amplify add hosting|Webホスティング用リソース|CloudFront, S3|
|amplify add api|API用リソース|API Gateway, AppSync|
|amplify add function|関数用リソース|Lambda|

ここで作りたいのはWebホスティング環境なので、以下のコマンドを実行する。

```
% amplify add hosting
```

あれこれと試行錯誤して分かったのは、Webホスティングのオプションには**セルフマネージド**と**Amplifyマネージド**の二種類があるということ。

- **セルフマネージド**の場合、CloudFrontディストリビューションやS3バケットは自動作成されるが、ユーザーのマネジメントコンソールに出てくる。またRoute 53やACMは、それぞれのコンソールで別途作業する必要がある。CICDは、レポジトリを接続した上で`git push`するか、`amplify publish`で簡易にやるかを選ぶ。
- **Amplifyマネージド**の場合、CloudFrontとS3は完全マネージドとなり、ユーザーのマネジメントコンソールから確認することはできない。Route 53やACMも、Webコンソールから構成できる（DNSや証明書はオープンな仕組みなので、リソース自体はさすがに各コンソールに出てくる）。CICDは完全マネージドで、レポジトリへの`git push`一択となる。なおこちらの場合、選択後マネジメントコンソールに移動するので、プロジェクトを選択し、CICD用のレポジトリプロバイダを選択する（ここではCodeCommit）。CloudFront/S3は、その存在すら意識することなく、フルマネージドで構成される。

両方試した結果、ここではあえて**Amplifyマネージド**で運用してみることを選択。
インフラにそれなりに知見があり、運用上の可視性を高めたいということであれば、**セルフマネージド**でもよいのではないかと感じた。少なくとも、こっちの方が勉強にはなる。

### 5. バックエンドリソースのデプロイ
バックエンドリソース作成後、`amplify push`を実行すると、バックエンドをデプロイしてくれる。
ちなみに`amplify publish`とすると、フロントエンド（コンパイル+デプロイ）とバックエンドのデプロイを一緒にやってくれる。事前に`amplify add hosting`と、CICDの構成が条件。
さらに余談だが、`amplify serve`とすると、`amplify push`でバックエンドをデプロイ/更新した上で、テストサーバーを`npm run serve`で起動してローカルテストさせてくれる。`https://localhost:8080`でローカルにアクセスすれば、実際にデプロイされたAWSバックエンド込みで、あれこれテストできるというわけだ。AWSリソースは実際に出来上がっているので、本番デプロイと遜色ないレベルで動確ができたりする。便利な世の中になった。

脇道に逸れたが、ここではひとまずバックエンドだけ構成できればよいので、以下を実行する。

```
% amplify push
```

### 6. ビルド設定の確認
何度かビルドに失敗し、試行錯誤の結果、辿り着いたビルド設定は以下の通り。
なお、ブランチ固有の設定が必要なければ、グローバルに適用されるビルド設定を、Webコンソール上で設定しておけばよい。ブランチ固有の設定が必要であれば、amplify.ymlとしてダウンロードしておく。

```yaml
version: 0.1
backend:
  phases:
    build:
      commands:
        - '# Execute Amplify CLI with the helper script'
        - amplifyPush --simple
frontend:
  phases:
    preBuild:
      commands:
        - npm ci
    build:
      commands:
        - npm run build
  artifacts:
    baseDirectory: dist
    files:
      - '**/*'
  cache:
    paths:
      - node_modules/**/*
```

### 7. ビルドテスト
うまく設定されていれば、Vue.jsのコード編集後、プロジェクトルートで以下のコマンドを実行するだけでフルオートでCICDが回り、パブリックにWebアプリを公開してくれる。

```
% git add .
% git commit -m "（コメント）"
% git push -u origin master
```

動いた。
<img width="1154" alt="サンプルアプリ" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/609876/51783825-9d4a-0843-0474-39fe84485baf.png">

参考までに、ビルド周りの落ち穂拾い。

- `amplify init`の過程でビルドコマンド（`npm run build`）やテストサーバー起動コマンド（`npm run serve`）を指定するが、誤ったコマンドを入力してしまっていないか確認する。自分はここで誤って`npm run start`と謎の文字列を入力してしまい、後続のビルドステップで1時間ほど無駄にした。

- `npm run build`でXcodeが見つからない旨のエラーが出る場合は、開発環境のMacを一度疑ってみる。以下を参考に、Xcodeやnode_modulesを再インストールしてみると動くかも。

[Macでyarn installしたらnode-gypのエラーが出た](https://qiita.com/hppRC/items/a01e33a5c890f7b2c125)
[【初心者】npm ERR! の対処法](https://qiita.com/wafuwafu13/items/2fe43414aa6e1899f494)

- `awsexports.js`が見つからないエラーの場合は、`.gitignore`で除外されていていないか念のため確認する。自分の場合は、何故かAmplifyが自ら除外していていた。

今回はここまで。
次回はAmplifyからaxios経由でAPIを呼び出し、AWS上のデータを引っ張ってくるところをトライする。