💡

tbls を Aurora Serverless・DSQL で使おうとしてハマったときの TIPS

に公開

TL;DR

  • tbls を Aurora serverless(v2) PostgreSQL 互換に対して Data API 経由で接続しようとしたところ、Data API をサポートしていなかったので、外部ドライバーを自作することになった
  • Aurora DSQL では、アクセスに必要な Token をパスワードとして DNS 形式で渡そうとして Parse エラーになっていたが、URL エンコードをすることで解決した

この記事を読んで欲しい人

  • Aurora serverless(v2) PostgreSQL 互換を Data API 接続で tbls を利用しようとしている人
  • DSQL で tbls を使おうとしている人

はじめに

皆さん、tbls 使っていますか?、GitHub 上の Markdwon でスキーマとその関係の情報を一覧で見られるので便利ですよね。DB の環境間比較が可能な diff も運用上便利な機能です。

さて、本記事ではその便利な tbls を AWS のサーバーレス RDB サービスである Aurora serverless(v2) PostgreSQL 互換を Data API で利用しようとしたケースと DSQL で使ってみようとしたケースでそれぞれハマったので、それらの対応策をまとめます。
さらに、これらのサービスで tbls を利用する時の特徴比較について最後に表形式でまとめたいと思います。

https://aws.amazon.com/jp/rds/aurora/serverless/

https://aws.amazon.com/jp/rds/aurora/dsql/

Aurora Serverless に Data API 経由で接続しようとしたら未対応

著者は、lambda x RDS 構成を割安で利用できないかを検討しており、下記の記事を読んで Data API を利用してみることにしました。

https://qiita.com/hirooka622/items/c6ce351d4e5cbd6feba3

これで、管理者が DB にアクセスするための踏み台の検討や、VPC lambda の制約なしに lambda x RDS 構成を利用できるぞーと喜んでいたのですが、tbls を使おうとなった時に問題が起こりました。

tblsは Data API をサポートしていませんでした

しかし、幸いなことに tbls は External database driver をサポートしてくれていたので、tbls 公式のpostgres ドライバーの実装や外部ドライバーを作成した先駆者の記事を参考にして、PostgreSQL 向けの Data API ドライバーである tbls-driver-rdsdataを作成しました。

本外部ドライバーの利用方法については、リポジトリの README.md を参照してください。

https://github.com/utcarnivaldayo/tbls-driver-rdsdata

Aurora DSQL に接続しようとして、Parse エラー

Data API 外部ドライバーを完成させた後日、私は Aurora DSQL が GA されていたことを知り、使ってみることにしました。

https://dev.classmethod.jp/articles/amazon-aurora-dsql-generally-available/

少し調べると、DSQL は Data API のような独自の接続方式ではなく、psqlで接続できる方式が取られており、tbls が標準サポートする postgres ドライバで接続できそうなことがわかりました。

通常の PostgreSQL との接続方法の違いといえば、パスワードを認証トークンとして定期的に発行しなければならない点ぐらいでした。

bash
# Your DSQL HOST
export PG_HOST='qyabuefksp2schmza2xkrmm5q4.dsql.ap-northeast-1.on.aws'
export PGPASSWORD=$(aws dsql generate-db-connect-admin-auth-token \
  --region ap-northeast-1 \
  --expires-in 3600 \
  --hostname ${PG_HOST})

# Aurora DSQL requires SSL and will reject your connection without it.
export PGSSLMODE=require

# Connect with psql, which automatically uses the values set in PGPASSWORD and PGSSLMODE.
psql --quiet \
  --username admin \
  --dbname postgres \
  --host ${PG_HOST}

https://docs.aws.amazon.com/ja_jp/aurora-dsql/latest/userguide/getting-started.html#accessing-sql-clients-psql

私は、下記のような tbls の設定ファイル作成して、下記のコマンドで tbls docを実行しようとしました。

tbls.yml
dsn: postgres://${PG_USER}:${PG_PASSWORD}@${PG_HOST}:${PG_PORT}/${PG_DATABASE}
docPath: db/docs/dsql
er:
  format: mermaid
bash
# Your DSQL HOST
export PG_HOST='qyabuefksp2schmza2xkrmm5q4.dsql.ap-northeast-1.on.aws'
export PG_USER='admin'
export PG_PORT=5432
export PG_DATABASE='postgres'
export PG_PASSWORD="$(aws dsql generate-db-connect-admin-auth-token \
  --region ap-northeast-1 \
  --expires-in 3600 \
  --hostname ${PG_HOST})"

tbls doc -c tbls.yml

tblsコマンドを実行しようとしたところ下記の Parse エラーが発生しました。

stdout
tbls doc -c tbls.yml
parse "postgres://admin:qyabuefksp2schmza2xkrmm5q4.dsql.ap-northeast-1.on.aws/?Action=DbConnectAdmin&~~~
~~~ token が長いので中略 ~~~
b057806c@qyabuefksp2schmza2xkrmm5q4.dsql.ap-northeast-1.on.aws:5432/postgres": invalid port ":qyabuefksp2schmza2xkrmm5q4.dsql.ap-northeast-1.on.aws" after host

直感的に、Token によくない文字列でも含まれているのだろうと推測しましたが、対応策は思いつきませんでした。

なんとなく tbls の issue を眺めていたところ、URL エンコードすれば解決するかもしれないとわかり試してみました。

https://github.com/k1LoW/tbls/issues/429

具体的な対応としては、Token の生成後にパイプしてjq -Rr @uriで URL エンコードする処理を追加しました。

bash
# Your DSQL HOST
export PG_HOST='qyabuefksp2schmza2xkrmm5q4.dsql.ap-northeast-1.on.aws'
export PG_USER='admin'
export PG_PORT=5432
export PG_DATABASE='postgres'
export PG_PASSWORD="$(aws dsql generate-db-connect-admin-auth-token \
  --region ap-northeast-1 \
  --expires-in 3600 \
  --hostname ${PG_HOST} | jq -Rr @uri)"

tbls doc -c tbls.yml

Token を URL エンコードすることで問題なくドキュメント生成ができました。

stdout
tbls doc -c tbls.yml
db/docs/dsql/README.md
db/docs/dsql/sys.job.md
db/docs/dsql/sys.iam_identity.md
db/docs/dsql/sys.iam_auth_member.md
db/docs/dsql/sys.viewdef.md
db/docs/dsql/sys.roles.md
db/docs/dsql/sys.iam_pg_role_mappings.md
db/docs/dsql/sys.jobs.md
db/docs/dsql/public.friends.md
db/docs/dsql/public.guilds.md
db/docs/dsql/public.users.md
db/docs/dsql/public.guild_members.md
db/docs/dsql/schema.json

tbls を Aurora Serverless・DSQL で利用する際の特徴比較

ここまで、tbls を Aurora Serverless・DSQL で使おうとした時のハマりポイントについて記載してきました。まとめとして、tbls 利用を前提とした時の Aurora Serverless・DSQL のメリット・デメリットの比較をしたいと思います。

観点/サービス Aurora Serverless + RDS Proxy Aurora Serverless + Data API Aurora DSQL
ドライバ ⭕️: tbls 標準対応 ⚠: 外部ドライバ(tbls-driver-rdsdata) ⭕️: tbls 標準対応(ただし、Token の URL エンコードが必要)
接続のリアルタイム性 ❌: DB 再起動時は約15秒以上時間がかかる ❌: DB 再起動時は約15秒以上時間がかかる ⭕️: 良い
料金 ❌: 高価 ⚠: Data APIは安価 ⭕️: 比較的安価
ER 図生成 ⭕️: 対応 ⭕️: 対応 ❌: DSQL は外部キーやパーティションをサポートしていないので ER図の作成不可
開発者体験 ❌: DB 再起動に時間を要する・インフラエンジニアにとって管理と認知コストが高い。 ❌: DB 再起動に時間を要する・Data API クライアントが独自で、CLIからSQLファイルを標準入力に流せないなど制約が多い。 ⭕️: 求めていたサーバーレス RDB の開発者体験。
  • Aurora Serverless + RDS Proxy
    • 予算があり DSQL が採用できないケースはこちらを採用。この構成を選ぶくらいであれば、Serverless でなく普通の Aurora を使った方が開発者体験は良いはずです。
  • Aurora Serverless + Data API
    • サーバーレス構成で金額も抑えたいけど、ER 図は作成したいという場合に有効と思われます。ただし、DB 再起動の対策としてアプリケーションコードや tbls の実行にリトライ機能を実装しなければならないなどの実装の手間も発生します。
  • Aurora DSQL
    • 求めていたサーバレス RDB という良い開発者体験。DSQL の制約がかかり、外部キーや SERIAL の利用ができない・楽観的制御の要件がクリアできる場合は有効です。ER 図は前述の制約で作成できません。

まとめ

本記事では、tbls を Aurora Serverless・DSQL で利用した際のハマりポイントとその対応策を紹介しました。
それらを加味した上で tbls を Aurora Serverless・DSQL で利用する際の特徴比較をまとめました。

本記事が tbls 利用者・AWS サーバーレス構成のアーキテクトの一助となれば幸いです。

Discussion