TORANA TECH BLOG

株式会社トラーナのエンジニアチームの開発ブログ

本番DBに対してアドホックなSQLの実行を制限・記録するツール群の紹介

SREのクラシマです。
様々な事情で、本番DBに対してアドホックSQLを実行する必要がありますが、できるだけ安全に実行したいものです。
SREチームがGolangで書いたツールがちょこちょこあるのでご紹介。(クラシマはそんなに作ってないです)

IAMポリシー一時付与CLI: shinse

❯ aws-vault exec $AWS_PROFILE -- shinse request

How long ...
format is 1m or 1h or 2006-01-02T15:04:05

Enter : 1h

Would you like to request with ...

Account: honban
PermissionSet: DatabaseConnect
End: 2023-10-20T16:06:07

Enter y/n: y
🎍🎍🎍🎍🎍🎍🎍🎍🎍🎍🎍🎍🎍🎍🎍🎍🎍🎍🎍🎍🎍🎍🎍🎍🎍🎍🎍🎍🎍🎍🎍🎍🎍
complete🥱

本番環境アカウントでのAWSのアクセス権限は、ReadOnlyAccessにしています。
shinseコマンドを使用してAdministratorAccessポリシーや、自作のDatabaseConnectポリシーを一時的にアタッチします。
99designs/aws-vault: A vault for securely storing and accessing AWS credentials in development environments も併用していることが多いです。
AWS Systems Manager Change Manager - AWS Systems ManagerSDKを使って呼び出しています。

❯ aws-vault exec $AWS_PROFILE -- shinse get-db-cred
dbname: username password

DBへの接続ID・パスワードも、一定時間だけ利用できるものが発行されます。
ParameterStoreにID・パスワードが格納されるので、取得するサブコマンドがあります。

ポートフォワードCLI: portforward

❯ aws-vault exec (awsp) -- portforward appname db
2023/10/20 14:07:44 host: appname-prd.cluster-****.ap-northeast-1.rds.amazonaws.com
port: 3306
localPort: 3306
accountID: 99999999999
bastion: app-bastion-prd
2023/10/20 14:07:44 desiredCount: 1
2023/10/20 14:07:44 taskID: 834e889b47c54cafb4b6bb4274028a4a

Starting session with SessionId: username@torana.co.jp-09db166e98fe02c3b
Port 3306 opened for sessionId username@torana.co.jp-09db166e98fe02c3b.
Waiting for connections...

DBのhostname、portとlocalPortをアプリケーションごとに設定したconfig.yamlを参照して、fujiwara/ecsta: ECS Task Assistant tool. をライブラリとして呼び出し、portforwardしています。
踏み台Fargateの構築の話 - TORANA TECH BLOG で紹介した踏み台Fargateを使っています。 踏み台Fargateが起動していない場合は起動する機能も含まれています。
↑のblog時点ではシェルスクリプトで誤魔化していましたが、Golangに書き換えました。

アドホックな更新SQLを通知するCLI: tosugo

DBで実行したSQLは、アプリケーションが発行したSQLと違い十分な検証が行われているとは言えません。
また、GitHub Issueを作ってレビューを受けたものを実行するルールですが、レビュー外のSQLを実行することもできてしまいます。
これに対応するため、誰が・いつ・どのようなSQLを実行したか検知するツールを作成しました。

RDS Auroraの監査ログ機能を有効化し、CloudWatch Logsに実行したSQLをログ出力します。
Amazon Aurora MySQL DB クラスターでのアドバンストな監査の使用 - Amazon Aurora
すべてのSQLログを出力するとCloudWatch Logsのコストがそれなりに掛かるため、アプリケーションから発行したSQLは除外しています。
ここから、CloudWatch Logs Insights SDKを呼んで、1日分の更新クエリを抽出、日次でGitHub Issueを作成しています。 shinseがDBのユーザまで作ってくれるので、誰が実行したかわかる、という仕組みです。

(監査ログに限らず、24時間ログが作成されない場合またはストレージの15%が消費された場合に、ログの出力が止まってしまう、という難点もあるのですが...)

UUIDv4() は自作のストアドファンクションです。

本当はtotsugoにするつもりがtypoしてtosugoになった、とツールの作者がREADMEに書いています。

まとめ

あまり事例が見つけられずに困ってしまい、AWSさんに相談したりして構築しました。
このあたり、皆様どうされてるんでしょうか...??? 聞くところによると、アドホックSQL実行も全てRuby on RailsやLaravelにもあるmigrationに寄せてしまう、というやり方もあるそうです。
トラーナでは本番DBへのmigrationは行っていないので、同じやり方にはできないのですが...。