どのようにPlatformチームの組織変更をしたか

Platform チームの@deeeeeeeetです.

Platform チームは2年前にMercariがMicroservicesの移行を始めたときに一緒に立ち上げられたチームです.Platform チームはMicroservicesを動かすための基盤や開発や運用のためのツールセットなど提供しています.立ち上げ時は自分を含めて2-3人で始まったチームですが2年が経ち10人を超えるチームにまで成長しました.

チームのメンバーが増えるほど1チームとして動くには限界がきており,またMicroservices化が進めば進むほどチームの負う責任範囲も広くなりCognitive load (認知負荷) も高くなっていました.これらの課題を解決するために組織変更を行い,Platform チームを複数の専門性に特化したチームに分割しました.

本記事ではチームのデザイン,チームが分離しても独立性を保ちつつも皆が同じ方向を向くために導入した仕組み,また組織変更の現状の評価(とその方法)などについて紹介します.

問題

今回の組織変更では大きく以下の2つ問題を解きました.

  • 1チームの抱えるCognitive loadの増加
  • Developer Productivityに関連するチーム間のMisalignment

Cognitive load

書籍Team Topologiesでも触れられているように,多くの組織においてPlatform的なチームというのは広範囲かつ多くの責任を負い,Cognitive loadは高くなりがちです.MercariのPlatform チームでも同様の問題が起こっていました.Platform チームはメインとなる基盤であるKuberentesやIstioの運用だけではなく,サービスチームが開発からテスト,デプロイ,運用までを自分たちで回すための各種ツールセットの提供も行っています.例えばデプロイのためにSpinnakerを提供したり,Microservicesのインフラの構築のためにTerraformを簡単に使える仕組みを準備したりしています.扱う範囲やコンポーネントは多岐に渡りCognitive loadはかなり高くなっていました.

象徴的だったのは昨年末にチームでオフサイトを行ったときです.オフサイトではチームの皆に課題になっていることを挙げてもらいました.以下がそのときに挙がった問題です.

f:id:deeeet:20200714094623j:plain

これは1チームが抱えられる問題の量を超えているし,自分はこの後の議論をちゃんと進めることもできませんでした.

チームのCognitive loadの高さは様々な影響を与えてしまいます.まず1チームとしてやるべきことの優先度づけが難しくなります.優先度づけに失敗すると四半期ごとにやることが大きく変わってしまいコンテキストスイッチの負荷が高くなってしまいます.また各メンバーは改善したいと思っていることを多く持っているのにもかかわらず優先度によってそれらに取り組めないこともあり,モチベーションにも影響を与えてしまいます.次に個々のコンポーネントの関わりが薄くなってしまいます.広い範囲を見る必要があるために,個別のコンポーネントを深く継続的に改善するのが難しくなってしまいます.一度作ってそのまま放置されていたコンポーネントもいくつかありました.この深さを追求できないことはメンバーの技術の熟達にも影響を与えてしまいます.

Misalignment

PlatformチームのメインのミッションはMicroservicesの開発を行うサービスチームのDeveloper Productivityを改善することです.このDeveloper productivityの改善を担っているのはPlatform チームだけではありません.例えばMerpay SREの一部のメンバーもこれに取り組んでいるし,Merpay Architectも多くを担っています.

Platform チームが提供する基盤上ではMercariとMerpayの両方のMicroservicesが動いています.しかしPlatform チームはMercariに所属しています.そしてMerpay SREとArchitectはMerpayに所属しています.小さな違いに見えるかもしれませんがこれだけで問題が起こっていました.

まずオフィスのフロアが変わってしまいます.するとコミュニケーションのコストが高くなりコミュニケーションの頻度は減ってしまいます.また組織によってやるべきことの優先度が変わってしまいます.Platformとしてはどちらかの組織に偏った優先度で動いているつもりはありませんでしたが,外から見るとMercari優先で動いているように見えてしまっていました.これらによって例えばPlatform チームがMerpay SREのやりたいことをブロックしてしまったり,方向性に違いが出てしまったり,同じ課題を別の方法で解き始めたりというMisalignmentの問題が起こっていました.

組織変更

上述した問題を解決するために組織変更を行いました.具体的には大きく2つことをしました

  • Platformチームを専門性に特化した複数のチームに分割すること
  • MercariとMerpayの両方からメンバーをアサインし組織横断のチームにすること

Design docを書く

組織やチームの変更に関しては人事に関わる情報でもあるため,広く議論されることは多くないと思います.しかし自分としてはチームを分ける,変えることは個人の情報を排して,ある程度デザインできるものだとずっと思ってきました.どのような問題を解くのか?どのようにそれを解くのか?どのように評価するのか?は明確にデザインとして説明でき,かつそれが妥当であるかを広く意見を得るべきだと思っていました.特に組織構造とアーキテクチャは密接に関わるものであり,実際に開発をしているメンバーやアーキテクトからの意見は必須だと思います.

MercariとMerpayでは新しくMicroservicesを作るときや既存のコンポーネントに大きな変更を加える場合にDesign docを書く文化があります.今回の組織変更でも同様にDesign docを書き,関連するメンバーから広くフィードバックをもらいつつ体制を固めていくということをしました(ちなみにこの記事はそのDesing docの内容をほぼそのまま載せています).

組織変更はたとえ小さな変更であってもチームのProductivityに大きな影響を与えてしまいます.一度変更を加えられたチームが再びゲル化し自律的にInnovativeな状態になるには時間がかかるため,かなり大きなコストになります.そのため「長期的に安定した」チームを作ることが大切です.デザインを行なう際は半年で変わってしまうのものではなく1-3年は使えるものを意識しました.

デザイン

チーム分割は以下の3つの戦略で行いました.

  • Microservicesの開発のライフサイクルの各ステージ毎にチームを配置する
  • PlatformのためのPlatformを配置する
  • Platform チームと開発チームのAccessibilityを確保するチームを配置する

SDLC

上述したようにPlatform チームはMicroservicesの開発から運用までの全てのソフトウェア開発ライフサイクル(Software Development Life Cycle = SDLC)をサポートしています.具体的には大きく「Build」「Test」「Deploy」「Operate」の4つが挙げられます.これらの改善にはそれぞれ異なる専門の知識が必要となるため,以下のようにそれぞれのフェーズごとにチームを配置することにしました.

f:id:deeeet:20200714093953p:plain

例えば「Build」フェーズを支えるチームとしてRuntimeチームを配置します.現在このフェーズのためにPlatform チームが提供しているコンポーネントとしてはGoでMicroservicesを書き始めるためのテンプレートプロジェクトがあります.しかしそれ以上は提供できていません.将来的にはこのチームにはGoやそれ以外の言語のためのフレームワークやProtocol bufferと連携したRPCフレームワークの提供などを行ってもらいたいと思っています.

他にも「Deploy」フェーズを支えるチームとしてDeliveryチームを配置します.DeliveryチームはSpinnakerを中心としたDelivery基盤を整備したり,Testing in Production, the safe wayで述べられているようなPost-production testingの仕組みを整えることに責任を持ちます.

Platform for platform

開発チームから見るとPlatformチームはMicroservicesの開発と運用に必要な基礎となる共通のインフラを提供しているチームに見えていると思います.サービス開発に共通で必要となるCross-cutting concernのための解法を提供するチームとも言えます.この構造はPlatformチーム内部でも利用でき,フラクタル的になります.上述したSDLCごとに配置したPlatform内のチームにもCross-cutting concernはあります.例えばCloud resourceのProvisioningはどのチームにも必要になります.このようなPlatformのためのPlatformを提供するチームとして「Cloud Infra」チームと「Network」チームを配置することにしました.

f:id:deeeet:20200714094012p:plain

Accessibility

たとえチームが複数に分離したとしてもそれを使う側=開発チームからは1つのPlatformとして見えるべきだと考えました.各チームが異なるコンポーネントを管理していたとしてもそれぞれが適切に統合されていることで,SDLC全体を通して一貫したUI/UXを提供することは非常に重要です.これはGCPやAWSといったCloud providerが良い例だと思います.自分たちと比べたら比較にならないくらい多くのチームやコンポーネントで構成されているはずですが,利用者から見たときにそのAPIやドキュメント,サポートシステムなどは一貫したものが提供されています.

この課題を解決するために配置したのが「Developer Experience (DX) チーム」です.DXは各チーム提供するAPIやツールのUXに大きな齟齬がないかを注視しつつ,共通となるドキュメントやサポートシステムを管理します.また開発チームとの窓口としても機能することを期待しています.

f:id:deeeet:20200714094052p:plain

移行戦略

長期的に上述した7チームに別れていくことが理想ですが,現在のチームの人数を考えたときに,いきなりそのような分離をすることは現実的ではありません.段階的な移行を行なうために,以下のように関連性の高いいくつかのチームをまとめたチームを作ることにしました.例えば「Test」を担うSETIチームと「Deploy」を担うDeliveryチームをマージしてCI/CDチームを構成します.

f:id:deeeet:20200714094449p:plain

いろいろなところで言われているように1チームの理想的な人数は5-8人とされています.これはコミュニケーションのコストやOn-callの体制などが根拠にされています (参考: How Twilio scaled its engineering structure, How to build a startup engineering team, Dunbar’s number).組織の拡大やチームの採用状況によってこの人数を超えた場合にオリジナルのデザインへと段階的に分離していく予定です.関連するチームで構成されているために,分離するときのコストはそこまで大きくはないと感じています.

また組織間での「Misalignment」の問題を解決するために,新しいチームのアサインはMerpayとMercari両方のから選出することにしました.この新しいチームは2つの組織にまたがるVirtualなチームとして定義しています.アサインにあたっては本人が希望したときには所属とレポートラインを継続することにしています.例えば所属とレポートラインはMerpay SREのままでCI/CDチームに参加しているメンバーもいます.

f:id:deeeet:20200714094501p:plain

働き方

複数チームに分離したとしてもPlatformとして各チームが同じ方向を見て動けるように働き方のデザインも同時に行いました.デザインの際の原則としてはSpotifyのSquadモデルを参考にし「自律的に動けるようにするが部分最適は避ける (be autonomous but don’t suboptimize)」を意識しました.

以下はこれまでのPlatformチームのリリースの構造です.

f:id:deeeet:20200714094852p:plain

チームとしてのMissionがあり,Missionに基づいた長期的なRoadmapがあり,RoadmapをもとにReleaseを決めてきました.Releaseの決め方や回し方はBasecampの6 week release cycleを参考にしており,詳細はHow We Structure Our Work At Mercari Microservices Platform Teamで紹介しています.

以下は新しいチーム体制でのリリースの構造です.

f:id:deeeet:20200714094929p:plain

基本的には以前と大きく変えていません.各チームはそれぞれMission,Roadmap,そしてReleaseを決めます.新しく導入したのは「2 Year goal」と「Bets」です.これらは各チームがバラバラの方向に向かってしまうのではなくPlatform全体として同じ方向へと向かうために導入しています.

f:id:deeeet:20200714095014p:plain

まず「2 year goal」は今後2年でPlatformとして達成したい野心的な大きな目標を定めています.例えばMercari Microservices PlatformにおけるKubernetes Cluster移行で述べたように「Ephemeral Cluster」を実現することなどがここに挙げられています.またこれらはMercariとMerpayの長期的なビジネスのゴールとアラインすることを意識しています.次に「Bets」はその「2 year goal」を達成するために複数チームが協業するプロジェクトです.

各チームは「2 year goal」をもとにチームの「Roadmap」を決めます.「Release」を決める際には「Bets」を考慮し,自分たちに関連するものであればそれをReleaseのターゲットとして入れるし,関係なければ本来自分たちがやろうとおもっていたことを「Roadmap」から選択します.これらの仕組みにより「自律」と「アラインメント」のバランスを保つことを目指しています.

サイロ化問題に対する取り組み

(2020年7月20日追記)

サイロ化問題に関する懸念についてコメントをもらったのでそれについての取り組みについて紹介します.

サイロ化とは各チームが孤立してコラボレーションやコミュニケーションが発生しなくなることを指します.サイロ化によっては開発プロセスが効率的に回らなくなってしまうとことがあり組織デザインにおいては重要な課題の1つです.このサイロ化と組織拡大によるチームの分割はトレードオフの関係にあります.サイロ化を気にしてチームの分割をしないと上述した課題が発生することになります.そのため,いかにチームを分割するかはとても重要です(なので今回多くの時間をデザインにかけました).

最も避けるべき分割の仕方は,ソフトウェアの開発のライフサイクル(SLDC)によってチームを分割することです.つまり開発のみをする開発チーム,テストのみをするQAチーム,運用のみを行なうインフラチームという分け方です.これでサイロ化する大きな問題はリリースのスピードを悪化させてしまうことです.開発が終わったらQAにタスクを依頼し,終わったらインフラチームに依頼しというコミュニケーションが毎回発生してしまうため,最終的なリリースに時間がかかってしまいます.また各フェーズのフィードバック・ループが回らなくなってしまうことも大きな問題です.例えばソフトウェアのバグによって本番で障害が発生しても,それはインフラチームで解決されるだけで最終的に開発チームにフィードバックされることは(断絶が大きいほど)少なく次回の開発にその失敗が活かされることがなくなります.Microservicesの組織に関してFunctionalチームではなく,Cross functionalなチームを構成してEnd-to-endで責任をもつようにしましょうとよく言われるのはこのような理由からです.

今回のデザインと似ているので混乱するかもしれないですが,今回PlatformチームがSLDCのフェーズでチームを分割しているのは,そのフェーズをサポートすることを責任範囲として限定するためです.Microservicesにおいては開発チームはサービス開発の全フェーズに責任を持っています.Platformチームがやるのはそのためのツールセットを提供することです.例えばSETIチームはSLDCにおける「Test」フェーズに責任を持っていますが,Microservicesのテストをすべて担うことはしません.SETIチームがするのはあくまでMicroservicesの開発者が自分たちでテストを行なうためのツールや環境を提供することです.そして「SETIチームのSLDC」は同じくSETIチームで閉じるようになっています.

とは言え各チーム間が互いにやっていることが全くわからなくなるのは大きな問題です.このような問題を解決するためにリリースごと(6週間ごと)にPlatform Allhandsを実施することにしました.All handsではPlatformの各チームのTLがそのリリースでやったことを紹介したり(開発者向けにリリースノートを書いているのでそれをもとに共有を行います),メンバーが新しい機能に関してデモを行ったり,もしそのリリースに向けて新しいテクノロジーを導入したらそれに関するテックトークをしたり,ということをしています.

これによりチームが分割されても互いの状況を知り,互いに質問を投げ合うことでコミュニケーションの機会にもなります.また長期的にはメンバーのチーム移動も可能にしていきたので,これによって移動も容易になることを期待しています.

評価

この新しいチーム体制で4月から実際に動き始めています.デザインはしましたがちゃんと動けているか?は継続的に評価をして調整をしていく必要があります.この評価の方法として,各チームメンバーに対してサーベイを行いました.以下はサーベイの結果です.

まず以下は総評です.組織変更全体に関しての評価をしてもらいました.

f:id:deeeet:20200714095116p:plain

これより組織変更に関しては全員がポジティブな意見を持っていることがわかります.

次に以下は詳細な評価です.各項目に対して1-5点(5が最も良い)でスコアをつけてもらっています.

f:id:deeeet:20200714095139p:plain

以下は各項目の質問内容です.

  • Release: 他のチームと最小限の調整と依存で機能のリリースができているか?
  • Focus: 以前と比較して特定の領域にフォーカスできているか?
  • Mission: 自分のチームのミッションは明確か? 皆がそれを意識できているか?
  • Roadmap: 自分のチームのロードマップは明確か?
  • Teamwork: 自分のチームはチームとして動けているか? 互いに助け合っているか?
  • Influencing work: リリースの議論に参加できているか?
  • Preference: やりたいことができているか?

問題点で挙げたように今回の組織変更で最も解きたかったのは「Cognitive load」の問題です.「Focus」の項目を見ると多くのメンバーが以前と比べて各領域にフォーカスできるようになったと答えています.また「Release」の項目の評価もよく各チームは独立して動けていることがわかります.これより解きたかった課題は解決できていると言えると思います.

課題があるのは「Mission」と「Roadmap」です.これらはできてないことをわかった上で聞いています.まさに現在各チームのTech Leadは年間のロードマップを作っているところなので,次回のサーベイではこれは改善できているはずです.

全体として最初のサーベイとしては良い評価だったと感じています(そもそも評価が悪かったらすべてやめてRollbackするつもりでした).今後もこのサーベイは継続して行い,結果をもとにチームの境界の調整などを行っていく予定です.

今後の展望

今後の課題にMercari SREチームとPlatformチームの協業があります.現状の展望として大きく2つの方向性があります.1つ目は以下の図のようにEmbeded SREとしてCriticalなMicroservicesの開発チームに参加してサービスのReliabilityの改善を担っていく方向です.そして2つ目はSREの中でもNetworkなどよりインフラ的な役割を持っているメンバーはPlatformチームに入りMicrosevicesを含めたインフラの改善を行なうという方向性です.これらも段階的に進めています.

f:id:deeeet:20200714191135p:plain

まとめ

本記事ではPlatformチームの組織をどのように拡大したかについてそのデザインから評価までを紹介しました.同様の組織変更を行おうと考えている方の参考になればと思います.

参考文献

自分としては組織については専門外であり多くを学ぶ必要がありました.以下は今回参考にした文献の一部です.特にUberやStripeの基盤チームのEMをやってきたWill Larson氏からは多くを学びました.