TL;DR
- sslmode は
verify-full
ではなくverify-ca
にする - あとはユーザーガイドの通りにやればOK
発端
どうやら IAM 認証が使えるのはメインの Read/write エンドポイントだけみたいですね。
→ AWS のサポートにて方法を教えてもらいました。
メインのエンドポイントとリーダーエンドポイントそれぞれで cli でトークンを作成して接続してみましたが、リーダーエンドポイントのときは次のエラーになりました。
sql: server common name "*.proxy-●●●●●●●●●●●.ap-northeast-1.rds.amazonaws.com" does not match host name "testforsupportcase-read-only.endpoint.proxy-●●●●●●●●●●●.ap-northeast-1.rds.amazonaws.com"
原因と対策
リーダーエンドポイントのホスト名に .endpoint.
があるため、証明書のコモンネームと不一致とされているようです。
コモンネームの一致まで検証しないようにすることで接続できるため sslmode を verify-full
ではなく verify-ca
にすれば接続できるということでした。
Python (Psycopg2) でのRDS Proxy IAM認証 接続サンプルコード
./AmazonRootCA1.pem
というパスで AmazonRootCA1.pem ファイルが置かれている想定です。
Lambda であれば lambda_function.py と同じフォルダに置いておけばOKです。
import psycopg2
import boto3
def connect_with_iam(proxy_endpoint, dbname, username, region, port="5432"):
client = boto3.client(service_name='rds', region_name=region)
token = client.generate_db_auth_token(DBHostname=proxy_endpoint, Port=port, DBUsername=username, Region=region)
con = psycopg2.connect(
host=proxy_endpoint,
port=port,
dbname=dbname,
user=username,
password=token,
sslrootcert='AmazonRootCA1.pem',
sslmode='verify-ca',
)
con.set_client_encoding('utf-8')
return con
IAM Role の設定等、その他の手順はユーザーガイドに従えばできます。
参考: IAMポリシー
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "rds-db:connect",
"Resource": "arn:aws:rds-db:{{REGION}}:{{AWS_ACCOUNT_ID}}:dbuser:{{PROXY_ID}}/{{DB_USER}}"
}
]
}
{{PROXY_ID}}
はプロキシARNの最後の prx-xxxxxxxxxxxxxxxx
の部分
参考記事
※PostgreSQL sslmode の説明は↑を参照