【AWS】LambdaからRDS Proxy経由でPostgreSQLへ接続する
LambdaからRDS Proxy経由でPostgreSQLへ接続する
この記事ではLambdaからRDS Proxy経由でRDS PostgreSQLへ接続する方法際の設定方法について書いています。
RDSの設定
インスタンス作成後認証方式とセキュリティグループの設定を行います。
認証方式設定
RDS ProxyとRDS間はID/パスワードによる認証となるのでRDSのIAM認証を無効にしています。
セキュリティグループ設定
RDSのセキュリティグループのインバウンド通信には後で作成するRDS Proxyからの通信を許可します。ここでは検証のためローカルPCのIPアドレスからの通信も許可する設定にしています。
検証用データベースとユーザの作成
マスターユーザでRDSインスタンスへ接続し、RDS Proxy経由で接続する際に使用するユーザと検証用のデータベース、テーブルを作成します。
# ユーザ作成
$ create user test_user with password 'xxxxx';
# test_userを所有者とするデータベースを作成するためにマスターユーザをグループへ追加する
$ grant test_user to postgres;
# データベースとテーブル作成
$ create database test_db2 owner=test_user;
$ create table employee(id serial primary key, name text);
$ insert into employee(name) values ('hoge'),('hogehoge'),('hogehogehoge');
Lambdaの作成
ロール設定
LambdaからRDS ProxyやRDSのようにVPC内のサービスにアクセスするためには、LambdaをVPC内に作成する必要があります。このときLambdaはネットワークインターフェイスの作成などを行える権限を設定する必要があります。このために「AWSLambdaVPCAccessExecutionRole」というAWS管理ポリシーが用意されていますので、これをLambdaに割り当てます。
VPC設定
RDS Proxyと通信可能なVPCとサブネットをLambdaに割り当てます。ここではLambda, RDS Proxy, RDSは全て同じVPC, 同じSubnetに割り当てています。
RDS Proxy
RDSのコンソールからProxiesを選び「プロキシを作成」をクリックしてRDS Proxyの作成を開始します。
作成するRDS Proxyの名前、接続先のRDSのエンジンを選択します。今回はLambdaとRDS Proxy間でIAM認証を行うために「Transport Layer Securityが必要」にチェックを入れます。
ターゲットグループ の設定で接続先のRDSを選択します。PostgreSQLの場合12系はRDS Proxyに対応していません。12系で作成するとドロップダウンに表示されないため注意してください。
RDS Proxy用のロールを新規作成するため「IAMロールを作成」を選択します。また、IAM認証を行うためにIAM認証は「必須」とします。
そして、RDS ProxyがRDSへ接続する際に使用するID/Passwordを保存するためにSecrets Managerのシークレットを作成します。新規作成する場合は「新しいシークレットを作成する」をクリックします。
Secrets Manager
RDS Proxyが使用するシークレットを新たに作成します。シークレットの種類を「RDSデータベースの認証情報」を選択します。そして、シークレットに保存するユーザ名、パスワードはRDS接続に使用するものを入力します。この記事の例ではあらかじめ作成しておいた「test_user」とそのパスワードを入力します。
そして、接続先のRDSインスタンスを選択します。
次へをクリックしシークレットの名前と説明を入力して次へ進みます。
今回はパスワードのローテーションは行わない設定で作成しました。最後に確認画面で入力内容を確認しシークレットを作成します。
LambdaからRDS Proxyへの接続
Lambda関数からRDS Proxyへ接続するためのコードを記述します。この例ではLambdaの言語をPython3.8としています。
レイヤーの追加
psycopg2を使用してPostgreSQLに接続します。psycopg2を簡単に使用するためにLambdaでPostgreSQLを使う(Python + psycopg2)で紹介されているようにレイヤーの追加を行います。
「ARNを指定を指定」を選択し、ARNへ「arn:aws:lambda:ap-northeast-1:898466741470:layer:psycopg2-py38:1」と入力し「追加」をクリックします。
RDS Proxyへの接続しSQLを実行するコード
以下のようなコードを記述してRDS ProxyへIAM認証で接続します。コードとしては接続先のエンドポイントがRDS Proxyにすればいいだけです。
この例ではあらかじめ作成しておいたemployeeテーブルのデータをコンソールに出力しているだけです。
import json
import os
import sys
import boto3
import psycopg2
def lambda_handler(event, context):
ENDPOINT="rds-proxy-xxxxx.proxy-xxxxxx.ap-northeast-1.rds.amazonaws.com"
PORT="5432"
USR="test_user"
REGION="ap-northeast-1"
client = boto3.client('rds')
# IAM認証を行いトークンを取得
token = client.generate_db_auth_token(DBHostname=ENDPOINT, Port=PORT, DBUsername=USR, Region=REGION)
# 取得したトークンをパスワードとしてデータベースへ接続
connection = psycopg2.connect(host=ENDPOINT, database="test_db2", user=USR,password=token, sslmode='require')
# SQLを実行
cur = connection.cursor()
cur.execute('SELECT * FROM employee')
results = cur.fetchall()
# コンソールへ出力
for r in results:
print(r)
# TODO implement
return {
'statusCode': 200,
'body': json.dumps('Hello from Lambda!')
}
作成した関数をテスト実行してみると以下のようにemployeeテーブルのデータが取得できています。
この記事ではRDS Proxyを使ってLambdaからRDSへ接続する方法を紹介しました。