こんにちは。テクノロジー本部アーキテクトグループの福留です。最近気になっているものは model-checking/kani です。
アーキテクトグループは、LIFULL のエンジニアの開発生産性を、エンジニアに寄り添いながら向上させていくことをミッションとして活動しています。 そこで今回は、昨年から今年にかけて行った LIFULL HOME'S のリリースフローの改善、通称「即日リリースプロジェクト」について紹介します。
このプロジェクトでは、 LIFULL HOME'S のリリース作業を完全自動化し、リリースにかかる時間を 1/5 に短縮しました。
その取り組みについて、順を追って説明します。
従来の LIFULL HOME'S のリリースフロー
LIFULL HOME'S はいくつかのマイクロサービスで成り立っています。
このマイクロサービスでの機能の公開、いわゆるリリースは「リリースチケット」と呼ばれる Jira チケットと GitHub の PullRequest によって管理されています。
リリースチケットは PullRequest ごとに作成される Jira チケットで、開発グループ長と、担当企画のリリース承認と、リリース状況の管理を行います。
また、LIFULL HOME'S のステージング環境を含めた環境は、テスト環境、プール環境、本番環境の 3 種類があります。
それぞれの環境は以下のような役割を持っています。
- テスト環境
- develop ブランチの内容が反映される
- テストデータによる動作確認が可能
- プール環境
- release ブランチの内容が反映される
- 個人情報等のセンシティブ情報をマスクした、本番環境相当のデータによる動作確認が可能
- 本番環境
- master ブランチの内容が反映される
- ユーザーに提供される本番環境
従来のリリースフローでは、これらを用いて以下の流れでリリースが行われていました。
- 1 日目
- (Jira) リリース承認を開発グループ長・企画担当者からもらう
- (GitHub) PullRequest を develop ブランチにマージし、テスト環境に反映
- (テスト環境) テスト環境で動作確認
- 2 日目
- (プール環境) 開発者がプール環境で動作確認
- 3 日目
- (本番環境) 開発者が本番環境で動作確認
以上をまとめると、従来は次の図のようなリリースフローでリリースが行われていました。
このフローの中では、「リリーサー」と呼ばれる人たちが、以下のような作業を行っていました。
- PullRequest とリリースチケットの突き合わせ
- develop ブランチを release ブランチにマージし、プール環境へ反映
- release ブランチを master ブランチにマージし、本番環境へ反映
- 反映された PullRequest に対応するリリースチケットのリリースステータスを「プール反映完了」「本番反映完了」などに変更
リリースフローの課題
このリリースフローには、以下のような課題がありました。
課題 1: リリーサーの負担が大きい
リリーサーの作業はすべて手作業で行われている上、上記のリリースフローで運用されているリポジトリは 5 つあります。ゆえに、リリーサーの確認作業はとても煩雑なものでした。
このリリーサーが手作業で行う作業は、月曜から木曜まで、1 日 4 時間ずつ、合計で 16 時間もかかっていました。
しかも、リリーサーはリリースフローと、リリースされるアプリケーションについて大まかな知識を持っている必要がありました。そのため、比較的社歴の長い、経験豊富なエンジニアがリリーサーを担当する傾向にありました。
つまり、 経験豊富なエンジニアの時間がリリーサー業務に、週 16 時間も使わなければならない という、もったいない事態が起こっていました。
課題 2: リリースまでの時間が長い
図の通り、開発者が変更を develop ブランチにマージしてからリリースされるまでには、約 3 日が必要です。
リリースまでのリードタイムは、最短で約 40 時間かかっていました。
本来なら新しい価値をどんどんユーザーに提供していきたいはずが、 価値提供のボトルネックがリリースフローにもある ことは明白でした。
即日リリースの目標
このような課題から、アーキテクトグループでは、以下の目標を立て、リリースフローの改善を行うことにしました。
- リリーサー業務を自動化し、リリーサーという存在を不要にすることで、エンジニアが開発に集中できる環境を作る
- リリースフローを効率化することで、develop マージ後 1 日以内でのリリースを可能にする
2 番目の目標から「即日リリースプロジェクト」と名付け、3 つのフェーズに分けて取り組むことにしました。
即日リリースの適用
Phase 1. リリーサーの確認業務自動化
最初に、リリーサーの作業で最も時間を取られていた確認業務を自動化することから始めました。
ところが、リリーサーはリリースチケットの上で、「リリース承認されていること」以外に何をチェックしているのか、具体的には分かっていませんでした。
というのも、リリーサーは部署をまたいで持ち回りで担当が決まっていたため、公式な引き継ぎ資料がなかったためです。
非公式な引き継ぎ資料はあったものの、あくまでリリーサーが所属する部署内での資料だったため、チェックしている内容はリリーサーによってまちまちになっていました。
たとえば、あるリリーサーは最低限承認されていることをチェックしているが、あるリリーサーは PullRequest の内容まで入念にチェックしているらしい、という状況のようでした。
そこで、リリーサーのチェックを一緒にやってみることで、実際のチェック内容を把握しつつ、標準となるチェック項目を作成しました。
具体的なチェック項目については割愛しますが、人間でなければ判断できないチェック項目はリリーサーやエンジニアとの合意の上で削減しました。そして、自動化しやすく、かつ守るべきところは守れるチェックリストに落とし込みました。
最終的にできたチェック項目について、手元で動かせる cli ツールを作成してリリーサーに使ってもらうことで、作業の負担を大幅に減らしました。
Phase 2. リリース作業の自動化
Phase 1 ではリリース前の確認作業を自動化しました。ここから各環境に反映していく作業、つまりリリース作業も自動化することで、リリーサーの存在を不要にできます。そこで、リリース作業を自動で行ってくれるアプリケーションの開発を計画しました。
リリース作業とは単に GitHub のマージボタンを押すだけかと思いきや、実はそうではありません。
LIFULL HOME'S を構成するアプリケーションは API 層・BFF 層・フロントエンド層に分かれており、それぞれに依存関係があります。
この依存関係を踏まえると、前段のアプリケーションがリリースされたことを確認してから、次のアプリケーションをリリースしなければなりません。
たとえばフロントエンドと BFF に同時に変更を行った場合、BFF の方が先にリリースされてしまうと、フロントエンドの参照部分が壊れてしまい、障害につながります。
つまりリリーサーは、「前段のアプリケーションのリリースが完了したこと」を確認してから、次の段のアプリケーション(リポジトリ)のマージボタンを押さなければなりません。
ところで LIFULL には、 KEEL という全社で横断的に利用しているアプリケーション実行基盤があります。KEEL のワークロード監視ダッシュボードからは、現在のアプリケーションの状態、具体的には Kubernetes の Pod の状態を確認できます。
KEEL については、ぜひ以下をお読みください。
KEEL チームに依頼し、Pod の状態として、現在デプロイされている Git のコミットハッシュを追加してもらいました。これで、リポジトリの master ブランチのコミットハッシュと Pod のコミットハッシュを比較できるようになりました。
リポジトリのコミットハッシュと Pod のコミットハッシュが同じになったのを見れば、アプリケーションがリリースされたかどうかを自動で判断できるようになりました。
また、リリースの進捗状況を Slack へ通知するようにしました。
通知内容は以下のようなものがあります。
- 現在どのアプリケーションをリリースしているのか
- GitHub の障害などによるマージの失敗
- カナリアリリースの失敗
これらの内容を、対処方法も含めて通知することで、リリースの進捗状況をほぼリアルタイムで把握できるようにしました。
同時に、このアプリケーションに、リリーサーが行っていたチェックを自動化するツールを組み込むことで、リリースのすべてを自動で行えるリリースシステムが完成することになりました。
Phase 3. リリースフローの高速化
リリーサー業務の自動化とは別に、リリースフローの高速化にも取り組みました。
従来のリリースフローをおさらいすると、次の図のようになっていました。
プール環境とは、本番環境のデータから個人情報をマスクしたデータを利用できる環境で、主に本番相当の環境としてテストを行うために利用されています。
この反映と確認のために 1 日かけることが、結果としてリリースまでのリードタイムを長くしていました。
そこで、プール環境にテスト環境と同じ develop ブランチを参照させることで、テスト環境とプール環境へ同じ日に反映を行い、リードタイムを短くすることを計画しました。
まずエンジニア全体にアイデアの共有を行い、そこで受け取った質問に対して回答や説明をしました。
そして、機能追加に責任を持つ企画・エンジニアの代表の方にプレゼンを行い、合意を得ることで、リリースフローの変更を行うことに決まりました。
最終的にできたリリースフローは以下のように、シンプルなものになりました。
- 1 日目
- (Jira) リリース承認を開発グループ長・企画担当者からもらう
- (GitHub) 開発者が PullRequest を develop ブランチにマージし、テスト環境とプール環境に反映
- (JIRA) リリースシステムがリリースチケットのステータスを変更
- 開発者がテスト環境とプール環境で動作確認
- 2 日目
- リリースシステムが develop ブランチを master ブランチにマージし、本番環境に反映
- (JIRA) リリースシステムがリリースチケットのステータスを変更
- 開発者が本番環境で動作確認
このリリースフローの変更に合わせて、以下のようなリリースのルールを設けました。
- (即日リリース) 当日 11 時までにテスト環境とプール環境で動作確認できていれば、その日のうちにリリース可能
- (即時リリース) プール環境での確認が必要なく、KEEL の機能で作成される Ephemeral Environment*1 で十分にテストできていれば、 直接 master ブランチにマージしてもよい
ルール 1 によって、従来のリリースフローでリリースされるまでに約 40 時間かかっていたものが、最短 8 時間、つまり約 5 倍速くリリースできるになりました。
また、ルール 2 に従えば、リリースまでのリードタイムはより短くなり、もはやリードタイムは存在しません。
これらの改善だけが原因ではないと思いますが、年間のリリース数は、即日リリース適用以前と比べて約 20 %増加しました。
まとめ
LIFULL HOME'S のリリースフローを改善することで、リリーサー業務を自動化し、リリーサーという存在を不要にできました。その結果、開発者が、開発業務により集中できるようになりました。
また、リリースフローを効率化したことで、リリースまでのリードタイムを大幅短縮し、価値提供が従来よりも速くなりました。
即日リリース PJ は、アーキテクトグループならではの「開発者に寄り添った開発生産性の向上」ができた、良い例だと思います。 今後も、エンジニアの生産性向上に向けて、さまざまな取り組みを行っていきます。
最後に、LIFULL ではともに成長していける仲間を募集しています。
12 月 2 日現在、アーキテクトグループでもメンバーを募集中です!よろしければこちらのページもご覧ください。
*1:Firebase のプレビュー環境のような、PullRequest に紐づいて作成されるテスト環境