はじめに
DROBE ではサービスで使うマスターデータの管理を Laravel の Seeder を使って行なっています
この記事では、具体的にどうやってマスターデータの管理と運用を行なっているかを解説します
Seeder によるマスターデータの更新
Laravel には seeder と呼ばれる機能があります
テストや開発用などで、先に定義しておいたデータを DB に入れる事が出来る機能です
以下のようなコードを書いておき、コマンドラインで seeder を呼ぶといった使い方をします
<?php
namespace Database\Seeders;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Str;
class DatabaseSeeder extends Seeder
{
/**
* Run the database seeders.
*
* @return void
*/
public function run()
{
DB::table('users')->insert([
'name' => Str::random(10),
'email' => Str::random(10).'@gmail.com',
'password' => Hash::make('password'),
]);
}
}
起動する時のコマンドラインは以下のようなイメージです
php artisan db:seed --class=UserSeeder
マスターデータの管理
DROBE ではマスターデータは CSV を git にコミットする形で管理しています
主な理由は以下です
- レビューが可能になる
- 変更の履歴が追える
- 必要があればデータのバリデーションが出来る
非エンジニアに PR を上げてもらう事も想定しているため、サービス本体とは分離して別の repository にしています
サービス本体はマスターデータの repository を submodule として持っているという構造です
├── database
└── seeders // ここまでは Laravel が用意している folder
└── masters // ここが submodule
├── master_1.csv
├── master_2.csv
├── ...
呼び出し時には以下のような形になります
use League\Csv\Reader; // csv reader は League\CSV を使っています
public function run()
{
// csv を読む
$csv = Reader::createFromPath('path_to_csv_file');
foreach ($csv as $record) {
// Model に変更を加える
Model::upsert($record->toArray());
}
}
マスターデータの更新
マスターデータの更新は、下記要件を満たせるようなものを考えて設計しています
- サービス本体を Deploy しなくても、マスターデータを更新できる
- 出来るだけ自動化されている (ボタンポチ、くらいで更新したい)
- 更新が終わったら知りたい
以下のパイプラインによって上記の全要件を満たすマスターデータの更新が可能になっています
各ステップを解説します
github actions
まず、最初にマスターデータを管理している repository の github actions を起動します
repository は csv を管理しているだけのもので、github actions はそれら csv を zip に固めて s3 にアップロードします
codepipeline
codepipeline は s3 のファイルを監視していて、github actions によってファイルが更新されると起動し 2 つの codebuild を順番に実行していきます
codebuild1
最初の codebuild はマスター更新用のコンテナを作る役割です
ます本番サーバー用に作られたコンテナをホストしている ECR から本番サーバー用のコンテナを pull します
次にそのコンテナ内部の Seeder 用 CSV を、アップロードされた zip ファイルに入っている CSV と差し替えます
最後に docker commit を行い、更新された CSV を持つコンテナを作り docker push によって、別の ECR repository に push します
codebuild2
2 つめの codebuild は 1 で作ったコンテナを指定して Fargate task を起動します
Fargate の起動コマンドに、Laravel の seeder の起動コマンドを指定する事で Fargate からマスターの更新処理を実行します
Fargate はコマンドが終わるまで破棄されないので、マスターの更新に多少時間が掛かっても問題なく実行できます。またマスターが大きくなっても Fargate のリソースのサイズを調整する事である程度までは耐えられると考えています
一連の処理が終わったら、AWS SNS 経由で slack に通知を行ないます
さいごに
DROBE におけるマスター更新の仕組みの解説をしました
もちろん git などを使わずに本番 DB のみでマスターを管理していくという方法もあると思いますが、やはりレビューができて変更履歴が追えるというのは便利だなと感じています
更新の仕組みの構築の手間や、即時でデータが反映されないといった短所もありますが、それを踏まえてもマスターデータを git で管理するという手法は魅力的だなと考えています