ECS 環境における Laravel と Master 更新
ECS 環境における Laravel と Master 更新

ECS 環境における Laravel と Master 更新

はじめに

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'),
        ]);
    }
}
公式に記載のもっとも簡単な seeder

起動する時のコマンドラインは以下のようなイメージです

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
						├── ...
seeder 周りのフォルダ構造

呼び出し時には以下のような形になります

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());
    }
}
csv を読み込んでマスターを更新する処理のイメージ

マスターデータの更新

マスターデータの更新は、下記要件を満たせるようなものを考えて設計しています

  • サービス本体を Deploy しなくても、マスターデータを更新できる
  • 出来るだけ自動化されている (ボタンポチ、くらいで更新したい)
  • 更新が終わったら知りたい

以下のパイプラインによって上記の全要件を満たすマスターデータの更新が可能になっています

github actions と codepiepline を活用したマスターデータ更新のパイプライン
github actions と codepiepline を活用したマスターデータ更新のパイプライン

各ステップを解説します

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 に通知を行ないます

image

さいごに

DROBE におけるマスター更新の仕組みの解説をしました

もちろん git などを使わずに本番 DB のみでマスターを管理していくという方法もあると思いますが、やはりレビューができて変更履歴が追えるというのは便利だなと感じています

更新の仕組みの構築の手間や、即時でデータが反映されないといった短所もありますが、それを踏まえてもマスターデータを git で管理するという手法は魅力的だなと考えています