SODA Engineering Blog
🦄

エンジニアだけのスクラムチームでリファクタリングプロジェクトを回してみたらこうなった

2024/12/03に公開

\スニダンを開発しているSODA inc.の Advent Calendar 2024 3日目の記事です!!!/

はじめに

エンジニアだけのスクラムチームでリファクタリング(以下システム改善)のプロジェクトを行ってみた。どのように進めたかを起承転結の4つのフェーズで記録する。同様のプロジェクトで再現性ある進め方ができることを期待する。

プロジェクトが立ち上がるまでの話

ある月、多数の変更障害が起こってしまった。
これは社内で大きく問題視され、急遽システム改善プロジェクトを立ち上げることとなった。
何をすれば変更障害が頻発する状態を脱却できるか、エンジニア全員でポストモーテムを行い、5つの施策(以降エピック)が合議的にまとまっていった。
これらのエピックをパッケージングしたプロジェクトは、筆者の所属チームにアサインされた。
以降は、チームで、このプロジェクトをどのように進めていったかを記述する。

【起】オーナー, ゴール, KPI, 会議体を設定する

さて、プロジェクトは立ち上がったものの、この状態からどう動いていくか?
施策もふわっとしているし、このプロジェクトにはオーナーがおらず、チームにはエンジニアしかいない。
立ち上げ期に各メンバーが頭を捻って下記のようなことを行なっていった。

チームメンバー(エンジニア)の中から擬似的にオーナーを設定する

  • チームにはプロダクトオーナーに当たるメンバーがいなかった。オーナーを誰か一人立てた方が良いと考えた。そこでチームメンバー(エンジニア)の中から擬似的にオーナーを設定した
  • エピックは5種類あるため、エピックごとにオーナーを設定した
  • オーナーは後述する完了の定義や進捗管理の責任を持つ
  • これにより責任を一箇所にまとめることができたほか、オーナーとなったメンバーは主体的にエピックの課題解決にあたることができた

エピックの完了の定義とKPIとその目標を設定する

  • エピックの完了の定義および、KPIとその目標をそれぞれ設定する
  • 完了の定義は特定の成果物を開発してリリースするといったようなコントーラブルで明確なものにする
  • KPIはそれよって得られるアウトカムに当たるものを設定する。今回のプロジェクトでは変更障害率とMTTR(平均復旧時間)としている。
  • このように、アウトプットとそれに対するアウトカムは明確に分ける。完了の定義はアウトプットベースで設定する方が良かった。アウトカムベースとするとスケジュールが曖昧になってしまう。

スプリントレビュー(のようなもの)を設定する

  • 週一回、スプリントレビューのような形で、チーム外への進捗報告・議論の場を設ける
  • 今回のプロジェクトはCTOからの委託事業と位置付けて、CTOを招待した。また、いくつかのエピックはSREが強く関わることからSREエンジニアも招待した
  • 初期の議論では、完了の定義やKPIやスケジュールに関する議論が中
  • ただし週一・30分のMTGでは、十分に相互理解が及ばず、ディスコミュニケーションが生じていた側面もあった。
  • ただしこれは責任分解点が曖昧になりがちだった。プロジェクトの性質によっては、どこまでの責任を誰が持つかを明確にする方がベターかもしれない。

以上が立ち上げ期にやったことである。それまでスクラム開発を行っていたので、できるだけスクラムのフォーマットに乗せるようにしてみた。スクラムの掲げる「経験主義」と「リーン思考」はこのようなシステム改善プロジェクトにおいても有効であると考えたからである。

【承】進捗とKPIを監視し議論しながら期待値を調整する

立ち上げ期が終わると、今度はこのプロジェクトは果たして順調に進んでいるのか?が気になってくる。進捗やKPIを確認しながら、少しずつ軌道修正する。

進捗をモニタリングする

  • 全体スケジュールを見積もる。6ヶ月の期間と、複数のエピックの中でどれをできるかを調整していく。全体スケジュールは一番最初に作成するのではなく、数スプリント回しながら徐々に作成していった。立ち上げ期においては1スプリントごとに状況や認識が大きく変わってくるためである。
  • エピックを少し細かいプロダクトバックログアイテムの単位に分割して、各アイテムごとの大まかな期限を設定した。一方で、さらに細かいサブタスク単位で振っていたストーリーポイントは形骸化した。普段の機能開発と比べて慣れない業務や不確かさを多分に含んでおり、見積もりが難しかったためである。要するに、荒い単位で見積もりを行った。
  • これらを行ってプロジェクトの進捗率や、予定通りに進捗が出ているかをモニタリングした。

KPIをモニタリングする

  • 週単位でKPI(変更障害率、MTTR)の推移を計測してみた
  • 当初はできていなかった。だが、これは早めにやるべきであった。眺めることで議論が生まれる面があった。
  • しかしこれらのKPIは週単位で綺麗に推移するようなものではなかったため、もう少しコントローラブルなサブKPIのようなものを適宜作って観測したりした。

モニタリング指標を基に議論する

  • モニタリングダッシュボードを眺めつつレトロスペクティブやスプリントレビューで随時議論を行った。
  • いくつかのエピックは進捗に不確かさがあり、テコ入れする場面があった。
    • 例えば、CI/CDの時間短縮のエピックにおいては、個別の施策に対してどういったアウトプット(=時間短縮)が出るのかが不透明であった。
    • アプリのE2Eテストの動作が想像以上に不安定で、シナリオのリファクタリングを行うなどで安定化させる追加作業が発生した。
    • v0脱却は当初全てのAPIを対象としていたが、期間中にやりきれる量では全然ないことがわかった。そこで、優先度をつけることにした。
  • 議論と開発のメリハリが重要であった。スプリントの途中はスプリントゴールの達成に集中する、スクラムイベントで議論をするといった按分が良かった。この2つを混ぜてスプリント中に「そもそも...」のような話をしだすとスイッチングコストが大きくなり、どちらも中途半端になりがちであった。アウトプットを出す責務と、アウトカムを出す責務の両方を担っていくのは結構難しいことがわかった(通常のスクラムではこの責務がPOとDEVに分かれている)

【転】プロジェクトの根本に関わる大きな議論が発生する

プロジェクト開始から時間が経過し、エピックのゴールが見えてきて、メンバーの解像度が上がってきたことで、プロジェクトの根本に関わる大きな議論が出てくるようになった。

設定したKPIの達成の困難

  • 「CI/CDの実行時間の削減」というエピックについて、サブKPIとして理想の実行時間(10分)を設定したものの、その数値に持っていくことはプロジェクトの期間中では実現困難であることがわかった。
  • そこで、中長期的に解決できる策を考えて、将来の開発のテーブルに乗せておくこととした。例えば詳細は省くが、アーキテクチャを適切にリプレイスすることができれば実行時間の削減が実現できる見込みであることを示すなど。

開発組織の関心事の変化

  • システム改善の当初の目的は変更障害率やMTTRの改善であった。ただ途中から開発組織の課題がそれらから生産性やエンゲージメントにシフトしていった。
  • 実際、プロジェクトの途中から変更障害率は低下していた。それがこのプロジェクトによる影響かは切り分けが難しいが、事実として変更障害が頻発する前の状態に戻っていた。
  • そこで、システム改善プロジェクトの位置付け自体を拡張した。変更障害対策に加えて、開発生産性向上のための負債脱却を考えるようになった。具体的には、同じ処理が分散して書かれているところの共通化を推進するなどをした。

【結】プロジェクトを検証する、将来の展望を考える、次の技術戦略に繋げる

プロジェクトが終わるに当たって、プロジェクトの成果を検証する。またそれだけではなく、今後の技術戦略に繋げていく。

プロジェクトを検証する

  • 設定したKPIが最終的にどうなったかを検証する。
    • 今回の例で言えば変更障害率は低下した。このプロジェクトの元々の目的は果たされた。
  • また、KPI以外に定性的なアウトカムがないかも掘り下げてみる。
    • 今回の例で言えばCI/CD時間の短縮は現場のエンジニアに実感された。これについては定性的な物だけではなく、実際にサブKPIに設定したデプロイ回数は少し増えた
    • また重要な実感として、各々が自分たちの運用するシステムのあり方を主体的に考えるようになりチームとして成長したように感じるということがあった。これはエンジニアのオーナー制を設けていたことや完了の定義が明確になかったことと無関係ではなさそう。与えられた背景や仮説に固執せず、発展的な議論が色々と出てプロジェクトの進め方を訂正していくといった動きも度々見られた。こういった経験は重要で、開発組織内に広めていきたいと感じた

次の技術戦略に繋げる

  • 自分たちのプロジェクトは終了するが、エンジニア組織として次なる技術戦略を立てていきたいというモチベーションがあったため、エンジニア主導のプロジェクトを体験した身としてフィードバックする。それにあたっては前節の「プロジェクトの検証」を深く掘り下げることが役にたつ。
  • 今回でいえば、心残りとして「そもそも変更障害が起こる前になんとかできなかったのか?」という点が挙げられる。今回のプロジェクトは変更障害が発生したことをきっかけにトップダウンで生まれたものだったが、現場のメンバーでシステム改善を再現性のあるかたちで進めるための仕組み作りの必要性を感じた。それを来年以降の技術戦略の議論のテーブルに挙げている。現在も議論中であり、少し先に何らかの結論が出るものと思われる

おわりに

この記事ではリファクタリングプロジェクトの顛末を起承転結という形で時系列順にまとめてみた。ポイントの一つとしては、プロジェクトが進むにつれて当初想定できていなかった方向へ議論が発展していき、進行中のプロジェクトの軌道修正を行ったり、将来の技術戦略にフィードバックしていったという点である。そういった不確かさを抱えるプロジェクトを主導するにあたっては、決まったプロダクトを開発するのとは思考や行動のパターンが大きく異なってくる。この記事ではそういったプロジェクトの進め方を汎用的に書いたつもりなので、参考になれば幸いである。

補足資料:やったこと

  • CUJの設定
    • 重要なユーザージャーニーを決定する。そこに対して後続のエピックを集中して行う。
    • 障害の位置付けを定義するSRE的なエピック
  • SLOの設定
    • CUJに対してSLOを設定する。下回ったらアラートを鳴らす
    • 障害の位置付けを定義するSRE的なエピック
  • E2Eテストの実装
    • 障害を分析したところアプリとAPIの接合面で問題が起こることが多かったため、CUJに対してE2Eテストを実装する。開発環境で定期実行させている。
  • CI/CDの高速化
    • 開発環境での動作確認を怠った結果障害を起こすことが散見された。その原因の一つに開発環境へのデプロイに時間がかかりすぎるということが指摘されたため、デプロイの高速化を図る。
  • 古いアーキテクチャのままになっているAPIのリプレイス
    • 古くからあるAPIはファットコントローラで実装されて可読性が低い、複雑度が高い、テストがしにくいといった問題を抱えているので、これを現在策定したアーキテクチャにリプレイスする
SODA Engineering Blog
SODA Engineering Blog

Discussion