vpc 内 Lambda から Lambda を呼ぶ( invoke する)場合、public subnet や private subnet などのパターン別に呼べるか検証してみた

# はじめに
LambdaからLambdaを呼ぶ時、以下のパターンでアクセス可能かどうか検証しました。
- vpc 内の public 内にいる Lambda が呼ぶ / 呼ばれる
- vpc 内の public 内にいる Lambda が呼ぶ / 呼ばれる (vpc endpointあり)
- vpc 内の private 内にいる Lambda が呼ぶ / 呼ばれる
- vpc 内の private 内にいる Lambda が呼ぶ / 呼ばれる (vpc endpointあり)
- vpc 外にいる Lambda が呼ぶ / 呼ばれる


# 構成図
以下のようにLambdaを呼ぶ側のLambdaと呼ばれる側のLambdaをそれぞれの２つずつ作成しました。
![スクリーンショット 2022-11-15 22.37.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/988747/13fc38dd-86a6-cdaf-3100-7288cd3a089b.png)


# sg作成
まずsgを作成します。
作成するlambda用のsgをインバウンドで許可するsgを１つ作成します。
![スクリーンショット 2022-11-15 22.41.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/988747/f75c2caf-71fd-99b5-8eab-726fa2ad5211.png)

vpc内のLambdaは、このsgをアタッチさせます。

# vpcエンドポイント
private subnetに vpcエンドポイントを設置します。
sgは、先程作成したsgをアタッチさせます。
![スクリーンショット 2022-11-15 23.02.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/988747/8771c21e-c44f-3cf8-7f3c-d71c7463b5db.png)


# Lambdaを作成
以下のように、sgは先ほど作成したsgをアタッチさせ、private subnet用のlambdaをpublic subnet用Lambdaを作成します。
![スクリーンショット 2022-11-15 22.48.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/988747/7e59a4b4-9ad7-aeec-dcdb-fb1faf7b3eec.png)

## IAMロール
以下のIAMポリシーをIAMロールにアタッチします。
- AWSLambdaRole
- AWSLambdaVPCAccessExecutionRole

## 設定変更
タイムアウトを3秒から7秒に変更します。

## Lambdaを呼ぶ側のコード
```js:index.js
const AWS = require('aws-sdk');
const lambda = new AWS.Lambda();

exports.handler = async (event, context, callback) => {
	let payload = {
	    "message":"test"
	};
	
	// ペイロードをStringにする。
	payload = JSON.stringify(payload);
	
	let params = {
	    FunctionName:"test", // invokeするLambdaの名前
	    InvocationType:"RequestResponse",
	    Payload:payload
	 };
	
	try {
	    // Lambda関数呼び出し
	    let callLambda = await lambda.invoke(params).promise();
	    console.log(callLambda);
	
	 } catch (e) {
	    console.log("[ERROR]sendSMS/callLambda",e);
	 }
};
```

## 呼ばれる側のLambdaコード
```js:index.js
exports.handler = async (event) => {
  return {
      statusCode: 200,
      body: JSON.stringify('invoke-success!'),
  };
};
```

## テスト
呼ぶ側のLamdbdaを実行します。
7秒以内に正常なレスポンスが返れば、呼び出し成功です。
失敗の場合、タイムアウトになります。

テスト結果をこれから記載します。

# vpc外のLambdaが呼ぶ時

結果

|  Lambda →  リソース |アクセス|
|:-:|:-:|
| Lambda  →  Lambda |○|
|  Lambda → public内 Lambda  | ○  |
|  Lambda → private内 Lambda  | ○  |

![スクリーンショット 2022-11-15 22.23.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/988747/85949995-941d-8423-0932-5bbd49f0b497.png)

このパターンは、vpc endpointあり、なしに関わらず呼ぶことができました。
privateにいるLambdaも呼ぶことができました。

理由としては、呼ぶ側の Lambda が`呼ばれる側の AWS Lambda`を呼んでおり、`呼ばれる側の AWS Lambda` が `呼ばれる側の Lambda 関数`をコールしているためです。
詳細は、以下の記事が分かりやすいです。

https://dev.classmethod.jp/articles/sqs-to-vpclambda/#toc-3

# vpcの public subnet 内の Lambdaが呼ぶ時

結果

|  Lambda →  リソース |アクセス|
|:-:|:-:|
| public内 Lambda  →  Lambda |✕|
|  public内 Lambda → public内 Lambda  | ✕  |
|  public内 Lambda → private内 Lambda  | ✕  |

|  Lambda → vpc endpoint →リソース |アクセス|
|:-:|:-:|
| public内 Lambda  → vpc endpoint →  Lambda |○|
|  public内 Lambda → vpc endpoint → public内 Lambda  | ○  |
|  public内 Lambda → vpc endpoint → private内 Lambda  | ○  |


![スクリーンショット 2022-11-15 22.30.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/988747/d7585e87-6186-b605-5d6a-b907660b10f4.png)

public subet 内の Lambda は、vpcエンドポイント経由でしかアクセスできませんでした。
理由としては、public subet 内の Lambda は、インターネットにアクセスすることができないためです。

ドキュメントにも記載がありました。

>関数はインターネットにアクセスできません。
VPC エンドポイントを使用すると、インターネットアクセスなしで VPC 内から AWS のサービスに接続できます。

https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/configuration-vpc.html#vpc-internet


# vpcの private subnet 内の Lambdaが呼ぶ時

結果

|  Lambda →  リソース |アクセス|
|:-:|:-:|
| private内 Lambda  →  Lambda |✕|
|  private内 Lambda → public内 Lambda  | ✕  |
|  private内 Lambda → private内 Lambda  | ✕  |

|  Lambda → vpc endpoint →リソース |アクセス|
|:-:|:-:|
| private内 Lambda  → vpc endpoint →  Lambda |○|
|  private内 Lambda → vpc endpoint → public内 Lambda  | ○  |
|  private内 Lambda → vpc endpoint → private内 Lambda  | ○  |

![スクリーンショット 2022-11-15 22.29.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/988747/f1c39a5c-12a0-534b-a117-87926e0a1c10.png)

public subnet 内の Lambda と全く同じ結果でした。
理由も同じです。

# 参考

https://aws.amazon.com/jp/premiumsupport/knowledge-center/internet-access-lambda-function/

https://qiita.com/hirai-11/items/5a25408d235b2bae34ef