技術的負債の現場視点のアクション

原トリ氏(以下、原):では、ここからは技術的負債の返済inアクションという感じで、まずは現場視点での返済の進め方について、ちょっと見ていきましょう。現場視点の整理が済んだら、次は意思決定層の視点です。

まず一般的に、技術的負債の返済の提案や実行は、現場の立場から行われることが多いです。いわゆるボトムアップと呼ばれるものです。日々開発をして、運用している人たちです。理由は明確で、その技術的負債によって生産性低下の悪影響を直接的にモロに受ける立場にあるのが、彼ら彼女らだからです。

ただ、もちろんトップダウンによる技術的負債の返済例もあります。トップダウンの例としては、僕が所属しているAWSのグループ企業であるAmazon.com、オンラインショッピングサイトです。AmazonのCEOであるジェフ・ベゾスが出したと言われるAPI Mandateは、トップダウンの例として有名だと思います。

API Mandate とは何かというのをざっくりまとめると、ほかのチームのデータを直参照することを禁止します。すべてのサービスはHTTPで呼べるAPIを相互に公開して、API経由でデータのやり取りをしなさい。さもなくばクビです、みたいな。これをトップダウンで命じたものです。

Amazon.comという巨大なオンラインショッピングサイトを、サービスの成長速度に合わせて開発運用、組織を成長させていくためには、トップダウンの意思決定も必要だったんだろうと個人的には予想しています。

ボトムアップでの技術的負債の返済

話を戻して、ボトムアップでの技術的負債の返済の話です。あなたはシステムにもビジネスにも真摯な開発者なので、こんなことをチームやステークホルダーに進言します。「機能開発を1回止めて、技術的負債の返済に取り組みましょう」「このまま放置しておくと今に自分たちの首を絞めることになります。やりましょう」と。

では、具体的に提案してみましょう。どう提案しましょうか? ちょっとデフォルメが過ぎるかもしれませんが、こういうのをよく聞きませんか? 「フルスクラッチで大勝利です!」。

違いますよね。こんな荒い提案を、「おぉ、いいね。じゃあさっそく今日からやってみようか!」なんて受け入れるステークホルダーは、おそらくいないでしょう。

提案している本人と受け入れる側に強い信頼関係があれば、もしかしたらこの提案で通るかもしれませんが、よっぽどのことがなければ、こんな提案は通りません。あるいは、フルスクラッチでやると言っている人がタダ働きするなら受け入れるかもしれませんが、そんなことはありません。

いくら現場で一番システムに触れている時間が長く、システムのことを理解していたとしても、いきなりフルスクラッチだのなんだのと文脈もなく言われても、受け入れることは非常に難しいわけです。理解できないですから。

この突拍子もない提案には、もともとなんらかの裏づけが脳内にあったはずです。例えば、本番環境での障害が多く、それに時間を取られて開発時間が確保できないとか。やたらとバグがよく出るコードがあるとか、テストが書かれていないモジュールがチョイチョイあるとか。

こういった目の前に見えている課題が背景となって、先ほどの突拍子もない提案につながっているはずなのです。理解されるボトムアップの提案にするためには、この背景の部分をもっと掘り下げる必要があります。

背景となる課題を掘り下げる

では掘り下げてみましょう。ここでは仮に、バグに起因して本番環境で障害が発生したり、ダウンタイムが生まれている事実があったとしましょう。これを掘り下げていきます。

まず当然ですが、本番環境で障害が発生すると、多くの場合その対応、障害に対しての対応がトッププライオリティとなるでしょう。そうすると、そこに時間を取られます。人間の数と時間は有限なので、障害対応に時間を取られることは、本来やりたかったはずの新機能開発や、クリティカルなバグのフィックスに割く時間がなくなってきます。

多くの場合、こういった開発ができないこと、バグが直せないことは、その運用しているサービス、プロダクトの競争力の低下を招きます。それから、競争力だけではなく、ダウンタイムの発生によって生まれる逸失利益、ユーザーの離脱。こういったところも見逃せない点になるはずです。

どうして本番環境で障害が多いかを、今度はシステムの側面から見てみて、ここでは仮にデプロイ1回あたりの変更が大きく、テストしきれていないかと仮定したとしましょう。

「どうしてデプロイ1回あたりの変更が大きくなるの?」というと、デプロイによって新たなバグの混入や、それに伴う障害の発生が怖い。それによって、デプロイの頻度をそもそも減らしたくなる。デプロイの頻度を減らすことは、1回のデプロイに入ってくる差分が大きくなるので、グルグルと悪循環になる。

デプロイの数を減らしたいのは、バグや障害発生だけが理由ではないかもしれません。例えば、「上長承認を紙で得たうえで、デプロイはスキルフルなエンジニアが手作業で行うので、3日前までに依頼をお願いします」のようなところにあるかもしれません。

そもそもバグを早期に発見できていない理由には、コードレビューが機能していないこともあるかもしれません。ほかにもいろいろ要因はあるでしょう。

意思決定層の視点と現場の課題を提案でつながなければいけない

(スライドを見ながら)この図において、仮に今あなたが現場のエンジニアだとすると、あなたの関心は青い部分にあります。このへんを改善すれば、すべてがうまく回るはずなので、提案の内容は当然これらに準じたものになるわけです。

しかし、先ほどちょっと出てきた意思決定層や経営層の関心は、多くの場合、残念ながらちょっと遠く離れた緑の部分にあるはずです。自分たちのプロダクトの競争力が足りないとか、ダウンタイムによる逸失利益、ユーザー離脱。このへんが、意思決定層の関心であることが多いでしょう。

つまり、あなたがボトムアップの提案でやるべきことは、真ん中の紫の部分にあるバグ起因の本番環境障害やダウンタイム、これがステークホルダーの共通認識です。それと赤の部分の新機能開発やバグフィックスが遅れているという、目に見える生産性の低下。これら2つ、共通認識と目に見える生産性の低下を鍵として、意思決定層の関心とあなたの関心をうまくつなぐことが必要です。

意思決定層の視点と課題をつなぐためのポイント

ではこれらをどうつなぐかがポイントになってきます。技術的負債の返済コストを、例にあがってきたような各ステークホルダー間で合意していくためには、経験上、ここに今からあげていくような内容が少なくともすべてそろっているかが非常に重要です。

まず、そもそも返済すべき技術的負債が何なのか。「20年もののコードがクソだよ」とTwitterにダラダラ書くような、そういう話ではなく、今我々が返済すべき技術的負債は何なのか。これを明示して、そしてそれをどうして返済する必要があるのかがわかるようになっていなければいけません。当たり前ですね。

先にもあげたとおり、システムにおける技術的負債と認定され得るものは、常に複数、なんらかのかたちで存在しています。そのため、ステークホルダーの間で、どの負債について話しているのか、共通認識をもてるようになる必要があります。

その数ある負債の中で、どうしてこの負債の返済の優先順位が高いのか説明を求められることも、きっとあると思います。さらにボトムアップの提案に必要となるのは、どう返済するか。やっつける方法です。

この負債をやっつけるためには、どんな方法を取るのが最善か。負債をやっつけたと言える状態になるまでに、期間や人員、あるいはお金がかかることもあるかもしれません。これらも、可能な範囲で見積もることが求められることも多いでしょう。

最後、絶対に忘れてはいけない、最も重要とも言える項目です。今あげた負債を返済することで、効果が出ていることをどうやって証明するかです。生産性への悪影響を解消できたと説明できるメトリクスを、何に設定するかという点です。

例えば、モノリスをマイクロサービスにしたいという提案を、社内でしようとしたとします。マイクロサービスにする理由は、デプロイの回数をもっと増やしたい。

今あまりデプロイができていないのはシステムがモノリスで、デプロイ前にいろいろなチームでやりとりをしないとできないから、きっと遅いんだと。マイクロサービス化すれば、きっともっとデリバリーがいっぱいできるようになると提案したとします。

この場合において、設定にふさわしいメトリクスは何でしょうか? いろいろなものが考えられますが、ここでは仮に1週間のデプロイの回数としましょう。もしプロトタイピング的に、あるモノリスの一部分をマイクロサービスに切り出してやってみたときに、デプロイの回数が増えていなかったら、そもそもマイクロサービスをやること自体が必要ないという説明になるわけです。

そのため、どんな負債を返そうとしているのか。そしてその負債が返せている、返せたことによって効果が出ている、生産性が改善されていることを説明できるメトリクスの設定が、技術的負債の返済においては非常に重要です。

ではそんな例を少し、先ほどの意思決定層の関心などが書いてあった図に寄せるかたちで、ちょっと例示していきます。

まず、返済すべき負債とその影響を特定しましょう。ここでは「デプロイ1回あたりの変更が大きいので、それによって本番環境で障害が起きたときに、原因の特定にすごく時間がかかっている」というのが負債としてあったとしましょう。

ではどうしてこれを解消するのかと言うと、障害の原因特定や、障害対応に時間が取られることで機能開発時間が削られてしまい、本来出したかった機能リリースができていない。遅れている。それから、サービスを提供できない時間、ダウンタイムが毎月何時間も発生している。

デプロイ1回あたりの変更が大きいことで、本番環境で障害の原因特定が長時間化していることを解決すれば、ここに挙げている「機能開発できていない」「ダウンタイムが何時間も発生している」といった、プロダクトにとって最も懸案な事項の解消につながるはずだと考えられるためです。

では返済の手段、方法。これはわかりやすく、デプロイ1回あたりの差分の変更です。可能な限り小さくできるように、デプロイの粒度を細かくすることを選択したとしましょう。

それを実現するためには、デプロイ作業内容のコマンドを、毎回上から下まで全部人間が確認したり、内容の承認をするものを極力なくす必要があるでしょう。この内容確認を人間がやったり、紙で承認を挟んだりが、先ほどの図で、心理的にデプロイの回数を減らしたくなる力学の重要な要素だったからです。

ただし、人間による確認や承認が必要になっていた背景は、きっとあるはずです。ここでは深掘りはしませんが、ミスオペレーションをなくしつつ、かつ継続的にデプロイを行っていけるように、典型的なデプロイ処理は自動化しましょうと。

例えば、データベースのスキーマ変更処理がデプロイのときに必要になる場合は、今までどおり、人間が一部作業をこなす行為をしましょう。ただ単純にステートレスなWebアプリをロールアウトしたいようなタイミングでは、自動化する方向を目指しましょう。

自動化するにあたって、当面は自動化したデプロイが正しく動作していることをちゃんと確認できるよう、なにも変更がなくても、1日に1回デプロイフローを回す方法でやってみましょう、と。

最後に最も重要な効果測定です。これは、何を設定するのが適切でしょうか? 「デプロイが自動で回っているか」「デプロイが落ちていないか」ではありません。「デプロイの回数が増えているか」……近い気がするけど、違います。

この負債の返済タスクにおける効果測定、最もこのケースにおいて適切なのは、障害の原因特定にかける時間を減らせているか。それによって開発時間を確保できているか。あるいはサービスのアップタイムが改善しているか。このあたりが、効果測定の重要なメトリクスになってくるはずです。

少し話は逸れますが、一般にやっつけようとする負債のサイズが大きければ大きいほど、技術的な難易度やステークホルダーへの説明の難易度、あるいは適切な効果測定を行うためのメトリクスの設定の難易度が高まります。

そのためにまずは小さく始めて、うまくいったら広げていく。うまくいっていないと判断される場合には、すぐやめる。重要なことは、やめるだけではなく、どうしてうまくいかなかったのか。もともと考えていたプランでは効果が出るはずだったのに、なぜ効果が出なかったのかを後日再評価することも非常に重要です。

意思決定層は人的リソースの投入を見逃しがち

ここまでが、現場視点での技術的負債の返済の提案の話です。今度は提案を受ける側、意思決定層です。意思決定層の側における、技術的負債の返済への取り組み方についてはメインのトピックではないので、軽く見ていきます。

今までいろいろなお客さんと話をしてきて、多くの組織において、大事なのに意思決定層が見逃しがち、あるいは気づけていないことが1つあります。何でしょうか? 

負債の返済に、提案を受けたものに納得して合意したら、イコールそれはその負債の返済に人的リソースを投入する。あるいはリソースの追加投入ができないのであれば、新規開発を止める必要があるという、暗黙の前提を見逃している、気づいていない、あるいはわかっているけど……無視しているとしたら最悪ですが。こういったケースがいろいろな組織における意思決定層によく見られます。

現場のエンジニアは合意をした負債の返済に全力を注いでいるはずなのに、それとはぜんぜん違う方向性の意思決定層の思惑や、謎の緊急対応依頼のようなものが突っ込まれてくるわけです。

こんなものが入ってきていては、返済できるものもできません。新たな技術的負債を作りこむ可能性すら生まれてしまうわけです。NGです。

もし意思決定層がCXO、CTOのクラスになるのであれば、経営層全体が「今あげている負債の返済には人が必要なんだ=金が必要なんだ」「もし追加リソースの投入ができないなら、新規開発を止める必要性があるんだ」ということをきちんと理解していないと、負債の返済タスクはうまくいきません。

怒られることを承知で大事なことを一言でまとめると、返済タスクの邪魔をしないことです。

現場と意思決定層が技術的負債の返済ですることのまとめ

まとめていきましょう。組織での継続的な開発は、その規模が大きくなればなるほど、多くのステークホルダーが関わって、意思決定層が何層にも重なっていきます。そのような状況において、技術的負債をちゃんと返済する。そこにコストを払い、高い生産性を維持していくためには、現場と意思決定層、あるいは経営層も含むことがあるでしょう。双方の相互理解が絶対に必要です。

ソフトウェア開発や運用の現場で、システムに関わる人間。現場の方は、負債の存在と、その返済の必要性をステークホルダーが理解できる言葉や価値で説明する必要があります。これは現場の方の責務ですね。

どうして現場の人が行うことを推奨しているのかと言うと、そのシステムを深く知る人間がこれを行うことが、ほかの誰がまとめるよりも、最も低コストになることが見込めるからです。

負債の返済は小さく始め、効果が出てきたらほかのところへ広げる。いきなり大きくやろうとしないことです。それから、効果が認められない場合は、すぐにやめる。これが重要です。

そして効果が出なかった場合に、「ダメでしたね」ではなく、なぜ効果が出なかったのかをきちんと再評価する。これも、次の返済タスクをきちんとデザインしていくためには非常に重要です。

意思決定層あるいはCTOのような経営層の立ち回りも非常に重要です。返済しようとしている負債が、数ある負債の中で今返すべきものなのか、そして返済の効果を測定する指標が、適切に設定されているのかをきちんと評価するのは、意思決定層、経営層の仕事です。

ひとたび負債の返済にコストをかけることに合意したのなら、そのために必要となるリソースの確保は、多くの場合意思決定層であるあなたの仕事です。新規リソースを急に確保する、特に人のハイヤリングが必要だとなった場合は、簡単にはいきません。

では既存リソースだけでやるしかないとなったなら、それが新規開発の一時的な停止とトレードオフになる可能性を理解しなければいけません。

もちろん、ここであげた理解を、経営レベル、ほかの意思決定層にちゃんと伝えていく。そこで合意形成をして、認識をみんなで共有していくのも、おそらく意思決定層であるあなたの仕事になる可能性が高いでしょう。

そして返済タスクが進み始めたら、今度は効果測定を注視しましょう。結果が出ていない場合に、方向修正やガイダンスを行うことも、あなたに求められることの1つかもしれません。

組織の心ない声から守ることも必要

最後になりますが、技術的負債の返済タスクは、一般的に機能開発やバグフィックスと直結しないことが多いです。そのため、返済タスクが大きければ大きいほど、期間が長ければ長いほど、組織の中でその返済タスクの意味を疑う声が出てくることがあります。

「やる意味あるの?」「あそこに使っている人間を、開発やバグフィックスに投入したほうがいいんじゃないの?」のような声があがってくることもあります。

そういった声に対して、返済タスクの価値をちゃんと説明して、タスクの遂行を組織の心ない攻撃から守る。これもぜひリーダー層の方々に期待して、セッションを終えたいと思います。どうもありがとうございました。