📝

VPC Lambda から プライベート API Gateway 経由で非 VPC Lambda を呼び出してみた

2022/10/10に公開約4,400字

今回は、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 公式ドキュメントおよびLambdaレイヤーにnode_modulesを登録してみたをご覧ください。
  • 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;
};

<my-api-id> は後で作成する API Gateway の ID に置換します。
{api-stage-name} は後で作成する API Gateway のステージ名に置換します。

VPC エンドポイント

https://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/apigateway-vpc-endpoint-policies.html

以下の設定で作成ました。

  • サービス名: com.amazonaws.ap-northeast-1.execute-api
  • VPC: VPC Lambda と同じ VPC
  • サブネット: VPC Lambda と同じプライベートサブネット
  • セキュリティグループ
    • インバウンドルール: すべてのトラフィックを VPC の CIDR (10.0.0.0/16) から許可
    • アウトバウンドルール: デフォルト (全許可)
  • ポリシー
{
	"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>/*"
		}
	]
}

{account-id} は AWS アカウント ID に置換します。
{my-vpc-id} は VPC エンドポイントを作成する VPC の ID に置換します。
<my-api-id> は後で作成する API Gateway の ID に置換します。

上記のポリシーで、VPC 内からの API 呼び出しのみ許可するように設定しています。

プライベート API Gateway

https://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/apigateway-private-apis.html
https://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/private-api-tutorial.html

以下の設定で作成ました。

  • 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>/*"
        }
    ]
}

{account-id} は AWS アカウント ID に置換します。
<my-api-id> はプライベート API Gateway の ID に置換します。
<my-vpc-endpoint-id> は上記で作成した VPC エンドポイントの 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 はあまり使ったことがなかったのですが、簡単に設定できました。

参考になれば幸いです。

Discussion

ログインするとコメントできます