はじめに
サーバーレスアーキテクチャにおいて、AWS LambdaからAmazon Auroraなどの関係データベース(RDB)に接続する設計は一般的です。しかし、Lambdaの急激なスケールアウトに伴う「DB接続(コネクション)の枯渇」や「フェイルオーバー時の瞬断」は、多くのインフラエンジニアが直面する代表的なトラブルです。本記事では、これらの課題を解決するベストプラクティスである「Amazon RDS Proxy」を経由した安全かつ高効率な接続手順について、ステップバイステップで解説します。
前提知識/必要な理由
Lambda関数はリクエストに応じて瞬時にスケールし、並行して多数のコンテナが起動します。RDBは通常、同時に接続できるコネクション数に上限があるため、Lambdaが直接接続するとすぐにコネクション上限に達し、接続エラーが発生します。
ここで活躍するのがAmazon RDS Proxyです。RDS Proxyを導入する主な理由は以下の通りです。
- コネクションプーリング:確立済みのDBコネクションをプールして使い回すことで、DBサーバーのCPU・メモリ負荷を大幅に軽減します。
- フェイルオーバーの高速化:Auroraのプライマリインスタンスが停止した際、DNSの切り替えを待つことなく、RDS Proxyが迅速にターゲットを代替インスタンスに切り替えるため、アプリケーション側の接続エラーを最小限(約30%〜60%短縮)に抑えられます。
- セキュリティの向上:データベースの認証情報をLambdaの環境変数に直接保持させることなく、AWS Secrets Managerで一元管理し、安全にローテーションできます。
具体的な設定手順・設計方法
今回は、VPC内に構築されたAurora PostgreSQLに対して、VPC内LambdaからRDS Proxyを経由して安全に接続する構成を構築します。
Step 1: Secrets ManagerにDB認証情報を保存する
RDS ProxyがAuroraに接続するためのユーザー名とパスワードをSecrets Managerに登録します。
- AWSコンソールで「Secrets Manager」を開き、「新しいシークレットを保存する」をクリックします。
- シークレットのタイプで「Amazon RDS データベースの資格情報」を選択します。
- データベースのユーザー名とパスワードを入力し、対象のAuroraクラスターを選択して保存します(例:
prod/db/credentials)。
Step 2: RDS Proxy用のIAMロールとセキュリティグループの作成
RDS ProxyがSecrets Managerから認証情報を取得できるようにするためのIAMロールを作成します。信頼関係に rds.amazonaws.com を指定し、以下のポリシーをアタッチします。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "secretsmanager:GetSecretValue",
"Resource": "arn:aws:secretsmanager:ap-northeast-1:123456789012:secret:prod/db/credentials-*"
}
]
}
また、ネットワーク間の通信を制御するために、以下の3つのセキュリティグループ(SG)を用意します。
- Lambda用SG: アウトバウンドのみ許可(デフォルト)。
- RDS Proxy用SG: Lambda用SGからのポート5432(PostgreSQL)のインバウンド接続を許可。
- Aurora用SG: RDS Proxy用SGからのポート5432のインバウンド接続を許可。
Step 3: RDS Proxyの作成
RDSのコンソールから「プロキシ」を選択し、「プロキシの作成」をクリックします。
- ターゲットデータベース:対象のAuroraクラスターを選択します。
- 接続性:Lambdaと同一のVPC、および事前に用意した「RDS Proxy用SG」とサブネットを選択します。
- 認証:Step 1で作成したSecrets Managerのシークレットと、Step 2で作成したIAMロールを選択します。
Step 4: Lambda関数の作成と外部ライブラリの導入
VPC内で動作するLambda関数(Python 3.x)を作成します。VPC設定には「Lambda用SG」と、Auroraが存在するプライベートサブネットを指定します。
ここで、PythonからPostgreSQLに接続するために psycopg2 ライブラリを使用しますが、Lambdaの標準環境には含まれていません。以下のいずれかの手順で導入(パッケージング)してください。
- Docker等でパッケージビルド:
pip install psycopg2-binary -t .を実行し、ライブラリ群を含めたZIPファイルをLambdaに直接アップロードします。 - Lambdaレイヤーの活用: AWSコミュニティで公開されている高品質な外部レイヤー(例: Klayersなど)から、使用しているPythonバージョンに対応した
psycopg2レイヤーのARNを関数に追加します。
Step 5: Lambda関数のコード実装
以下は、RDS Proxyを経由してAuroraにクエリを実行するLambda関数のサンプルコードです。環境変数 PROXY_ENDPOINT にはRDS Proxyの書き込みエンドポイント、DB_NAME にはデータベース名を指定します。
import os
import psycopg2
import boto3
import json
def get_secret():
secret_name = "prod/db/credentials"
region_name = "ap-northeast-1"
client = boto3.client(service_name='secretsmanager', region_name=region_name)
response = client.get_secret_value(SecretId=secret_name)
return json.loads(response['SecretString'])
def lambda_handler(event, context):
creds = get_secret()
try:
conn = psycopg2.connect(
host=os.environ['PROXY_ENDPOINT'],
database=os.environ['DB_NAME'],
user=creds['username'],
password=creds['password'],
port=5432,
connect_timeout=5
)
with conn.cursor() as cur:
cur.execute("SELECT NOW();")
result = cur.fetchone()
print(f"Connection successful! DB Time: {result}")
conn.close()
return {"statusCode": 200, "body": "Success"}
except Exception as e:
print(f"Error: {e}")
return {"statusCode": 500, "body": "Connection Failed"}
実務での注意点
- セキュリティグループのチェーン:疎通エラーの多くはSGの設定ミスです。Lambda → RDS Proxy → Aurora の順にインバウンドがチェーンで許可されていることを必ず確認してください。
- ピン留め(Pinning)の回避:RDS Proxyを使用しても、セッション状態を変更するクエリ(一時テーブルの使用や
SETコマンドなど)を実行すると、「ピン留め」と呼ばれる現象が発生し、接続がプールされず特定のクライアントに固定されてしまいます。クエリの設計はシンプルに保つことがベストプラクティスです。 - コストの考慮:RDS Proxyは非常に有用ですが、プロキシが稼働するvCPU時間に対して時間課金が発生します。検証用の低コスト環境など、同時アクセスが極めて少ないシステムでは導入の是非を慎重に判断してください。
まとめ
本記事では、VPC内のLambdaからRDS Proxyを経由してAurora PostgreSQLに安全かつ効率的に接続するための設計と設定手順を解説しました。RDS Proxyを導入することで、Lambdaの強みである高いスケーラビリティを活かしつつ、リレーショナルデータベースが抱えるコネクション制限の壁を克服できます。耐障害性とパフォーマンスに優れたサーバーレスインフラの構築に、ぜひお役立てください。