DevOpsは、アプリケーションを開発して公開し、サポートからのフィードバックを反映していく方法として主流になりつつあります。しかし、DevOpsを成功に導くには、組織面での複雑さやマシンデータの収集といった課題を克服する必要があります。
技術的負債(Technology Dept)はソフトウェア開発上の問題に対して、根本的で徹底した解決策ではなく、安易で不完全な「その場しのぎ」の解決策を選択したために、組織が後で支払うことを余儀なくされる大きな潜在的コストのことです。コード負債とも呼ばれます。技術的負債については、プログラマーのWard Cunningham氏が1992年に発表した記事(英語)で初めて定義されました。その記事では、不完全なコーディングによって企業は短期的にはコストを節約できるものの、長期的には、金銭的負債と同様に技術的負債による「利息」が蓄積し、時間が経つにつれて最初の問題を修正するためのコストが増加すると述べられています。
技術的負債は悪いもののように思えるかもしれません。しかし、適切に管理されていれば、必要に応じて開発を迅速に進めるための手段となります。実際にMVP(実用最小限の製品)は、大きな技術的負債を抱えた状態で開発されることも珍しくありません。この場合、MVPに継続的な価値があることが証明された段階で、完全にリファクタリングや作り直しが必要になるということが想定されています。技術的負債とは、物事を迅速に行うことと、それを正しいやり方で行うことは、滅多に両立しないという認識に立った考え方であるといえます。
また、技術的負債は、意図せず発生することもあります。ずさんなプログラミング、手抜き、急なスケジュールの前倒しはすべて、どの企業も直面する共通の問題といえるでしょう。この用語の厳密な定義に従えば、これらの問題は真の技術的負債には分類されないものの、問題の修正には同様の作業が必要になることは変わりありません。
技術的負債の特定は非常に難しいです。また、低品質なコードが技術的負債になるとは限りません。技術的負債とは、コードそのものではなく、低品質なコードがもたらす損害と、後にそれを修正するためのコストを指します。
元来、技術的負債とは、トレードオフが必要となることがわかっている意図的なものです。コードは、後々修正されることを意図したうえで(MVPの一部として、または一時的な解決策として)、記述されることがあります。このような技術的負債を特定するのは簡単です。開発者の中には、ある解決策が一時的なものであり、将来の時点で何らかの手直しが必要になるということをコーディング中に積極的に文書化する人もいます。
その他の種類の技術的負債については、見抜くのがより難しい場合があります。偶然、怠慢、能力不足、適切なトレーニングの欠如などが技術的負債を招くこともあれば、ユーザーの要件が途中で変更され、それでも製品を予定通りに出荷しようとして、ミスが発生したり、急いでコードを記述したりしたために生じることもあります。また、数カ月あるいは数年後に別のプログラマーがプロジェクトを引き継ぎ、コードベースに変更を加えることで新たな問題が発生することもあります。
意図しない技術的負債を発見する主な方法の1つは、ユーザーの声に耳を傾けることです。問題を訴えることが多いのはユーザーです。たとえば、時間の経過とともにパフォーマンスが低下するという問題をユーザーが訴えているとしたら、そこに意図しない技術的負債が潜んでいる可能性があります。また、技術的負債を発見する別の方法として、クラッシュログやアプリケーションパフォーマンスデータの分析も挙げられます。
技術的負債は、本来は悪いものではありませんが、良い方向に作用することが少ないのも事実です。しかし、時間との勝負であるような場合や、完成したコードの最終的な品質が重要でない場合には、貴重な手段となり得ます。たとえばPoC (概念実証)や、どうしても必要なソフトウェア機能を市場に迅速に提供しなければならない場合などには有効な手立てです。
とはいえ、技術的負債が膨らんだり、無計画に使用されたりすると、問題が生じ始めます。実際、技術的負債という概念は、プログラミングの粗悪さやいいかげんさを隠すために使われることが少なからずあります。技術的負債という概念の背後にある中核的な考え方についても、年々誤解が深まっていると主張する専門家もいます。Ward Cunningham氏は当初、開発者が解決しようとしている問題への理解が不十分なために、最初に低品質なコードを記述したとしても、その理解が深まった後でより良いコードに書き換えるつもりであれば、技術的負債を肯定的に捉えることができると述べていました。しかし、今日の技術的負債の多くは、単にやり方がずさんなために発生しているといえるでしょう。「後で修正する」というのがいつも言い訳であったり、低品質なコードをすべて技術的負債と呼んでいたりするようでは、技術的負債は「悪」であると考えるべきでしょう。
金銭的な負債の場合も同様のことが言えます。良い技術的負債とは、なるべく迅速またはタイムリーに返済するように計画され、それを利用することで組織とエンジニアリングチームが何らかのリターンを得られるようにすることです。開発チームがプログラミングの問題に対する理解を深めるにつれて、低品質なコードをリファクタリングして書き直し、より持続可能で堅牢なソフトウェア製品を生産することで技術的負債を返済する必要があります。MVP(実用最小限の製品)にはほぼ必ず技術的負債が伴いますが、時間の経過とともにその改良を重ねていくことを計画している場合にのみ、「良い」技術的負債といえます。
技術的負債は、複数のカテゴリに分類されています。
- 意図的な技術的負債:意図的な技術的負債とは、企業が製品を迅速に市場に投入するために、意図的に行われるものです。この形態の技術的負債の1つが計画的選択です。これは基本的に、製品を早期にリリースする代わりに、ある程度の不安定さ、安全性やパフォーマンスの低さ、ユーザーの不満などの問題を企業が受け入れることを意味します。このような技術的負債にはリスクがありますが、すべての関係者が適切なタイミングで文書化、追跡、および修正できる既知のリスクになります。
- 意図しない技術的負債:この形態の技術的負債は、ソフトウェアエンジニアリングのずさんさ、予期しない複雑さ、または技術的専門知識の不足から発生します。経営陣が突然出荷期限を1週間早めたために、エンジニアリングチームが手を抜いたり、製品のテストを完全に行わなかったり、不注意で製品にバグが入り込んだりすることによって、意図しない技術的負債が発生することがよくあります。このような技術的負債は文書化されることもありますが、しばらく気付かないことが多いため、通常は文書化されません。意図しない技術的負債を修正することは可能ですが、そのためには、開発プロセスを調整し、出荷済みのコードを見直す時間をスプリントシステム内に確保する必要があります。
- 環境による技術的負債:技術的負債の最後のカテゴリは環境の技術的負債です。これは、時間の経過あるいはアクティブな対策を行わないことによって発生します。完璧なプログラムを開発し、リリース後の評判も上々であったとしても、環境は常に変化しているため、プログラムがアクティブに管理されていなければ、環境による技術的負債が発生する可能性があります。たとえば、オペレーティングシステムにパッチが適用されたことにより不整合や互換性の問題が生じたり、ベンダーのAPIや必要なソフトウェアライブラリのアップグレードにより互換性の問題が生じたり、セキュリティパッチによりアプリケーションが正しく動作しなくなったりすることがあります。こうした変化に対応できなければ、アプリケーションはやがて正常に機能しなくなり、他の技術的負債と同様、時間とともに悪化の一途を辿ります。
3種類の技術的負債:意図的な技術的負債、意図しない技術的負債、環境による技術的負債
技術的負債の管理は複雑な問題です。なぜなら、あらゆる種類の負債と同様に、技術的負債も返済が長引くほど悪化していくからです。組織が「返済」計画を立てずに技術的負債を負った場合、問題はすぐに悪循環に陥って制御不能になる可能性があります。
ここでは、技術的負債に対処するためのベストプラクティスをいくつか紹介します。
- スクラム/スプリントのプロセスに技術的負債を明示的に含める:技術的負債の返済を日々の開発プロセスの一部に含めて、バックログにならないようにします。
- 技術的負債を慎重に追跡する:目に見えないものを修正することはできません。開発における他の課題と同じように、技術的負債を監視して追跡し、優先順位を付けます。
- 新製品のリリース作業だけでなく、メンテナンス作業に対しても正当に報いる:目立つ新製品を市場に投入したソフトウェア開発者にばかり賞賛が集まりがちですが、既存のソフトウェアプロジェクトや製品の機能を修正し、維持するために全力で取り組んでいる人たちにも目を向けましょう。
- 品質基準を設定し、それを遵守する:プログラマーがずさんなコードを出荷するのを阻止できれば、意図しない技術的負債を回避しやすくなり、管理も容易になります。
- 突然のスケジュール変更を避ける:経営陣が開発者に対するルールの変更、納期の変更をすると、技術的負債が避けられなくなることが多々あります。現実的なスケジュール、手法、対応可能なワークロードを提案して、技術的負債を管理しやすくします。
行動分析の結果から技術的負債がビジネスに及ぼす影響について、以下のことがわかっています。
- ユーザーの不満:技術的負債は総じてバグの多いコードとなることから、ユーザーエクスペリエンスが損なわれ、満足度が低下します。これは、最終的には費用の増加(顧客サービスの必要性が増加)と、収益の減少(顧客離れが発生)につながります。
- 開発サイクルの長期化:技術的負債が悪化するにつれて、開発者は既存のコードベース内で作業することが難しくなります。その結果、新機能の開発と古い機能の修正の両方に時間を割かれるため、構築プロセスに時間がかかり、市場投入までの時間が長くなります。
- イノベーションの行き詰まり:技術的負債が深刻な場合、開発者は問題への対応に追われ、革新的な新機能の構築に時間を費やすことができなくなります。
- 潜在的なセキュリティの問題:低品質なコードはセキュリティも不十分であることが多く、企業のソフトウェアシステムに予期しない脆弱性を与える可能性があります。
技術的負債は、以下のような形でビジネスに数多くの財務的な悪影響をもたらす可能性もあります。
- 直接的な売上の減少:バグの多いソフトウェアに不満が高まり、顧客離れが発生する可能性があります。
- サポート費用の増加:留まっている顧客も、カスタマーサポートを必要とすることが多くなります。
- 開発者の人数の増加:技術的負債を管理するためには、負債を抱えたソフトウェアを修正するための追加の人材が必要になります。
- 生産性の低下:開発者は、付加価値のあるソフトウェア機能の開発に多くの時間をかけることができず、全体的な生産性が低下し、ビジネス目標やビジネスニーズの達成が阻害されます。
- セキュリティ侵害のリスクの増大:セキュリティ侵害には、資産の直接的な損失、ビジネス上の損失、規制当局による罰金や罰則のリスクなど、金銭的なリスクが伴います。
技術的負債は、売上の減少、サポート費用の増加、生産性の低下など、企業の財務実績に悪影響を及ぼす可能性があります。
継続的開発という固有の性質から、DevOps環境を技術的負債の回避に役立てることができます。継続的なテスト、自動化ツール、開発サイクルと運用の統合によって、短期的であっても、技術的な課題が脇に追いやられるようなことが起こりにくくなります。DevOpsチームは常に、企業にとって最大のメリットをもたらす方法で問題を解決するにはどうすべきかを考えています。そのため、技術的負債の課題に対しても、早期に、頻繁に、そして直接的に対処しなければならないことも多くあります。
問題は、すべてのコードのスニペットが高品質であるとは限らず、同じレベルのチェックを受けるわけでもない点にあります。最も厳格なDevOps企業であっても、緊急の問題に対処するために、開発者がちょっとしたコードをすばやく記述し、QAプロセスを省略しなければならないことがあります。
実際、迅速な開発と継続的なリリースサイクルを重視するあまり、このようなその場しのぎの解決策が結果的に容認されることもあります。なぜなら、開発者は自分のせいでリリースパイプラインを遅らせることは避けたいからです。さらに、DevOps体制が確立するよりも前から存在するサードパーティのライブラリやレガシーコードには、それ自体が抱えている対応が必要な技術的負債の問題が存在していることもよくあります。
基本的に、DevOpsは技術的負債を免除するものではありません。しっかりと管理されたDevOpsフレームワークは、技術的負債への依存を軽くすることはできますが、開発者の多くは、非DevOps環境で「危機的状況」を乗り切ってきたのと同じ回避策にこれからも頼るでしょう。
金銭的負債とは違って技術的負債には特有の代価があり、従業員や他のチームメンバーの多大な労働力によってこの負債を返済します。新製品や新機能の開発とは異なり、古いコードをリファクタリングして技術的負債を返済する作業は、やりがいのある仕事とはいえません。また、開発者が付加価値のある作業に取り組む代わりに、古いコードを修正することは、チームの他のメンバーのみならずビジネス全体にも影響を与えます。
技術的負債が重くのしかかると、開発チーム内で責任のなすりあいや非難の応酬が始まり、分裂や内輪もめにつながる可能性もあります。チームワークがすべてであるDevOps環境において、これはあってはならないことです。これにより、チームの士気低下や、生産サイクルに遅れが生じて新製品のリリースまでの時間が不足する可能性があります。また、新たな技術的負債が発生するため、ビジネスの状況がさらに悪化する可能性があります。
最終的には、管理できなくなった技術的負債が悪循環を生み出して、従業員の不満や高い離職率のほか、ビジネス成果にさまざまな悪影響をもたらすことになります。
多大な技術的負債が蓄積すれば、やがてはその負債を単に管理するだけでなく、返済しなければならないときがやってきます。多大な技術的負債を返済するための方法には、次のようなものがあります。
- 良い技術的負債と悪い技術的負債を分ける:技術的負債を、その発生場所と、意図的(良い)かそうでないか(悪い)に基づいて分類することが重要です。技術的負債から脱却するためにどのような戦略を取るにしても、通常は悪い技術的負債に最初に焦点を当てる必要があります。これはビジネスに最も大きな影響を与える可能性があるためです。
- 修正計画にはソフトウェア開発者を参加させる:技術的負債が手に負えなくなりつつあるときは、総力を挙げてこの問題に対処する必要があります。新機能や新製品を開発する代わりに、古いコードのリファクタリングに注力するような優先順位の変更には多くの開発者が抵抗する可能性が高いです。そのため、この作業をチーム全体の取り組みとして位置付けることが重要です。一握りの開発者に仕事を丸投げするのではなく、チーム全体で仕事を分担することを検討してください。
- 重大な問題を優先する:技術的負債が原因でアプリケーションが停止したり、セキュリティ上の欠陥が露呈したりしている場合、これらの問題に最初に対処する必要があります。たとえば、疑わしいコードであっても、パフォーマンスへの影響が少ない場合はすぐに対処する必要がないかもしれません。
- 技術的負債の影響を測定するためのメトリクスを設ける:これらのメトリクスとしては、コードのタイプに応じて、顧客満足度、アプリケーションのクラッシュデータ、あるいはパフォーマンスや財務に関連するデータなどが考えられます。こうしたメトリクスを長期的に監視することで修正作業の効果を判断できるため、開発チームの意欲を高めることもできます。
- 技術的負債の修正を継続的な作業とする:DevOpsが継続的開発と統合を重視するように、技術的負債の修正も継続的なリリースサイクルの一部とするべきです。修正の習慣を日々のスクラムやスプリントに取り入れることで、最終的には、これが生産サイクルの一部として当然の作業になるでしょう。
「技術的負債」という用語は誤用されることも多く、十分な理解を得られていません。そして多くの開発者は、品質の低いコードすべてに対してこの用語を当てはめています。これでは、技術的負債の有用性を活かすことはできません。技術的負債を適切に管理すれば、ビジネスに大きな柔軟性、俊敏性、実行スピードをもたらすことができます。その一方で、技術的負債が適切に管理されなかったり、過剰に使用されたり、誤用されたりすると、すべてが深刻な問題につながり、技術的負債が累積するにつれて状況はさらに悪化し、最終的には開発サイクルが停滞することになります。意図しない技術的負債や環境による技術的負債を回避し、意図的で詳細に文書化された技術的負債のみを利用するよう心がけることで、開発チームそしてビジネスを成功に導くことができます。
DevOps 5つのプラクティス
DevOpsチームの明暗を分ける5つのプラクティスについてご紹介します。