Atlasを使った宣言的マイグレーションでDBスキーママイグレーションを自動化する

はじめに

この記事はTVerアドベントカレンダー2024 18日目の記事です。
17日目の記事は @HaSuzuki さんの 「Jetpack Compose で AppSearch に対応する」 でした。

こんにちは。TVerでバックエンドエンジニアをしている 小林 @k0bya4 です。

今回はDBマイグレーションツールであるAtlasを導入して、DBのスキーママイグレーション作業の自動化を進めていることについて書きます。

DBスキーママイグレーションの自動化

自動化前の課題

TVerサービスのバックエンドではDBスキーママイグレーションが必要なケースで手動でのクエリ実行によるスキーマの変更を行っています。

自動化を行う前の状況は

  • マイグレーションの実行が必要になったタイミングでsqlファイルをGitリポジトリにコミットしている
  • コードを開発環境(development、staging)そして、本番環境など各環境へデプロイする前にエンジニアの誰かがローカルから踏み台経由でDBに接続してddlを実行する

といったもので、課題としては以下のようなものがありました。

  • どこまでがどの環境に反映されたddlが判断できない
  • Git管理されているスキーマと実際のDBでスキーマの差異がある

自動化で達成したいこと

今回DBスキーママイグレーションの作業を自動化することで、クエリ実行時の人為的なミスに起因するリリース時のリスクの低減とリリース作業のリードタイムの削減を目指します。

宣言的スキーママイグレーション

今回スキーママイグレーションの方式として、主に宣言的スキーママイグレーション(Declarative Migration) が可能なツールを検討しました。
宣言的スキーママイグレーションを行うツールとは、理想状態のスキーマを定義に対してマイグレーション対象のDBのスキーマの状態が同一となるように差分を検知してddlを作成・実行していくようなアプローチで処理を行うツールです。

宣言的マイグレーションの採用理由

TVerサービスのバックエンドでは、今後テーブルの新規追加を伴う多数のプロジェクトが予定されています。 特に開発環境では試行錯誤を繰り返しながら頻繁なスキーマの変更伴うデプロイやローカル開発でのスキーマのsyncがしやすいように、開発者の負荷を減らすことを優先して都度差分を管理するバージョン管理型マイグレーション (Versioned Migration) ではなく、宣言的なマイグレーションが利用できないかを検討しています。ddlがオンラインで実行できるかなどチェックする必要はありますが、後述のワークフローでカバーできる判断をしています。

ツール選定

Atlas

AtlasはGo製で宣言的マイグレーションとバージョン管理型のマイグレーションの双方に対応したツールです。

比較した他のツールについては今回割愛しますが、主に以下のメリットからAtlasを採用しています。

  • 企業 (Ariga Technologies) によるメンテナンスがなされており、有償プランやサポートの体制があり、ある程度長期的に安定した開発が見込める
  • 環境によって宣言的マイグレーションとバージョン管理型のマイグレーションを使い分けるようなユースケースにも対応できる
  • トラブル時にメンバーのスキルセット(Go)的にコードを追いかけやすい

導入にあたり追加した設定

設定ファイルの追加

Atlasの設定ファイルはHCLで記述します。 理想状態のスキーマの定義として参照するSQLやHCLのファイルのパスなど、プロジェクト単位や環境単位で定義できます。 (Atlasでは、スキーマの定義にもHCLを使うケースを想定して書かれていることが多いです。)

破壊的変更のスキップ

今回、スキーマの破壊的な変更についてはスキップできるよう設定を追加しました。 HCLで設定を記述できるので、以下のように実行時の引数を参照してdiffのskipをするようにしています。

variable "destructive" {
  type    = bool
  default = false
}

diff {
  skip {
    drop_schema = !var.destructive
    drop_table  = !var.destructive
    drop_column = !var.destructive
  }
}

GitHub Actionsでのマイグレーション実行

CDでマイグレーションの実行を行う際の環境についても紹介します。 今回、AWS環境のプライベートサブネットにあるRDSにクエリ実行するにあたってCodeBuildを利用したワークフローを構築しています。

ワークフロー

以下のようなワークフローでの実行を行います。 宣言的マイグレーションの採用理由で述べたddlの正当性についてのチェックはツールが生成したddlをPRのレビュー時と開発環境でのデプロイ時に行うこととしています。また、破壊的な変更についてはリリースのロールバックが必要となったケースなどで、スムーズな切り戻しができるようデプロイと同期的に行わないこととしました。

GitHub Actionsでのマイグレーション実行時のワークフロー
GitHub Actionsでのマイグレーション実行時のワークフロー

GitHub Actionsのself-hosted runnerとしてCodeBuildを使う

2024年4月よりCodeBuildをself-hosted GitHub Actions runnerとして利用できるようになっています。

GitHubとの接続方法などは以下の手順が詳しいため、ここでの説明は割愛します。

https://docs.aws.amazon.com/codebuild/latest/userguide/action-runner.html

VPC内に配置したCodeBuildをself-hosted GitHub Actions runnerとして利用することで、RDSに接続するDBマイグレーションのワークフローをGitHub Actionsの構文を利用して実行できます。

まとめ

Atlasを利用して、宣言的スキーママイグレーションの仕組みの導入を進めていることについて書きました。 宣言的マイグレーションGitHub Actionsのself-hosted runnerを利用して、バックエンド開発者の負荷を減らしたDBスキーママイグレーションの実施ができる形を目指しています。 現在は本番環境への導入に向けて準備を進めている状態なので、実運用上の課題など出てくれば追って発信できればと思います。

おわりに

TVerでは、開発チームのスケールのため開発サイクル上の課題の改善に取り組むEnablingチームがあります。
Backend Enabling Team ができました in TVer

今回のDBスキーママイグレーション自動化の取り組みも、Enablingチームで主導しているTVerサービスのバックエンドリアーキテクチャプロジェクトの一環となっています。 Enablingチームの最近の取り組みについてはTVerアドベントカレンダー2024 15日目の記事 「Backend Enabling Teamと立ち上がりの半年」 もぜひご覧になってください。

ご興味を持っていただけた方は、ぜひカジュアル面談へのご応募お待ちしております。
https://herp.careers/v1/tver/xujbYGz8ZD5w

明日は @NagaiKoki さんの「Webフロントチーム内製化への道のりとこれから」が公開されます。