はじめに
AWS Lambdaからプライベートサブネット内にあるAmazon RDSに接続する構成は、実務で頻繁に登場します。しかし、「セキュリティグループの設定ミスで接続できない」「Lambdaのタイムアウトが発生する」といったトラブルが多いテーマでもあります。本記事では、初心者から中級者のエンジニア向けに、LambdaをVPC内に安全に配置し、RDSに接続するための手順をステップバイステップで解説します。
前提知識/必要な理由
なぜLambdaをVPC内に配置する必要があるのでしょうか。通常、Lambda関数はAWSが管理するデフォルトのネットワーク上で実行され、インターネット経由でリソースにアクセスします。しかし、企業のデータベース(RDSなど)は、セキュリティ上の理由からインターネットに公開せず、VPC内のプライベートサブネットに配置するのがベストプラクティスです。
LambdaをVPC内に配置(VPC Lambda化)することで、LambdaはVPC内のプライベートIPアドレスを持ち、インターネットを経由せずにRDSと安全に通信できるようになります。
具体的な設定手順・設計方法
この手順では、LambdaからVPC内のAmazon RDS(PostgreSQL)に接続する設定を行います。Pythonのデータベース接続ライブラリである psycopg2-binary をLambdaレイヤーとして導入する手順も合わせて解説します。
ステップ1:セキュリティグループの作成と設定
まず、Lambda用とRDS用にそれぞれセキュリティグループを作成します。
- Lambda用セキュリティグループ(sg-lambda)
- インバウンドルール:なし(空でOK)
- アウトバウンドルール:すべてのトラフィック(デフォルト)
- RDS用セキュリティグループ(sg-rds)
- インバウンドルール:カスタムTCP / ポート 5432 / ソース: 「sg-lambda(Lambda用セキュリティグループ)」
- アウトバウンドルール:すべてのトラフィック
ステップ2:Lambdaレイヤーの準備(外部ライブラリの導入)
LambdaからPostgreSQLに接続するために、外部ライブラリ psycopg2-binary を使用します。Lambda環境で動作させるために、ローカル環境(またはDocker環境)でzipパッケージを作成し、Lambdaレイヤーにアップロードします。※ここではPython 3.9環境を想定しています。
1. ターミナルで以下のコマンドを実行し、ライブラリを特定のディレクトリ構造にインストールしてzip化します。
mkdir -p python/lib/python3.9/site-packages
pip install psycopg2-binary -t python/lib/python3.9/site-packages/
zip -r psycopg2_layer.zip python
2. AWS管理コンソールで「Lambda」>「レイヤー」に移動し、「レイヤーの作成」をクリックします。
3. 作成した psycopg2_layer.zip をアップロードし、互換性のあるランタイムに「Python 3.9」を指定して作成します。
ステップ3:Lambda関数の作成とVPC設定
1. Lambda関数を新規作成します(ランタイム:Python 3.9)。
2. 関数の設定タブから「VPC」を選択し、「編集」をクリックします。
3. 接続先のVPC、RDSが存在するプライベートサブネット(冗長性のために最低2つ推奨)、およびステップ1で作成した「sg-lambda」セキュリティグループを選択し、保存します。
4. 関数のコード画面最下部にある「レイヤー」セクションから「レイヤーの追加」を選択し、ステップ2で作成したカスタムレイヤーを追加します。
ステップ4:テスト用コードの配置
以下のサンプルコードをLambda関数に貼り付け、環境変数(RDS_HOST, RDS_DB, RDS_USER, RDS_PASSWORD)を設定してテストを実行します。
import os
import psycopg2
def lambda_handler(event, context):
try:
conn = psycopg2.connect(
host=os.environ['RDS_HOST'],
database=os.environ['RDS_DB'],
user=os.environ['RDS_USER'],
password=os.environ['RDS_PASSWORD']
)
with conn.cursor() as cur:
cur.execute("SELECT version();")
db_version = cur.fetchone()
print(f"接続成功! DBバージョン: {db_version}")
conn.close()
return {
'statusCode': 200,
'body': 'Database connection successful!'
}
except Exception as e:
print(f"接続エラー: {e}")
raise e
実務での注意点
1. インターネット通信の確保(NAT Gatewayの必要性)
VPC内に配置されたLambdaは、デフォルトではインターネットにアクセスできません。もしLambda内から外部のサードパーティAPIなどを呼び出す必要がある場合は、Lambdaを配置するサブネットのルートテーブルに、NAT Gateway(またはNATインスタンス)を経由するルートを設定する必要があります。
2. コールドスタートと起動時間
現在のVPC Lambdaは、Hyperplane ENI(Elastic Network Interface)の仕組みにより起動が大幅に高速化されています。しかし、完全なコールドスタート時にはわずかな遅延が発生することがあります。WebAPIなどで極端な低レイテンシーが求められるシステムでは、プロビジョニングされた同時実行(Provisioned Concurrency)の利用を検討してください。
3. IPアドレスの枯渇対策
Lambda関数が急激にスケールアウトすると、設定したサブネットのプライベートIPアドレスを大量に消費します。サブネットのCIDR設計時には、Lambdaの最大同時実行数を考慮し、十分なIPアドレス空間(/24など)を確保しておきましょう。
まとめ
本記事では、AWS LambdaからVPC内のRDSへ安全に接続するための設定手順を解説しました。セキュリティグループによる正確なアクセス制御と、外部ライブラリを共通化するLambdaレイヤーの活用は、実務における必須スキルです。セキュリティと可用性を両立した安全なインフラを構築するために、ぜひ本手順を役立ててください。