VPCアクセス可能なlambda関数をamplifyで作成する方法 発展版 ~ env毎にVPCを切替可能とする

先に以下の記事を投稿しました

https://qiita.com/kujiraza/items/458629d5a3d210ad45ad

この記事ではamplifyで1つのenvしか用いない前提で記載しています。
本記事ではこの記事（以降元記事と記載します）を発展させて、envを複数用意した場合にenv毎に別のVPCに接続するための手順を記載します。

# やること

[元記事の手順](https://qiita.com/kujiraza/items/458629d5a3d210ad45ad#%E6%89%8B%E9%A0%86)をベースとして、以下の部分を変更してlambdaを作成します。

- セキュリティグループIDとサブネットグループIDをパラメータ化し、値は別ファイルに設定する
- 値の設定先としてenv毎にパラメータを指定できる`amplify/team-provider-info.json`を使用する


# 前提

`amplify add env`により、devに加えてstgを作成済みとします。 これ以外は[元記事の前提](https://qiita.com/kujiraza/items/458629d5a3d210ad45ad#%E5%89%8D%E6%8F%90)に準じます。

# 手順


（**太字**が元記事と異なる部分）

1. 【事前準備】lambdaの新規作成 
2. lambdaのテンプレートファイル編集
    1. VPC接続設定に必要なIAMポリシー追加
    2. **パラメータ定義**
    3. **パラメータを用いて**VPC接続設定追加
    4. リソースの構築順指定
3. **env毎に異なるパラメータ値を設定**
    1. **envがdevの場合のパラメータ値を追加** 
    1. **envがstgの場合のパラメータ値を追加**
4. ビルド＆クラウドへの反映
5. 確認

以下に詳細な手順を記載します。

## 1.  【事前準備】lambdaの新規作成

[元記事と同じ手順](https://qiita.com/kujiraza/items/458629d5a3d210ad45ad#1--%E4%BA%8B%E5%89%8D%E6%BA%96%E5%82%99lambda%E3%81%AE%E6%96%B0%E8%A6%8F%E4%BD%9C%E6%88%90)とにて`vpclambda`関数を作成します。（詳細は省略）

## 2. lambdaのテンプレートファイル編集

1.で作成されたテンプレートファイル`vpclambda-cloudformation-template.json` に対して4か所追記します。
List型パラメータを定義する場合のパラメータの型は、`"Type": "CommaDelimitedList"` とします。

```diff_json:テンプレートファイル追記箇所
{
  "AWSTemplateFormatVersion": "2010-09-09",
  "Description": "Lambda Function resource stack creation using Amplify CLI",
  "Parameters": {
    ...
    "s3Key": {...},
+    // 2-2. パラメータ定義（上の行のカンマも追加必要）
+    "subnetIds": {
+      "Type": "CommaDelimitedList"
+    },
+    "securityGroupIds": {
+      "Type": "CommaDelimitedList"
+    }
+    // 2-2 ここまで
  },
  "Conditions": {...},
  "Resources": {
    "LambdaFunction": {
+      // 2-4. リソースの構築順指定
+      //   (2-1のIAMポリシー作成後にLambdaFunctionを作成)
+      "DependsOn": [
+        "LambdaExecutionPolicyCustom"
+      ],
+      // 2-4 ここまで
      "Type": "AWS::Lambda::Function",
      "Metadata": {...},
      "Properties": {
        ...
        "Timeout": 25,
+        // 2-3. パラメータを用いてVPC接続設定追加（上の行のカンマも追加必要）
+        "VpcConfig": {
+          "SecurityGroupIds": {
+            "Ref": "securityGroupIds"
+          },
+          "SubnetIds":  {
+            "Ref": "subnetIds"
+          }
+        }
+        // 2-3 ここまで
      }
    },
    "LambdaExecutionRole": {...},
    "lambdaexecutionpolicy": {...},
+    // 2-1. VPC接続設定に必要なIAMポリシー追加（上の行のカンマも追加必要）
+    "LambdaExecutionPolicyCustom": {
+      "DependsOn": [
+        "LambdaExecutionRole"
+      ],
+      "Type": "AWS::IAM::Policy",
+      "Properties": {
+        "PolicyName": "lambda-execution-policy-custom",
+        "Roles": [
+          {
+            "Ref": "LambdaExecutionRole"
+          }
+        ],
+        "PolicyDocument": {
+          "Version": "2012-10-17",
+          "Statement": [
+            {
+              "Effect": "Allow",
+              "Action": [
+                "ec2:CreateNetworkInterface",
+                "ec2:DescribeNetworkInterfaces",
+                "ec2:DeleteNetworkInterface"
+              ],
+              "Resource": "*"
+            }
+          ]
+        }
+      }
+    }
+   // 2-1 ここまで
  },
  "Outputs": {...}
}
```

- `...`は省略の意
- 行頭`⁺`は追加行を強調するために使用
  (コピペする場合は`⁺`を削除すること)
- テンプレート内にコメントを記入できますが、次の手順を実施するとコメントは消えます

## 3. env毎に異なるパラメータ値を設定

パラメータの値は`amplify/team-provider-info.json`へList型として指定します。
env毎、lambda関数毎に異なるパラメータを指定できます。

```diff_json:amplify/team-provider-info.json
{
  "dev": {
    "awscloudformation": {...},
    "categories": {
      "function": {
        ...
        "vpclambda": {
          ...
+          // 3-1. envがdevの場合のパラメータ値を追加
+          "securityGroupIds": [
+            "sg-XXXXXXXXXXXXXXXXX"
+          ],
+          "subnetIds": [
+            "subnet-XXXXXXXXXXXXXXXXX",
+            "subnet-XXXXXXXXXXXXXXXXX",
+            "subnet-XXXXXXXXXXXXXXXXX"
+          ]
+          // 3-1 ここまで
        }
      }
    }
  },
  "stg": {
    "awscloudformation": {...},
    "categories": {
      "function": {
        ...
        "vpclambda": {
          ...
+          // 3-2. envがstgの場合のパラメータ値を追加
+          "securityGroupIds": [
+            "sg-XXXXXXXXXXXXXXXXX"
+          ],
+          "subnetIds": [
+            "subnet-XXXXXXXXXXXXXXXXX",
+            "subnet-XXXXXXXXXXXXXXXXX",
+            "subnet-XXXXXXXXXXXXXXXXX"
+          ]
+          // 3-2 ここまで
        }
      }
    }
  }
}
```

## 4. ビルド＆クラウドへの反映

以下のコマンドを実施します。env毎に実行する必要があります。

```bash:実行コマンド
amplify push -y
```

## 5. 確認

[元記事](https://qiita.com/kujiraza/items/458629d5a3d210ad45ad#4-%E7%A2%BA%E8%AA%8D)同様、AWSコンソールのlambdaのVPC設定を確認ください。
以下のようにenv毎に別のlambdaが作成されますので、それぞれのlambdaのコンソール画面を確認ください。

- vpclambda-dev
- vpclambda-stg

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617842/cc080d25-bbb6-2a5e-7de9-ad2610a6e52f.png)


# 最後に

この記事を書くにあたって、cloudformationのList型パラメータの扱い方がとても勉強になりました。
`"Type": "CommaDelimitedList"`は、知らないとなかなか調べられないですよね。

# 参考

以下のサイトを参考にさせて頂いています。ありがとうございます。

https://github.com/aws-amplify/amplify-cli/issues/32

https://qiita.com/fossamagna/items/16f4eb427b7401808f3a