VPC内のlambdaからVPC外のlambdaを実行する

# 概要

- デフォルトVPC内のap-northeast-1aのデフォルトサブネットに設置されたlambda関数から、VPCが設定されていないlambdaを同期で実行する方法をまとめる。

# やりたいこと

- VPC内の関数Aを手動実行し、関数A内で関数Bにリクエストが投げられ、VPC外の関数Bが実行される。

![work__Online_Whiteboard_for_Visual_Collaboration.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/f6984f1b-7a67-495c-c96f-47f26cc1cf71.png)

# 情報

- 各lambda関数のランタイムはNode.js18を使用する。

# 方法

## Lambda関数Bの作成

- 先にLambda関数Aから呼び出されるLambda関数Bを作成する。
- 下記の情報で関数を作成する。
    - 名前：function_b
    - ランタイム：Node.js18
- 下記のコードを記載し、hello-worldテストを作成し実行して「Hello world for function B」が出力されることを確認する。

    ```js
    export const handler = async(event) => {
        // TODO implement
        const logString = 'Hello world for function B';
        console.log(logString);
        const response = {
            statusCode: 200,
            body: JSON.stringify(logString),
        };
        return response;
    };

    ```

## セキュリティグループの作成

- 下記の情報でセキュリティグループを作成する。
    - 名前：forVpcEndPointSG
    - 説明：forVpcEndPointSG
    - VPC：デフォルトVPCを選択
    - インバウンドルール
        - タイプ：HTTPS
        - ソース：0.0.0.0/0
    - アウトバウンドルール
        - タイプ：すべてのトラフィック
        - 送信先：0.0.0.0/0

## VPCエンドポイントの作成

- 下記の情報でVPCエンドポイントを作成する。
    - 名前：forFunctionAVpcEndPoint
    - サービスカテゴリ：AWSのサービス
    - サービス：com.amazonaws.ap-northeast-1.lambda
    - VPC：デフォルトVPC
    - サブネット：ap-northeast-1aのデフォルトサブネット
    - IPアドレスタイプ：IPv4
    - セキュリティグループ：forVpcEndPointSG
    - ポリシー：フルアクセス

## Lambda関数Aの作成

- 次にLambda関数Bを呼び出すLambda関数Aを作成する。
- 下記の情報で関数を作成する。
    - 名前：function_a
    - ランタイム：Node.js18
- 下記のコードを記載する。

    ```js
    import { Lambda } from '@aws-sdk/client-lambda';
    
    const lambda = new Lambda({
      region: "ap-northeast-1"
    });
    
    export async function handler(event) {
    
      const functionBArn = 'lambda関数BのARN';
    
      const params = {
        FunctionName: functionBArn,
        InvocationType: 'RequestResponse',
        Payload: JSON.stringify(event),
      };
    
      try {
        // Lambda関数Bを呼び出し、結果を取得
        await lambda.invoke(params);
        
        console.log('Hello world for function A');
      
        return true;
      } catch (error) {
        console.error('Error invoking functionB:', error);
        throw error;
      }
    }

    ```

- 下記の方法でlambda関数Aにlambda関数Bを実行するための権限を付与する。
    - lambda関数AのIAMロールに下記インラインポリシーを追加する。

        ```json
        {
          "Version": "2012-10-17",
          "Statement": [
            {
              "Effect": "Allow",
              "Action": "lambda:InvokeFunction",
              "Resource": "lambda関数BのARN"
            }
          ]
        }
        ```

- lambda関数AのIAMロールに「AWSLambdaVPCAccessExecutionRole」ポリシーをアタッチする。
- lambda関数AをデフォルトVPCのap-northeast-1aのデフォルトサブネットに設定する。セキュリティグループはデフォルトのセキュリティグループを割り当てる。
- hello-worldテストを作成しlambda関数Aを実行するとlambda関数Aのログに「Hello world for function A」が出力され、lambda関数Bのログに「Hello world for function B」が出力される。

# 参考文献

https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/API_Invoke.html

https://docs.aws.amazon.com/ja_jp/sdk-for-javascript/v2/developer-guide/lambda-examples.html

https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/welcome.html

https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/clients/client-lambda/

https://qiita.com/miriwo/items/e9084359d4b75b6bffb2