amplify delete で全て無にする話

# 概略

PoC で構築した Amplify ベースの Web アプリをまるっと消しこむことがあったので, その話を書きます。
`amplify delete` で一気にやります。

## amplify delete とは

Amplify CLI で使えるコマンドのうち, `amplify delete` というものが存在します。

手が滑って以前の PoC 案件で `amplify delete` してしまって空を仰いだことがあるのですが, このコマンド, 軽率に打ち込める割にパワーがあります。
ざっくり一言で表すと, Amplify で管理されているものを全て消すコマンドって感じです。

ちなみに `amplify help` で得られる情報は以下。

```bash
$ amplify help
  ... ...
  delete    Deletes all of the resources tied to the project from the cloud.
```

クラウド上から現在のプロジェクトに関連するリソースを全て削除する, とのこと。

実際に打ち込んでみると以下。

```bash
$ amplify delete
? Are you sure you want to continue? This CANNOT be undone. (This will delete all the environments of the project from the cloud and wipe out all the local files created by Amp
lify CLI) (y/N)
```

赤字で警告してくれます。コマンドのヘルプよりも詳しい情報をくれます。

- クラウドから全環境のリソースを全て削除
- Amplify CLI で作成されたローカルのファイルを全て削除

ここで言っている全環境というのは, `amplify add env` とかで追加した環境全てを指します。
現在の Amplify CLI で認識させている `Current Environment` だけを消してくれると思っているとしくじります。

## amplify delete 実践

では, `amplify delete` で消していきます。
残念ながら, 今回の PoC 案件では 1 環境しか作っていないので消されるのは全環境といっても 1 環境のみになります。

今回使う Amplify CLI の Version は [6.3.1](https://github.com/aws-amplify/amplify-cli/releases/tag/v6.3.1) になります。（2021/10/13 提供のものです。）

```bash
$ amplify --version
6.3.1
```

### 事前確認

まずは現状の確認です。
以下コマンド結果上の `Resource name` はマスクのため適当に書き換えさせてもらいました。構成は以下になります。

<dl>
  <dt>Hosting</dt>
  <dd>S3 + CloudFront の構成です</dd>
  <dt>API（+ Auth）</dt>
  <dd>AppSync で API を構成し, Cognito のユーザープールによる認証を追加しています</dd>
  <dt>Lambda Function</dt>
  <dd>Lambda Layer と通常の Function を追加し, AppSync の Query と紐づけています</dd>
<dl>

```bash
$ amplify status

    Current Environment: dev

┌──────────┬───────────────────────────────────┬───────────┬───────────────────┐
│ Category │ Resource name                     │ Operation │ Provider plugin   │
├──────────┼───────────────────────────────────┼───────────┼───────────────────┤
│ Api      │ sample-api                        │ No Change │ awscloudformation │
├──────────┼───────────────────────────────────┼───────────┼───────────────────┤
│ Auth     │ userPoolGroups                    │ No Change │ awscloudformation │
├──────────┼───────────────────────────────────┼───────────┼───────────────────┤
│ Auth     │ sample-auth                       │ No Change │ awscloudformation │
├──────────┼───────────────────────────────────┼───────────┼───────────────────┤
│ Function │ samplelambdalayer                 │ No Change │ awscloudformation │
├──────────┼───────────────────────────────────┼───────────┼───────────────────┤
│ Function │ samplefunction                    │ No Change │ awscloudformation │
├──────────┼───────────────────────────────────┼───────────┼───────────────────┤
│ Hosting  │ S3AndCloudFront                   │ No Change │ awscloudformation │
└──────────┴───────────────────────────────────┴───────────┴───────────────────┘

GraphQL endpoint: < endpoint URL >
Hosting endpoint: < hosting URL >
```

### amplify delete 実行

では消します。最終確認に `y` を返答して実行します。

```bash
$ amplify delete
? Are you sure you want to continue? This CANNOT be undone. (This will delete all the environments of the project from the cloud and wipe out all the local files created by Amp
lify CLI) (y/N) y

⠋ Deleting resources from the cloud. This may take a few minutes...
Deleting env: dev.
✔ Project deleted in the cloud.
Project deleted locally.
```

数分待つと上の Deleted メッセージを残して消えました。
ちなみに上記ログは特に何も改変していないので, `amplify delete` 時のログはこれぐらいしかでないという話です。

`amplify push` とかでは `DELETE_IN_PROGRESS` とか `FAILED` の情報を大量に出してくれるのですが, `amplify delete` のときはでないんですね。いつもと違ってクラウドにアクセスしてる感がないので誰かが本番環境向けに `amplify delete` しても何分かは気づかなそう（所感）。

### 実行後確認

消えたものを確認します。

#### AWS Cloud 上

まずは AWS Console から, CloudFormation を開き, Amplify が操作しているスタックの情報を確認します。 `amplify-<project name>-<env>` で始まるスタックと紐づくもの全部ですね。

なお, 画像なしですみませんが, <font color="Red">普通に DELETE_FAILED してました。</font>

今回私の構成状況としてある程度手動のカスタマイズを入れていたので `DELETE_FAILED` しやすかったのかなと思いますが, 基本的にカスタマイズされる人の方がきっと多いので素直に `DELETE_COMPLETE` になってるのはきっと稀！だと！おもいます！（暴論）

`DELETE_FAILED` しても, `amplify delete` コマンドの実行結果上は Deleted とでるので, ちゃんと CloudFormation の実行状況は確認した方が良いですね。

消えてなかったものは手動で消していきますが, 後述します。

#### ローカル PC 上

以下の記述通り, Amplify CLI で作られたものが消えていました。

> wipe out all the local files created by Amplify CLI

私の構成において消えていたものは, 具体的には以下です。

- amplify/ 配下全て
- src/aws-exports.js
- src/graphql/ 配下のファイル

逆に `amplify` コマンド操作時に変更されていて消えてなかったのは以下です。

- `.gitignore` および `.vscode/settings.json ` 内の amplify 関連記述
- src/graphql のディレクトリ（中身は消えたけどディレクトリ自体は生きてました）
- src/API.ts および .graphqlconfig.yml（`amplify push` 時に Codegen を利用している場合）

### 後処理（DELETE_FAILED の処理も）

では消えているものと消えていないものが見えたところで, 後処理をしていきます。
CloudFormation のスタック上で `DELETE FAILED` となっているリソースを手動で削除します。  
私の構成の場合, 以下が消えてませんでした。

- Hosting 用の S3 Bucket  
- Custom Domain を当てている AppSync（合わせて AppSync 用の IAM Role も残っていた）   

### S3 Bucket の後処理
Hosting 用の S3 Bucket について, `User Initiated` というステータスで `DELETE_SKIPPED` になってました。詳細追えず。
`DELETE_SKIPPED` になっている関係で, S3 Bucket を管理している CloudFormation のスタック自体は, `DELETE_COMPLETED` になっていたので, 後処理では単純に対象のバケットを手動で削除しました。

### Custom Domain ありの AppSync の後処理
Custom Domain を当てている AppSync に対するスタックでは以下エラーが出てました。（AppSync への Custom Domain 自体, 2021/12/06 提供の機能なのでそんなものかなと思います）

```
AWS::AppSync::GraphQLApi DELETE_FAILED
API can not be deleted as it is associated to a domain. (Service: AWSAppSync; Status Code: 400; Error Code: BadRequestException; Request ID: xxxxxxxxxxx; Proxy: null)
```
メッセージによると AppSync API を消す前に Custom Domain の設定紐付けを解除する必要があるらしいので, AWS Console から削除対象の AppSync API への Custom Domain の紐付けを解除して, 手動で API も削除しました。

また, AppSync の Query と Lambda Function を紐づけてるので, AppSync 用の IAM Role である, `<Lambda function 名> + xxxxxxx + "api-" + <env name>` という感じの命名規則のものを手動で消しました。

削除が終わったら, `DELETE_FAILED` になっている CloudFormation のスタックを開き, スタックの削除を実行して〆です。


### その他の後処理
`.gitignore` や `.vscode/setting.json` から Amplify 記述があるものを削除しまいた。

また, Amplify とは別に手動でひっそり設定していた以下のリソースたちを手動で削除しました。

- ACM 証明書
- Route53 のレコード（CloudFront, AppSync URL 向け）
- WAF の設定


## 〆の所感
`amplify delete` は, かなりパワーのあるコマンドのため試すのもなかなか躊躇される印象でした。
今回は, PoC 案件の全てを消しこむという作業だったため, せっかくなのでその流れを書いてみました！  

Amplify 自体はすごく簡単に素早く AWS 上でアプリを立ち上げるのでどんどん使っていきたいですが, 手が滑ってやらかさないようには注意していきたいですね！