Amplifyのenv毎に異なる値をCloudFormationテンプレートのパラメータに設定する

# はじめに

amplifyでCfnテンプレートの独自に追加したパラメータにenv毎の異なる値を設定したいということがあり、その方法を調べてよさそうな方法がありました。

この方法は [amplify-cliのIssueのコメント](https://github.com/aws-amplify/amplify-cli/issues/3240#issuecomment-577832717) に書かれているだけで、2020-6-12時点ではまだドキュメント化はされていないでここに記録しておきます。

## amplifyのCfnテンプレートの独自パラメータに値を渡す方法

amplifyが扱うCloudFormationテンプレートで独自のパラメータを追加した場合、パラメータに値を渡すには `parameters.json` に値を記述します。

例えば、次のように`externalEndpointUrl`というパラメータをテンプレートに追加した場合、

```json:template.json
{
  "AWSTemplateFormatVersion": "2010-09-09",
  "Description": "Lambda resource stack creation using Amplify CLI",
  "Parameters": {
    // 他のパラメータもある。

    "externalEndpointUrl": { // ユーザが独自に追加したパラメータ
       "Type": "String"
   }
  },
}
```

以下のように `parameters.json` に書いておくとテンプレートをデプロイした時に、`externalEndpointUrl`には `https://api.example.com/` が設定されます。

```js:parameters.json
{
  "externalEndpointUrl": "https://api.example.com/"
}
```

この方法は[公式ドキュメント](https://docs.amplify.aws/cli/usage/customcf)にも書かれています。

ちなみに、余談ですが `parameters.json` の値に直接以下のようにCloudFormationテンプレートの関数を書くことができて、他のテンプレートのOutputsを参照できるというのを今回初めて知りました（公式ドキュメントに書かれていました。。。）

```json:parameters.json
{
        "authmycognitoresourceUserPoolId": {  // The format out here is `<category><resource-name><attribute-name>` - we have defined all of these in the `backend-config.json` file above
           "Fn::GetAtt": [
              "authmycognitoresource",  // check `amplify status` to find resource name in the category auth
              "Outputs.UserPoolId"
           ]
        }
 }
```

## env毎の値を定義する

さて、独自パラメータの値を `parameters.json` に設定できるのはよいのですが、この値はenvにより違う値を設定することはできません。

env毎に異なるパラメータ値を設定するには `amplify/team-provider-info.json` にその値を設定します。
env毎のパラメータを定義するファイルの形式は以下のようになります。

```json:team-provider-info.json
{
    "dev": {
        "awscloudformation": {
            "AuthRoleName": "xxxxxxxxxxx",
            "UnauthRoleArn": "xxxxxxxxxxx",
            "AuthRoleArn": "xxxxxxxxxxx",
            "Region": "xxxxxxxxxxx",
            "DeploymentBucketName":  "xxxxxxxxxxx",
            "UnauthRoleName":  "xxxxxxxxxxx"
            "StackName": "xxxxxxxxxxx",
            "StackId":  "xxxxxxxxxxx"
        },
        "categories": {
            "function": {
                "<function-resource-name>": {
                    "externalEndpointUrl": "https://api.example.com/dev" // dev環境固有の値
                }
            }
        }
    },
    "prod": {
        "awscloudformation": {
            "AuthRoleName": "xxxxxxxxxxx",
            "UnauthRoleArn": "xxxxxxxxxxx",
            "AuthRoleArn": "xxxxxxxxxxx",
            "Region": "xxxxxxxxxxx",
            "DeploymentBucketName":  "xxxxxxxxxxx",
            "UnauthRoleName":  "xxxxxxxxxxx"
            "StackName": "xxxxxxxxxxx",
            "StackId":  "xxxxxxxxxxx"
        },
        "categories": {
            "function": {
                "<function-resource-name>": {
                    "externalEndpointUrl": "https://api.example.com/" // prod環境固有の値
                }
            }
        }
    }
}
```

上記のように `amplify/team-provider-info.json` のenv毎の `categories` 配下に独自パラメータの値を定義できます。これで、本番、ステージ、開発など環境毎に異なる値をパラメータに設定することができるようになります。

## 注意点

**amplifyのバージョンが2.20以上でないと、amplify initで`team-provider-info.json`の値が消えてしまう[バグ](https://github.com/aws-amplify/amplify-cli/pull/4161)があるので、2.20未満ならバージョンアップが必要です。**