本番環境でAmplifyを3年くらい使ってみている弊社環境のご紹介

# Amplify Boost Up \#04

Amplify Japan User Group さん主催の Amplify Boost Up の4回目に登壇したので、その内容について補足しつつまとめてみました。

https://aws-amplify-jp.connpass.com/event/300944/

資料は以下の SpeakerDeck で共有しておりますので、ご確認ください

<script defer class="speakerdeck-embed" data-id="aea909ae713f4bc3b1d15ba9d9621a24" data-ratio="1.4" src="//speakerdeck.com/assets/embed.js"></script>

## Amplify を使っている理由

我々開発運用チームは社外の方も含めて5名です。この人数で動画配信サービスの「hod」と番組関連グッズを販売している「HTBオンラインショップ」の２つのオンライン事業のシステムを担当しています。やらないことを少しでも増やすために、サーバレス構成を基本としており、その流れでAmplifyを活用しています。

だいぶ、省略した部分はありますが、以下にアーキテクチャを載せます。

[![thumbnail](https://files.speakerdeck.com/presentations/aea909ae713f4bc3b1d15ba9d9621a24/slide_11.jpg)](https://speakerdeck.com/miu_crescent/ben-fan-huan-jing-deamplifywo3nian-kuraishi-tutemiteirubi-she-huan-jing-nogoshao-jie?slide=12)

フロントエンドのデプロイ先としては **Amplify Hosting** を利用しており、フロントエンドはサービス単位、バックエンドは共通の App として構築しています。
バックエンドの中核となる AppSync と DynamoDB は **amplify-cli** を使って構築しています。
今回主題となる Amplify の外になってしまいますが、
**Lambda　や　Step Functions** は Serverless Framework を使って管理しています。

また、フロントエンドでは AppSync に GraphQL のクエリを投げるクライアントとして、**Apollo Client** を使用しています。

この構成自体はスムーズに構築できたのですが、運用上で工夫した部分について以下の3つをご紹介したいと思います。

- GraphQL の型ファイルの受け渡しについて
- 環境変数のコード管理について
- 溜まってしまった技術的負債のご紹介


[![thumbnail](https://files.speakerdeck.com/presentations/aea909ae713f4bc3b1d15ba9d9621a24/slide_12.jpg)](https://speakerdeck.com/miu_crescent/ben-fan-huan-jing-deamplifywo3nian-kuraishi-tutemiteirubi-she-huan-jing-nogoshao-jie?slide=13)


### GraphQL の型ファイルの受け渡しについて

GraphQL Code Genetator を使用して、フロントエンドで使用する TypeScript の型ファイルを生成しています。

https://github.com/dotansimha/graphql-code-generator

バックエンド側の最新状態がフロントエンドで使用する型ファイルにも反映されている必要があるのですが、フロントエンドとバックエンドでAppをわけてしまったので、この辺りの管理を考える必要があります。

バックエンド専用のAppの方に、あえて簡単なHTMLだけをおいたフロントエンドをデプロイして、合わせてこの型ファイルも一緒にデプロイする様にしています。
これで、フロントエンドのCI/CDの中で `wget` で型ファイルを取得する方法を取っています。

（他にもっとスマートなやり方があったら、ぜひ、おしえてください！！）


[![thumbnail](https://files.speakerdeck.com/presentations/aea909ae713f4bc3b1d15ba9d9621a24/slide_17.jpg)](https://speakerdeck.com/miu_crescent/ben-fan-huan-jing-deamplifywo3nian-kuraishi-tutemiteirubi-she-huan-jing-nogoshao-jie?slide=18)


### 環境変数のコード管理について

これはしばらくやり方がわかっていなくて、ずっと wiki で本番/開発の環境変数を管理して、管理者の人（私）が Amplify コンソールを操作してコピペしていくいう作業をしていました。Amplify コンソールは入力のボックスが短くて、編集画面だとすごく操作が難しいです。
とくに React を使用していると、環境変数のプレフィックスとして `REACT_APP_`　をつける必要があるのですが、これで入力欄がほぼ埋まってしまい、正しい値が入力されているのかを確認するのがすごく難しいです。


これの解決方法を探して、`amplify-cli` でいろいろ探していたのですが、環境変数に対する操作を見つけられず、諦めていました。また、環境変数で渡している値によって、決済処理をしている Step Functions を開発/本番 で叩き分けていたりするので、ミスがあると結構めんどくさ買ったです。

これの解決方法は結構簡単で `aws cli` でした。

[![thumbnail](https://files.speakerdeck.com/presentations/aea909ae713f4bc3b1d15ba9d9621a24/slide_23.jpg)](https://speakerdeck.com/miu_crescent/ben-fan-huan-jing-deamplifywo3nian-kuraishi-tutemiteirubi-she-huan-jing-nogoshao-jie?slide=24)

Amplify コンソールの操作は 以下の様な **aws cli** で実現可能でした

```shell
aws amplify update-branch --app-id <APP_ID> --branch-name <BRANCH_NAME> --environment-variables <JSON_FILE_PATH> 
```

弊社ではフロントエンドの環境変数は `.env` を使用しているため、ここから以下の VS Code の拡張を使用して、JSON ファイルを作成しています。

https://github.com/andrusch/vscode-dotenv-plus-json

これで、環境ごとの環境変数を格納したJSONをそれぞれ作成してGitで管理ができる様になりました。
もう、Amplify コンソールでの環境変数の管理はしたく無いです。

### 溜まってしまった技術的負債のご紹介

**amplify-cli** を使うと簡単に、スキーマを定義するときに 簡単なディレクティブを指定してあげるだけで、バックエンドを作成してくれます。
AppSyncとDynamoDBだと、AppSyncからDynamoDBを繋ぐリゾルバーをいい感じで作ってくれたりするわけです。意識しなくてもよいので最高です。

この中のひとつで `@connection` ディレクティブというのがあって、これを使うと、DynamoDBのテーブル間を繋げて、データを持ってくることができます。

簡単がゆえに、機能追加に合わせて気軽に使ってしまったのですが、これが積もり積もって、大変なことになった。のです。
これにより、AppSyncのとあるQuotaに引っかかる様になってしまって。。。

[![thumbnail](https://files.speakerdeck.com/presentations/aea909ae713f4bc3b1d15ba9d9621a24/slide_26.jpg)](https://speakerdeck.com/miu_crescent/ben-fan-huan-jing-deamplifywo3nian-kuraishi-tutemiteirubi-she-huan-jing-nogoshao-jie?slide=27)


この辺りは話すと長くなってしまうので、今回では特に触れませんが、他の資料がありますので、ご参考までに。
根本的な解決は大規模なリファクタリングが必要そうだったので、 **Momento** を活用してなんとか回避したお話です。
以下のブログや資料をご確認ください。

https://qiita.com/miu_crescent/items/abe122734b6727786038

<script defer class="speakerdeck-embed" data-id="34087a16bb5545b38c9714912f7fc253" data-ratio="1.4" src="//speakerdeck.com/assets/embed.js"></script>


ちなみに、このスキーマを定義するだけで、バックエンドを構築してくれる部分を担っているいろんなディレクティブ群は「GrapQL Transformer」というのですが、これの version 1 をずっと使っていたのすが、v2 が出てきており、この変更も対応できておりません。

ちなみに `@connection` が `@hasOne` や `@hasMany` などに変更されています。

https://docs.amplify.aws/javascript/tools/cli/migration/transformer-migration/


## まとめ

Amplify のおかげで、爆速でリリースができたのは間違いありません。
AppSyncも自分でリゾルバーをいきなり書くのはなかなか辛いものがあると思いますが、まずはAmplifyから入って、動いてるものを見てきたからこそ深まった理解もあります。

[![thumbnail](https://files.speakerdeck.com/presentations/aea909ae713f4bc3b1d15ba9d9621a24/slide_29.jpg)](https://speakerdeck.com/miu_crescent/ben-fan-huan-jing-deamplifywo3nian-kuraishi-tutemiteirubi-she-huan-jing-nogoshao-jie?slide=30)

技術的負債は結構溜まってきてしまいましたが、DynamoDBの特性に合わせた使用方法をちゃんとできていなかったで、我々の使い方が問題だったと思います。これを改善するべくリファクタをしていきたいといろいろ調査していた矢先に、「Amplify Gen 2」が発表されました。

https://aws.amazon.com/jp/blogs/news/introducing-amplify-gen2/

まだ、ちゃんと調査できていないのです、今回紹介したペインポイントがいろいろ解決できそうな点が紹介されていたので、積極的に活用していきたいと考えてきます。（特にammplify-cliでやっていた部分がファイル定義ベースになりそうなので期待。）

CDK勉強しよう。。。