Amplify CLI でカスタムリソースを作成する手順

[Add custom AWS resources](https://docs.amplify.aws/cli/usage/customcf)
Amplify CLI で対応していない設定やリソースを使用したいときはカスタムリソースを作成する必要がある。
つまり、amplify CLI で自動生成された CloudFormation テンプレートを手動で書き換える。この時の手順に関して、上記のドキュメントを改めて確認したメモ。

## まとめ
- Amplify CLI で対応していないリソースや細かな設定は CloudFormation テンプレートを手動で変更する必要がある
- 手動で変更した CloudFormation テンプレートは何かの拍子(`amplify update xxx`など)で上書きされて消える可能性があるので保管方法には注意が必要
- 参照しているドキュメントはカスタムリソースの作成についてであり、CloudFormation スタックを新規に作成している。しかし`function`など既に Amplify CLI から作成できるが設定を細かく変更したいという場合には自動生成されたテンプレートを編集する形になる(`function`カテゴリの場合には`amplify/backend/function/<function-name>/<function-name>-cloudformation-template.json`)。この記事では特に触れていない

## 事前準備
手元に実際に amplify プロジェクトが欲しかったため、以下を実行しておく。

```sh
amplify init
amplify add storage  # storage の他に auth, functionも一度に追加できる
```

`function` と `storage` のテンプレートはそれぞれ以下のファイル。普通の CloudFormation テンプレート
function
`amplify/backend/function/<function-name>/<function-name>-cloudformation-template.json`
storage
`amplify/backend/storage/<bucket-name>/s3-cloudformation-template.json`

## ドキュメント内容確認

### 1. Configure backend configuration with custom resource
> Modify amplify/backend/backend-config.json in your project:

`backend-config.json`の編集が必要らしい。`backend-config.json`とは。
[Core Amplify Files](https://docs.amplify.aws/cli/reference/files#core-amplify-files)に説明がある。

>backend-config.json
>
Manual edits okay: YES
Add to version control: YES
>
The backend-config.json in the backend directory contains configuration about your project’s backend, such as how connects to AWS resources (eg. Cognito for auth or AppSync for an API backend). Typically, this file is updated by the CLI commands like amplify add auth or amplify add api. It can also be extended manually to configure your backend beyond Amplify CLI’s features. Both the amplify/backend and amplify/#current-cloud-backend directories contain an backend-config.json file.


具体的に何をしているファイルなのかピンとこなかったが、手元に作成された以下の`backend-config.json`を見るとバックエンドリソースの依存関係(CloudFormationスタックのデプロイ順序)を表しているように見える。`dependsOn`くらいしか有益な情報なさそう。

```json
{
  "auth": {
    "<auth-name>": {
      "service": "Cognito",
      "providerPlugin": "awscloudformation",
      "dependsOn": [],
      "customAuth": false
    }
  },
  "function": {
    "<function-name>": {
      "service": "Lambda",
      "providerPlugin": "awscloudformation",
      "build": true
    }
  },
  "storage": {
    "<bucket-name>": {
      "service": "S3",
      "providerPlugin": "awscloudformation",
      "dependsOn": [
        {
          "category": "function",
          "resourceName": "<function-name>",
          "attributes": [
            "Name",
            "Arn",
            "LambdaExecutionRole"
          ]
        }
      ]
    }
  }
}
```

作業としては実際に何をするかというと、`backend-config.json`ファイルに他のリソースを真似てカスタムカテゴリーをかく。ドキュメントのサンプルは↓。`<custom-category-name>`の部分が上記の自動生成されたテンプレートの`function`や`auth`にあたる。

```
  "<custom-category-name>": {
    "<custom-resource-name>": {
      "service": <custom-aws-service-name>,
      "providerPlugin": "awscloudformation"
    }
  }
```

### 2. Modify folder structure for custom resource
>Under amplify/backend folder, make a folder structure like the following:

```
amplify
  \backend
    \<custom-category-name>
      \<custom-resource-name>
        parameters.json
        template.json
```

 1. で定義した`backend-config.json`に記載の通りにディレクトリを作って、そこに CloudFormation のテンプレートを作成するよう。
 
### 3. (Optional) Reference existing parameters
必要なら `dependsOn`で依存関係を追加してという内容。

### 4. Enable custom resources
`amplify env checkout <current-env-name>`をする必要があるとのこと。やらないと `amplify push`で反映されないとかだろうか？