はじめに
前回の記事では、PHP5レガシーシステムの負債の全貌と刷新方針の決定について記録しました。
今回はその2として、実際のLaravel移植とインフラ移行の実録を記録します。
この移行で大切にしたこと
技術的な手順の前に、この移行全体を通じて最も大切にしたことをお伝えします。
それは現場のオペレーターの業務を壊さないことです。
MA前から10年分の業務フローを1人で回してきたオペレーターの方がいました。いきなり「移植後はこうしましょう」と宣言しても受け入れられないどころか、混乱しますので今回は以下の方針を取りました。
- まずは今まで通りの業務で回すことを最優先に移植する
- 季節ごとのキャンペーンなども従来通り実施しながら移植を進める
- 移植完了後の定例会で「業務上困っていること・非効率に感じていること」を出し合い、改善はその後
この順序を取ったことで現場の混乱を最小化しながらプロジェクトを進めることができました。そして業務を壊さない移植を続けたことでビジネス側の信頼を得られ、移植後のリファクタリングや業務改善の議論がスムーズに進むようになりました。
もちろんトップダウンで業務ごと刷新するほうが正解の場合もあり、どちらが良いかはケースバイケースです。今回はビジネス側の体制もオペレーター1人に依存しているためこのように判断しました。この判断が結果的にうまく機能したと思っています。
移行の全体像
移行は以下の順序で進めました。
- さくらVPS → AWS EC2へのインフラ移行(旧PHP5システムをEC2で稼働)
- 同一リポジトリにLaravelプロジェクトを作成・動作確認
- ALBでパス別に向き先を切り替えながら段階的にLaravel化
- Laravel完全移植後にEFS → S3、EC2 → ECS Fargateへ移行
インフラを先行させ、アプリケーション移植はその後というのが基本的な方針です。理由はシンプルで、まず旧システムをEC2上で動かした状態を作り、そこにLaravelを並走させることで切り替えリスクを最小化できるからです。
インフラ移行:さくらVPS → AWS EC2
EFSへのファイル移行
さくらVPS上に散在していたプロフィール画像等のファイルは、副業インフラエンジニアと相談しながらEFSへ移行しました。方針はシンプルで、まずすべてのファイルを移行し、リファクタリング後に不要と判断したディレクトリを確認・削除するという順序です。
移行初期に不要ファイルの精査まで行おうとすると、コードの読み込みと並行する作業量が膨大になります。「まず移す、後で整理する」という割り切りが現実的でした。
ALBによるパス別ルーティング
EC2移行後は、ALBを使って以下のような構成を取りました。
- ユーザー向け画面 → Laravelディレクトリ
- 管理画面 → 旧PHP5ディレクトリ
管理画面は後回しにするという意向があったため、パスによって向き先を切り替えることで新旧システムを並走させました。これにより、フロントエンドをLaravel化しながら管理画面はPHP5のまま安定稼働させるという柔軟な移行が可能になりました。
Laravel移植:画面単位で進める
移植の単位と順序
移植は画面単位で進めました。PHP5のノーフレームワーク構成ではViewにロジックが書かれているため、画面単位で読み込むことがそのまま機能単位の移植にもなります。
各画面のロジックをController/Viewに分離する際、業務ロジックは一旦Response層に寄せるという設計を取りました。
Response層という設計判断
ここで言うResponse層とは、ControllerのメソッドとResponseクラスが1対1になるクラス群です。Viewに書かれていたロジックをまずこのResponseクラスに書き出すことで、ViewとロジックをひとまずControllerの外に出しました。
この段階では「きれいなアーキテクチャを作る」ことより「Viewからロジックを剥がす」ことを優先しています。リファクタリングは後のフェーズで行う方針だったので、まず分離できていれば十分という判断です。
解読不能なロジックとの向き合い方
決済ロジックや報酬計算は、処理の仕様はわかるもののなぜそうなっているかの意図が読み取れないものが多数ありました。創業者はすでに不在で確認する手段もありません。
この場合の判断はシンプルです。
- 意図はわからないがロジックは読める → そのまま移植
- 移植後にビジネス側にテストを依頼してOKが出ればOK
一気にロジック改善まで行うのは期間とリスクが大きすぎます。「意図のわからないロジック」はすべてリファクタリング対象として積み残し、後のフェーズで対処しました。ビジネス側にテストを依頼してOKをもらうというプロセスを挟むことで、エンジニア単独の判断でリリースするリスクを回避できます。ビジネスリスク管理の観点からも、この判断は正しかったと思っています。今となってはAIのサポートがあればもう少し解読が楽になったかもしれませんが、当時はひたすら読んで移植するしかありませんでした。
Laravel完全移植後:EFS → S3、EC2 → ECS Fargate
S3移行はリファクタリング後に実施
EFSからS3への移行は、Laravelへの完全移植と安定稼働が確認できた後、さらにリファクタリングが一定完了してから実施しました。プロジェクトのかなり後半です。
この順序にした理由は明確で、ファイルアップロード処理がコード上に散在していたためです。先にリファクタリングでアップロードロジックを1箇所に集約してからS3へ切り替えることで、修正箇所を最小化できました。散在した状態のままS3へ切り替えると、修正漏れのリスクが高くなります。
Fargate移行
Fargate移行は以下の手順で実施しました。
- 開発環境でテスト実施
- EC2と並行してFargateを稼働
- 社内テスト要員(エンジニア・ビジネス両方)が直URLで動作確認
- ALBで向き先をFargateに切り替え
EC2と並走させながら確認できる環境を作ってから切り替えたため、比較的スムーズに移行できました。
移行後の構成としては、EC2と同等スペックのFargateを2台構成にすることで、スペックを維持しながら冗長性を確保しています。オートスケールも可能になり、インフラの拡張性という当初の課題もこれで解消されました。
本番切り替えのタイミング
ALBによるLaravelへの完全切り替えは夜間に実施しました。このサービスは深夜2時から朝5時の間はレッスン提供がなく、予約のみ受け付ける時間帯です。あらかじめ告知することで作業時間を確保し、大きなトラブルなく切り替えが完了しました。
まとめ
この記事では、インフラ移行からLaravel完全移植・Fargate移行までの実録を振り返りました。
ポイントを整理すると以下のとおりです。
- インフラを先行させ、ALBで新旧を並走させることで切り替えリスクを最小化できます
- 意図不明なロジックは一旦そのまま移植し、リファクタリングは後フェーズに積み残すのが現実解です
- ファイルアップロードロジックを1箇所に集約してからS3切り替えをすることで修正漏れを防げます
- 技術的な正解より現場のオペレーターを尊重した移植順序が、プロジェクト全体の成功に寄与しました
次回は移植完了後のテストコードによる挙動保証について記録します。
