2年半Amplifyを使い続けてたどり着いた開発構成

本記事は [AWS Amplify Advent Calendar 2021](https://qiita.com/advent-calendar/2021/amplify)の17日目の記事です。

# はじめに
Amplifyを使い始めて、早2年半。AWSとはなんぞや？の状況から最初に出会ったのがAmplifyで、これまで色々と大変お世話になってきました。

今回は、ユーザーが利用するWEBサイト(以下、WEBサイト)とそのサイトを管理する管理サイト(以下、管理サイト)を別リポジトリ/別ドメインで管理する開発構成について書いていきたいと思います。

# やりたいこと
- WEBサイトと管理サイトを別リポジトリ/別ドメインで管理する
- バックエンドは管理サイトでのみ管理し、基本的にWEBサイトでの開発では触らない

# 環境
- Amplify CLI 5.1.1 (まだv7試せておりません、、、。)
- aws-amplify 3.4.3
- nuxt.js 2.15.7
- node 14.17.3
- npm 6.14.13


# 初期設定
基本的なAmplifyConsoleやAmplifyCLIでの設定については、割愛しておりますので、予めご了承ください。

## １）管理サイト側でバックエンドを作成
### 1. バックエンド作成
まずはバックエンドを管理するための管理サイトを一番最初に作成します。
通常フローで`$ amplify init`、`$ amplify push`を行い、必要なバックエンドを作っていきます。

### 2. AmplifyConsoleでアプリの設定
上記のバックエンドを作成すると、AmplifyConsoleにアプリが作成されていると思いますので、AmplifyConsle用に新しいロールを作成し、初回ビルドまで済ませておきます。

## ２）WEBサイト側で管理サイトで作成したバックエンドと紐付け

### 1. amplify pullコマンドの実行
WEBサイトを作成し、プロジェクト直下で以下のコマンドを実行します。

```console
$ amplify pull
? Select the authentication method you want to use: AWS profile
? Please choose the profile you want to use amplify_net_no_madoguchi  // 管理サイトで設定した同じ権限を選択する
? Which app are you working on? d3exxjamvea55r // 管理サイトのアプリを選択する
? Pick a backend environment: enecomdev // ここではといあえずdevでOK
? Choose your default editor: Visual Studio Code // 管理サイトと同じにする
? Choose the type of app that you're building javascript  // 管理サイトと同じにする

Please tell us about your project
? What javascript framework are you using vue  // 管理サイトと同じにする
? Source Directory Path:  src  // 管理サイトと同じにする
? Distribution Directory Path: dist  // 管理サイトと同じにする
? Build Command:  npm run-script build  // 管理サイトと同じにする
? Start Command: npm run-script serve  // 管理サイトと同じにする
? Do you plan on modifying this backend? No // バックエンドのは触らないのでNoにするが、後述するamplifyフォルダを残したい条件に当てはまるときはYes)
```

これで、src直下にいちばん大切な`aws-exports.js`のファイルが生成されます。

この次は、AWS CLIが開発プロジェクトのAWSアカウントで設定してある場合かどうかで、対応方法が変わります。

### 2-1. AWS CLIが開発プロジェクトのAWSアカウントで設定してある場合
以下のコマンドでgraghqlのフォルダ/ファイルおよびaws-exports.jsを生成します。

```console
$ aws appsync get-introspection-schema --api-id ${APPSYNC_APP_ID} --format JSON schema.json
$ amplify codegen add
$ amplify codegen
```
`APPSYNC_APP_ID`は管理サイトで作成したバックエンドのAppSyncのAppIdです。先程生成された`aws-exports.js`の`aws_appsync_graphqlEndpoint`に記載されているURLのappsyncの直前の文字列のどちらかを参照してください。

### 2-2. AWS CLIが開発プロジェクトのAWSアカウントで設定していない場合
2-1で対応した内容について手動での対応になります。

#### Ⅰ. プロジェクト直下に.graphqlconfig.ymlを作成します。

```yaml:.graphqlconfig.yml
projects:
  Codegen Project:
    schemaPath: schema.json
    includes:
      - src/graphql/**/*.js
    excludes:
      - ./amplify/**
    extensions:
      amplify:
        codeGenTarget: javascript
        generatedFileName: ''
        docsFilePath: src/graphql
        region: ap-northeast-1
        apiId: null
        frontend: javascript
        framework: vue
        maxDepth: 3
extensions:
  amplify:
    version: 3
```
基本的には、 上記のコピペで良いですが、管理サイトの上記ファイルのamplifyのversionが違う場合は、同じ数字に変更してください。

#### Ⅱ. プロジェクト直下にschema.jsonを作成
管理サイトの`src/graghql/schema.json`内をコピーし、プロジェクト直下に新規作成します。

この時、必ず`.graphqlconfig.yml`のschemaPathに記載されている場所に、`schema.json`を作成してください。（2-1を実行するとプロジェクト直下に生成されたのでプロジェクト直下指定にしていますが、schemaPathにを変更すれば管理サイト同様に`src/graghql/`フォルダ内でも問題ありません。）

#### Ⅲ. graghqlフォルダ/ファイルを生成

```console
$ amplify codegen
```
srcフォルダ直下に`graghql`フォルダが作成され、各ファイルが生成されます。

#### Ⅳ. gitignoreにamplifyフォルダを追加
今回のフローではamplifyフォルダは作成されないので、追加しなくても問題はありませんが、何かの拍子でできなくもないので、念の為、gitignoreにも記載しておきます。

```:.gitignore
amplify
```

#### Ⅴ. aws-amplifyの設定
aws-amplifyをインストールします。

```
$ npm i aws-amplify
```

pluginsにamplifyの設定処理のファイルを作成します。
（nuxt.js出ない方は、aws-amplifyが動くように設定を行ってください。）

```javascript:plugins/amplify.js
import awsconfig from '@/aws-exports'
import Amplify, * as AmplifyModules from 'aws-amplify'
import Vue from 'vue'
Amplify.configure(awsconfig)

Vue.use(AmplifyModules)
```

上記のファイルを読み込むようにnuxt.configに記載します。

```javascript:nuxt.config.js
export default {
  plugins: [
    { src: '~plugins/amplify.js' },
  ]
}

```

## ３）AmplifyConsoleの設定
基本的には、AmplifyConsoleのGUIから操作を行っていきます。

### 1. アプリ作成
まずは、AmplifyConsoleのGUIから新しいアプリケーション=>ウェブアプリケーションをホストを選択して、新しいアプリを作成します。

### 2. ロールの指定
選択するロールは、管理サイトのAmplifyConsoleで指定しているロールと同じロールを指定します。

![スクリーンショット 2021-12-07 14.39.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252427/b7950466-0bfe-23d2-b4e0-92dff0a4a622.png)

### 3. ビルドを停止
アプリを作成後、初回のビルドが走りますが、まだバックエンド紐付けていないので、一旦停止させます。

### 4. バックエンドの紐付け
継続的なデプロイ設定から、管理サイトのアプリおよびバックエンドを指定し、フルスタックデプロイを無効にします。

![スクリーンショット 2021-12-07 14.52.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252427/376a038e-e2b3-f0a7-8a41-d67d9674f715.png)

![スクリーンショット 2021-12-07 14.52.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252427/bc36d027-d59d-1260-e43a-2b7c9f5f247b.png)


### 5. 再ビルド
これで設定は整いましたので、先程停止した初回のビルドを再ビルドして完了です。

# バックエンドの更新方法
バックエンドの更新は、①AmplifyCLIで$ amplify push で更新する方法と、②AmplifyConsoleのフルスタックデプロイによって更新する方法の2パターンがあります。

今回の構成では、バックエンドの開発は全て管理サイトに任せているため、以下のような設定をして更新します。

||  $ amplify push  | フルスタックデプロイ |
| ----| ---- | ---- |
| WEBサイト(開発) |  実行しない  |  OFF  | 
| 管理サイト(開発) | 実行する |  OFF  |
| WEBサイト(本番) | 実行しない  | OFF | 
| 管理サイト(本番) | 場合によって実行する  | ON |

基本的に、開発環境ではAmpifyCLIで更新し、本番環境への反映はフルスタックデプロイに任せています。

上記の構成を前提に、更新方法について書いていきます。

## １）バックエンドの更新は管理サイト側で行う
バックエンドの更新は、管理サイトでのみ行います。

## ２）必要に応じてWEBサイトに反映させる
基本的な流れは、WEBサイトの`schema.json`を更新して、`$ amplify codegen`を実行します。

### 1. amplify pullコマンドの実行
WEBサイト側の`aws-exports.js`の更新のために、`$ amplify pull`を実行します。`aws-exports.js`が変わっていないことが明確であれば、実行しなくても問題はありません。
(WEBサイト側にもamplifyフォルダを作成している場合は、必ず実行が必要です。)

### 2-1. AWS CLIが開発プロジェクトのAWSアカウントで設定してある場合
下記コマンドで各ファイルを更新します。

```console
$ aws appsync get-introspection-schema --api-id ${APPSYNC_APP_ID} --format JSON schema.json
$ amplify codegen
```

### 2-2. AWS CLIが開発プロジェクトのAWSアカウントで設定していない場合
手動で管理サイトの`schema.json`をWEBサイトの`schema.json`にコピペして、以下のコマンドを実行するだけです。

```console
$ amplify codegen
```

# メモ/補足
この開発構成で気になっていること。

## WEBサイト側のamplifyフォルダについて
基本はWEBサイト側ではamplifyフォルダは生成しない前提で記事を書いていますが、作成したほうがいい場合もあります。

- WEBサイト側の本番環境でフルスタックデプロイを行いたい(これ割と大事かも、、、。このことを踏まえたベストプラクティス構成を導き出したい)
- WEBサイト側で、本番環境のバックエンドでテストがしたい( `$amplify env checkout prod`のコマンドを実行したい)
- 管理サイトのコードを見れないフロントエンド開発者が`schema.graphql `を確認したい
- WEBサイト内でamplifyのコードをチェックしたい

## team-provider-info.json
フルスタックデプロイ任せにしてれば問題はないのですが、git上の`team-provider-info.json`の情報が更新されないので、prodが古い情報になりがちなので、なにかもトラブルのものにならないかちょっとだけ気にしています。

## WEBサイトでフルスタックデプロイをしたい
WEBサイトでフルスタックデプロイをしたい場合は、一番最初のamplify pullの最後の質問にYesと答えましょう。

```
? Do you plan on modifying this backend? Yes
```

これで、amplifyフォルダが生成されます。


バックエンドの更新については、以下のような構成になります。

||  $ amplify push  | フルスタックデプロイ |
| ----| ---- | ---- |
| WEBサイト(開発) |  実行しない  | OFF |  
| 管理サイト(開発) | 実行する | OFF |
| WEBサイト(本番) | 実行しない  | ON | 
| 管理サイト(本番) | 場合によって実行する | OFF |

WEBサイトを本番環境にデプロイするときは、以下の2つのコマンドの実行を絶対に忘れないでください。

1. $ amplify pull -y
1. $ amplify codegen

忘れると当然のことながら、管理サイトで作成したバックエンドたちが本番環境に反映されなくなります。
(こういうことを考えると、そもそもWEBサイト側でバックエンド作業も行ったほうがいいのか？とも思えてくる、、、。何がベストなんだろう、、、。)

# おわりに
この記事が、少しでも誰かの参考になれば幸いです！
そして、うちはこんな構成でやっているよ、だったり、これ大丈夫？的なことあれば、コメントいただけたら嬉しいです。

引き続き、Amplifyを楽しんで使っていきたいと思います！！

# 参考サイト
https://dev.classmethod.jp/articles/amplify-tips-series-1/