📝
VPC Lambda から プライベート API Gateway 経由で非 VPC Lambda を呼び出してみた
今回は VPC Lambda から プライベート API Gateway 経由で非 VPC Lambda を呼び出してみました。
構成図
非 VPC Lambda
以下の設定で作成しました。
- ランタイム:
Node.js 16.x
- コード
index.js
exports.handler = async (event) => {
// TODO implement
console.log(JSON.stringify(event, null, 2))
const response = {
statusCode: 200,
body: JSON.stringify('Hello from Lambda!'),
};
return response;
};
VPC Lambda
以下の設定で作成しました。
- ランタイム:
Node.js 16.x
- レイヤー: axios をインストールしたレイヤー
レイヤーについては AWS 公式ドキュメントおよび Zenn ブログをご覧ください。 - VPC
- サブネット: プライベートサブネット × 1
- セキュリティグループ
- インバウンドルール: なし
- アウトバウンドルール: デフォルト (全許可)
- コード
index.js
const axios = require('axios');
exports.handler = async (event) => {
const res = await axios.get("https://{my-api-id}.execute-api.ap-northeast-1.amazonaws.com/{api-stage-name}");
console.log(res.data)
return res.data;
};
VPC エンドポイント
AWS 公式ドキュメントを参考に以下の設定で作成ました。
- サービス名:
com.amazonaws.ap-northeast-1.execute-api
- VPC: VPC Lambda と同じ VPC
- サブネット: VPC Lambda と同じプライベートサブネット
- セキュリティグループ
- インバウンドルール: すべてのトラフィックを VPC の CIDR (
10.0.0.0/16
) から許可 - アウトバウンドルール: デフォルト (全許可)
- インバウンドルール: すべてのトラフィックを VPC の CIDR (
- ポリシー
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Deny",
"Principal": "*",
"Action": "execute-api:Invoke",
"Resource": "arn:aws:execute-api:ap-northeast-1:{account-id}:<my-api-id>/*",
"Condition": {
"StringNotEquals": {
"aws:sourceVpc": "{my-vpc-id}"
}
}
},
{
"Effect": "Allow",
"Principal": "*",
"Action": "execute-api:Invoke",
"Resource": "arn:aws:execute-api:ap-northeast-1:{account-id}:{my-api-id}/*"
}
]
}
上記のポリシーで VPC 内からの API 呼び出しのみ許可するように設定しています。
プライベート API Gateway
- Amazon API Gateway でのプライベート API の作成 - Amazon API Gateway
- チュートリアル: プライベート REST API の構築 - Amazon API Gateway
上記 2 つの AWS 公式ドキュメントを参考に以下の設定で作成ました。
- API タイプ: REST API
- エンドポイントタイプ: プライベート
- メソッド: GET
- Lambda プロキシ統合の使用: 有効
- Lambda 関数: 作成済みの非 VPC Lambda
- リソースポリシー
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Deny",
"Principal": "*",
"Action": "execute-api:Invoke",
"Resource": "arn:aws:execute-api:ap-northeast-1:{account-id}:{my-api-id}/*",
"Condition": {
"StringNotEquals": {
"aws:sourceVpce": "{my-vpc-endpoint-id}"
}
}
},
{
"Effect": "Allow",
"Principal": "*",
"Action": "execute-api:Invoke",
"Resource": "arn:aws:execute-api:ap-northeast-1:{account-id}:{my-api-id}/*"
}
]
}
上記のポリシーで VPC エンドポイントからの API 呼び出しのみ許可するように設定しています。
動作確認
VPC Lambda からテスト実行してみます。
レスポンスを取得できました。
トラブルシューティング
エラーが発生する場合には以下の点を確認してください。
- VPC Lambda
- レイヤーを登録して関数に追加したか
- セキュリティグループのアウトバウンドルールで通信を許可しているか
- VPC エンドポイント
- サブネットが VPC Lambda と同じか
- セキュリティグループで VPC Lambda からの通信を許可しているか
- ポリシーで VPC からのアクセスを許可しているか
- API Gateway
- リソースポリシーで VPC エンドポイントからのアクセスを許可しているか
- デプロイしたか
- その他
- ネットワーク ACL などのその他のファイアウォール機能で通信を許可しているか
- Lambda のコードをデプロイしたか
- API Gateway のテスト実行はうまくいくか
- 成功する場合: VPC Lambda から API Gateway までの設定を見直す
- 失敗する場合: API Gateway と 非 VPC Lambda の設定を見直す
- ログを確認する
まとめ
今回は、VPC Lambda から プライベート API Gateway 経由で非 VPC Lambda を呼び出してみました。
VPC Lambda やプライベート API Gateway はあまり使ったことがなかったのですが、簡単に設定できました。
参考になれば幸いです。
参考資料
- Lambda レイヤーの作成と共有 - AWS Lambda
- Lambdaレイヤーにnode_modulesを登録してみた
- API Gateway でプライベート API 用の VPC エンドポイントポリシーを使用する - Amazon API Gateway
- Amazon API Gateway でのプライベート API の作成 - Amazon API Gateway
- チュートリアル: プライベート REST API の構築 - Amazon API Gateway
- AWS Lambda の Amazon CloudWatch Logs へのアクセス - AWS Lambda
- API ゲートウェイ REST API と WebSocket API の CloudWatch ログを有効にする | AWS re:Post
Discussion