LambdaからプライベートサブネットのRDSに接続できない — VPC設定の正しい理解と診断手順
「Lambda関数からRDSに接続しようとしたら、タイムアウトが返ってくる。セキュリティグループは開いているはずなのに」——この症状で詰まるエンジニアは多い。原因の大半はVPC設定の誤解にある。LambdaをプライベートサブネットのRDSに接続するには、Lambda自身もVPC内に配置する必要があり、その設定には正確なサブネットとセキュリティグループの指定が必要だ。
TL;DR — Lambda × プライベートRDS 接続チェックリスト
| 確認項目 | 正しい状態 |
|---|---|
| LambdaのVPC設定 | VPC・サブネット・セキュリティグループが明示的に指定されている |
| Lambdaのサブネット | RDSと同じVPC内のプライベートサブネット(複数AZ推奨) |
| RDSのセキュリティグループ | LambdaのSGからのインバウンドを許可するルールが存在する |
| LambdaのIAMロール | VPC ENI作成権限(AWSLambdaVPCAccessExecutionRole)が付与されている |
| インターネットアクセス(必要な場合) | NATゲートウェイ経由でのルーティングが設定されている |
なぜLambdaにVPC設定が必要なのか — 接続の仕組み
デフォルト状態のLambda関数はAWSが管理するVPC内で動作しており、ユーザーのVPCリソース(RDS、ElastiCacheなど)には直接到達できない。プライベートサブネットに置かれたRDSはパブリックインターネットからアクセス不可能なため、Lambda側もそのVPCに参加する必要がある。
Lambda関数にVPC設定を行うと、AWSはHyperplane ENI(Elastic Network Interface)をユーザー指定のサブネットに作成し、Lambda実行環境をそのVPCに論理的に接続する。この仕組みにより、Lambda関数はRDSと同じネットワークセグメントから通信できるようになる。
- デフォルトLambda(VPC設定なし): AWSマネージドVPCで動作。ユーザーVPCのプライベートリソースには到達不可。
- VPC設定済みLambda: 指定サブネットにHyperplane ENIが作成され、Lambda実行環境がユーザーVPCに接続される。
- セキュリティグループ: LambdaのSGはENIにアタッチされ、RDSのSGはそのSGからのインバウンドを許可する。
- プライベートサブネット: RDSはインターネットゲートウェイへのルートを持たないサブネットに配置されている。
Lambda VPC接続 — 正しい設定手順
Step 1: LambdaのVPC設定を確認・追加する
まずLambda関数に現在VPC設定があるかを確認する。VPC設定が存在しない場合、どれだけセキュリティグループを調整しても接続は成立しない。これが最初に確認すべき理由は、他のすべての診断がこの前提の上に成り立つからだ。
# Lambda関数のVPC設定を確認する
aws lambda get-function-configuration \
--function-name your-function-name \
--query 'VpcConfig'
レスポンスの VpcId が空文字列の場合、Lambda関数はVPC外で動作している。以下のコマンドでVPC設定を追加する。
# LambdaにVPC設定を追加する
aws lambda update-function-configuration \
--function-name your-function-name \
--vpc-config SubnetIds=subnet-xxxxxxxxxxxxxxxxx,subnet-yyyyyyyyyyyyyyyyy,SecurityGroupIds=sg-xxxxxxxxxxxxxxxxx
サブネットは複数AZにまたがるプライベートサブネットを指定する。単一AZのみ指定した場合、そのAZで障害が発生するとLambdaが起動できなくなる。
Step 2: セキュリティグループのルールを検証する
VPC設定が正しくても、セキュリティグループのルールが不正確だと接続は失敗する。よくある誤りは「RDSのSGでCIDRブロックを許可しているが、LambdaのSGを参照していない」パターンだ。IPアドレスベースの許可はENIのIPが変わる可能性があるため、SGベースの参照が推奨される。
# RDSのセキュリティグループのインバウンドルールを確認する
aws ec2 describe-security-groups \
--group-ids sg-rds-security-group-id \
--query 'SecurityGroups[*].IpPermissions'
RDSのSGに以下のようなルールが存在することを確認する。LambdaのSGをソースとして直接参照するルールが最も確実だ。
# RDSのセキュリティグループにLambdaのSGからのインバウンドを許可するルールを追加する
aws ec2 authorize-security-group-ingress \
--group-id sg-rds-security-group-id \
--protocol tcp \
--port 5432 \
--source-group sg-lambda-security-group-id
ポート番号はRDSエンジンに合わせて変更する(MySQL/Aurora MySQL: 3306、PostgreSQL/Aurora PostgreSQL: 5432)。
Step 3: LambdaのIAMロールにVPCアクセス権限があるかを確認する
VPC設定とSGが正しくても、LambdaのIAMロールにENI作成権限がなければデプロイ時にエラーが発生する。この権限不足はLambda関数の実行時ではなく、設定更新時や関数の初回起動時に表面化するため、接続問題と混同されやすい。
# LambdaのIAMロールにアタッチされているポリシーを確認する
aws iam list-attached-role-policies \
--role-name your-lambda-execution-role-name
AWSマネージドポリシー AWSLambdaVPCAccessExecutionRole がアタッチされていることを確認する。存在しない場合は以下で追加する。
# VPCアクセス実行ロールポリシーをアタッチする
aws iam attach-role-policy \
--role-name your-lambda-execution-role-name \
--policy-arn arn:aws:iam::aws:policy/service-role/AWSLambdaVPCAccessExecutionRole
Step 4: サブネットのルートテーブルを確認する
LambdaをVPC内に配置しても、Lambdaが配置されたサブネットのルートテーブルが正しく構成されていないと、RDSへのパケットが届かない。特にRDSが別のサブネットにある場合、同一VPC内であればローカルルートで到達できるはずだが、誤ったルートテーブルの設定が干渉することがある。
# Lambdaが配置されているサブネットのルートテーブルを確認する
aws ec2 describe-route-tables \
--filters Name=association.subnet-id,Values=subnet-lambda-subnet-id \
--query 'RouteTables[*].Routes'
同一VPC内の通信はローカルルート(local)で処理される。このルートはデフォルトで存在し、削除できない。RDSへの接続に外部インターネットは不要なため、NATゲートウェイへのルートがなくてもVPC内通信は成立する。
Step 5: RDSのエンドポイントとポートを確認する
ネットワーク層が正しく設定されていても、接続先のエンドポイントやポートが誤っていれば接続は失敗する。アプリケーションコードのハードコードされた値と実際のRDS設定が一致しているかを確認する。
# RDSインスタンスのエンドポイントとポートを確認する
aws rds describe-db-instances \
--db-instance-identifier your-db-instance-identifier \
--query 'DBInstances[*].{Endpoint:Endpoint.Address,Port:Endpoint.Port,VpcId:DBSubnetGroup.VpcId}'
よくある誤診断パターン — 実際の障害から
「セキュリティグループのアウトバウンドルールをすべて許可にしたのに接続できない」という報告が来たことがある。確認してみると、LambdaのVPC設定自体が存在しなかった。アウトバウンドルールを見直す前に、そもそもLambdaがVPCに参加しているかを確認するのが先だ。
セキュリティグループはファイアウォールのルールセットだが、そのルールが適用されるのはENIが存在する場合のみだ。LambdaにVPC設定がなければENIは作成されず、SGのルールは意味を持たない。
もう一つの典型的な誤診断は「RDSのSGでインバウンドを0.0.0.0/0で開放したら接続できた。だからSGの問題だった」という結論だ。これは正しくない。実際の原因はLambdaのSGをソースとして指定していなかったことであり、全開放は問題の回避であって解決ではない。本番環境では必ずLambdaのSGを明示的に参照するルールに絞り込む。
- タイムアウト発生: Lambda関数がRDS接続でタイムアウト。エラーログにはネットワーク到達不能を示すメッセージが出る。
- 誤診断1 — SGのアウトバウンド: LambdaのSGアウトバウンドルールを確認するが、VPC設定自体がないため無意味。
- 誤診断2 — RDSのSG全開放: 全開放で接続できるが、これはセキュリティホールを作るだけで根本解決ではない。
- 正しい診断: LambdaのVPC設定追加 → LambdaのSGをRDSのSGインバウンドルールに追加 → 最小権限で接続成功。
Lambdaがインターネットアクセスも必要な場合
LambdaをVPC内に配置すると、デフォルトではインターネットへのアクセスができなくなる。外部APIの呼び出しやAWSサービスへのアクセス(VPCエンドポイントがない場合)が必要な場合は、NATゲートウェイをパブリックサブネットに配置し、プライベートサブネットのルートテーブルにNATゲートウェイへのデフォルトルートを追加する必要がある。
AWSサービス(S3、DynamoDB、Secrets Managerなど)へのアクセスはVPCエンドポイントを使用することでNATゲートウェイなしに実現できる。RDSの認証情報をSecrets Managerで管理している場合は、Secrets Manager用のVPCエンドポイントを作成することを検討する。
# Secrets Manager用のVPCエンドポイントを確認する
aws ec2 describe-vpc-endpoints \
--filters Name=vpc-id,Values=vpc-xxxxxxxxxxxxxxxxx \
Name=service-name,Values=com.amazonaws.us-east-1.secretsmanager \
--query 'VpcEndpoints[*].{State:State,ServiceName:ServiceName}'
IAMポリシー — 最小権限での設定例
Lambda実行ロールに必要な権限を最小限に絞った例を示す。VPCアクセスに必要なENI操作権限はAWSマネージドポリシーで付与し、RDS接続に必要な認証情報取得権限は別途付与する。
🔽 Lambda実行ロール IAMポリシー例(クリックして展開)
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "CloudWatchLogs",
"Effect": "Allow",
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": "arn:aws:logs:us-east-1:123456789012:log-group:/aws/lambda/your-function-name:*"
},
{
"Sid": "SecretsManagerAccess",
"Effect": "Allow",
"Action": [
"secretsmanager:GetSecretValue"
],
"Resource": "arn:aws:secretsmanager:us-east-1:123456789012:secret:your-rds-secret-name-*"
}
]
}
VPC ENI操作権限(ec2:CreateNetworkInterface、ec2:DescribeNetworkInterfaces、ec2:DeleteNetworkInterface)は AWSLambdaVPCAccessExecutionRole マネージドポリシーで付与する。これらをインラインポリシーで手動定義する場合、Resource: "*" が必要になるため、マネージドポリシーの使用が実用的だ。
LambdaからプライベートRDSへの接続 — 診断フローまとめ
- LambdaのVPC設定が存在するかを最初に確認する。存在しなければ追加が必須。
- VPC設定がある場合、サブネットがRDSと同じVPC内のプライベートサブネットかを確認する。
- RDSのSGにLambdaのSGからのインバウンドルールが存在するかを確認する。
- LambdaのIAMロールにVPCアクセス実行ロールポリシーがアタッチされているかを確認する。
- すべて正しい場合、RDSのエンドポイント・ポート・認証情報をアプリケーションコードで確認する。
まとめ — LambdaとプライベートRDS接続の要点
LambdaからプライベートサブネットのRDSに接続するには、Lambda自身をVPC内に配置することが前提条件だ。VPC設定(サブネットとセキュリティグループ)の明示的な指定、RDSのSGへのインバウンドルール追加、IAMロールへのVPCアクセス権限付与——この3点が揃って初めて接続が成立する。タイムアウトが発生したらまずLambdaのVPC設定の有無を確認し、その後セキュリティグループのルールを検証する順序で診断を進めると効率的だ。
詳細な設定手順については AWS Lambda VPC設定公式ドキュメント を参照すること。
用語集
| 用語 | 説明 |
|---|---|
| Hyperplane ENI | Lambda VPC接続で使用されるAWS管理のElastic Network Interface。複数のLambda実行環境で共有される。 |
| プライベートサブネット | インターネットゲートウェイへの直接ルートを持たないサブネット。外部からの直接アクセスを遮断する。 |
| セキュリティグループ(SG) | ENIレベルで動作するステートフルなファイアウォール。インバウンド・アウトバウンドルールを定義する。 |
| VPCエンドポイント | インターネットを経由せずにAWSサービスへプライベート接続するための仕組み。 |
| NATゲートウェイ | プライベートサブネット内のリソースがインターネットへアウトバウンド通信するためのマネージドサービス。 |
コメント
コメントを投稿