🌟

SQLAlchemyでRDS ProxyをIAM認証で接続する際に発生したエラーの解決

2024/01/20に公開

概要

  • AWS LambdaからSQLAlchemyを使ってRDS ProxyをIAM認証で利用しPostgreSQLに接続する際に、以下のエラーに悩まされたので、その解決方法を紹介します
  • エラー内容

結論

  • URLエンコードを利用して、generate_db_auth_tokenで取得したトークンをエンコードする必要がありました

詳細

  • 実装内容と説明となります
from boto3
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from urllib.parse import quote

try:
  rds = boto3.client('rds')
  region = os.getenv("AWS_REGION")
  cert_path = './cert/AmazonRootCA1.pem'

  password = rds.generate_db_auth_token(
      DBHostname=db_host,
      Port=db_port,
      DBUsername=db_user,
      Region=region
  )
  # URLエンコードが必要だった
  password = quote(password)
  
  url = f"postgresql+psycopg2://{db_user}:{password}@{db_host}:{db_port}/{db_name}?sslmode=verify-full&sslrootcert={cert_path}"
  engine = create_engine(url)
  session = sessionmaker(autocommit=False, autoflush=False, bind=engine)
  # queryなど
  session.execute("SELECT * FROM table_name")
except Exception as e:
  print(f"Exception: {e}")
  raise e

原因と考察

  • rds.generate_db_auth_tokenした結果に特殊文字が含まれていること
  • SQLAlchemyが接続情報を連結してURLとして扱うこと
  • これらが原因で不正なトークンとして認識されていたようです
  • 他のパッケージは、URLではなくDBの接続情報をそれぞれのパラメータとして渡すことが多いため、このようなエラーは発生しづらいのだと考えられます

参考

Discussion