はじめに
LambdaからLambdaを呼ぶ時、以下のパターンでアクセス可能かどうか検証しました。
- vpc 内の public 内にいる Lambda が呼ぶ / 呼ばれる
- vpc 内の public 内にいる Lambda が呼ぶ / 呼ばれる (vpc endpointあり)
- vpc 内の private 内にいる Lambda が呼ぶ / 呼ばれる
- vpc 内の private 内にいる Lambda が呼ぶ / 呼ばれる (vpc endpointあり)
- vpc 外にいる Lambda が呼ぶ / 呼ばれる
構成図
以下のようにLambdaを呼ぶ側のLambdaと呼ばれる側のLambdaをそれぞれの2つずつ作成しました。
sg作成
まずsgを作成します。
作成するlambda用のsgをインバウンドで許可するsgを1つ作成します。
vpc内のLambdaは、このsgをアタッチさせます。
vpcエンドポイント
private subnetに vpcエンドポイントを設置します。
sgは、先程作成したsgをアタッチさせます。
Lambdaを作成
以下のように、sgは先ほど作成したsgをアタッチさせ、private subnet用のlambdaをpublic subnet用Lambdaを作成します。
IAMロール
以下のIAMポリシーをIAMロールにアタッチします。
- AWSLambdaRole
- AWSLambdaVPCAccessExecutionRole
設定変更
タイムアウトを3秒から7秒に変更します。
Lambdaを呼ぶ側のコード
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コード
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 | ○ |
このパターンは、vpc endpointあり、なしに関わらず呼ぶことができました。
privateにいるLambdaも呼ぶことができました。
理由としては、呼ぶ側の Lambda が呼ばれる側の AWS Lambda
を呼んでおり、呼ばれる側の AWS Lambda
が 呼ばれる側の Lambda 関数
をコールしているためです。
詳細は、以下の記事が分かりやすいです。
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 | ○ |
public subet 内の Lambda は、vpcエンドポイント経由でしかアクセスできませんでした。
理由としては、public subet 内の Lambda は、インターネットにアクセスすることができないためです。
ドキュメントにも記載がありました。
関数はインターネットにアクセスできません。
VPC エンドポイントを使用すると、インターネットアクセスなしで VPC 内から AWS のサービスに接続できます。
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 | ○ |
public subnet 内の Lambda と全く同じ結果でした。
理由も同じです。
参考