Agile も DevOps も銀の弾丸なんかじゃない
……と、のっけから噛みつかれそうなタイトルを掲げてみたのですが;、ここ最近、立て続けて数件、「いやそれはアジャイルとか無理だろ;」的な話があって、ちょっとエントリを書いてみようかと思った次第。どんな話だったのかというと、
- アジャイルとか DevOps やれば必ず開発生産性上がるんでしょ? → そんなわけないでしょ;。
- これからの開発は当然アジャイルとか DevOps でしょ! → そんなわけないでしょ;。
みたいな話;。2 年ほど前に、「続・拝啓『変わらない開発現場』を嘆く皆様へ ~ ウォータフォール & アジャイル編~」というエントリを書いたのですが、その補足的な意味合いも兼ねて、少しまとめてみようと思います。正直、当たり前すぎる話なので、その道のプロな方は「ふ~ん」と読み流してください;。
[アジャイルや DevOps を活用することによる ROI 最大化の注意点]
のっけから結論を書いてしまうのですが、アジャイルや DevOps をエンプラ系プロジェクトに適用してメリットを得たい場合には、以下 2 つの点に特に注意する必要があります。
簡単に言えば、十把一絡げにアジャイルや DevOps を適用してもうまく行くわけがなく、これらの手法は決して銀の弾丸ではありません。しかし、なぜこれらが銀の弾丸ではないのか、またどんな条件があればアジャイルや DevOps のメリットが最大化されるのかは、意外に端的に語られていないため、軽く説明してみたいと思います。
[アジャイル開発 vs ウォータフォール型開発]
モノづくりの観点から考えると、ウォータフォールとアジャイルは、計画型/適応型のトレードオフの関係で捉えることができます。このため、それぞれ請負向き/内製向きという特性があることは、以前のエントリでも解説しました。日本の開発現場では、両者は二者択一の文面で語られることが多いのですが、日本のエンプラ系開発現場においてより良い開発を目指すためには、両者をミックスした開発プロセスのテーラリングが必要になります。
しかし、このような説明だとなかなかしっくりこないと思いますので、ぶっちぎりの適応型アジャイル(ここでは仮に「フルアジャイル」と呼ぶことにしましょう)がどのようなものなのかを考えてみたいと思います。
[完璧(?)なアジャイル開発について]
ご存じのように、アジャイル開発の背後には、「アジャイルソフトウェア開発宣言」と「アジャイル宣言の背後にある原則」がベースラインの考え方として存在します。原典そのまま引用すると、こんな感じです。
しかし見ていただければわかる通り、これらは具体的に何かの(技術的)手法を定義しているわけではなく、ある意味、ソフトウェア開発の『理想像』や『思想』を語ったものに近いです。実際、アジャイルを実践する開発現場では、日々、自律的な模索と改善が続けられ、よりよい開発技法を目指して進化を続ける……これこそがアジャイルの真価ではないかと思います。
……が、ぶっちゃけこれだと煙に巻かれた気がするなんだかよくわからないのも実際のところです;。以下は完全に私の私見なのですが、実際にこれらを目指して優れたアジャイル開発を実現している現場では、特に以下の 4 つをきっちり実践しているように思います。(この辺は皆様のご意見をいただきたいところですが、私の感覚として。)
ちょっとだけ補足をすると、以下の通りです。(MVP アプローチは極めて重要なので後述)
- 内製開発
- 一般的に請負型ウォータフォール開発では、受発注関係による利害関係が生じるため、請負契約の後は、発注側は「いかに変更・修正を突っ込むか」、受注側は「いかにそれを突っぱねるか」という不毛な争いが生じます。
- (特に大規模開発においては)請負契約は、確実に成果物責任を以て遂行させるという観点において極めて重要なものですが、一方で、関係者全員が同じ方向を向いてゴールを共有することが時として難しくなる元凶にもなり得ます。
- 内製開発であれば関係者全員が同じ方向を向いてゴールを共有することが容易ですが、その一方で、全員がプロフェッショナルであり、オープンかつ自律的な活動・改善ができる(言い換えれば全員が大人である)ことが求められます。(大規模開発だとそれだけの数のプロフェッショナルの頭数を揃えることが困難なケースが多いです。)
- データ駆動型開発(運用環境第一主義、Production First Mindset)
- 例えば仕様案として A, B の 2 つがある場合、実際の開発現場では、どちらを採用すべきかは一番偉い人の鶴の一声で決まることが多いです。しかしこのような主観的な物事の決め方では不適切な決定が行われることも多く、「客観性を以て」、すなわち「データを元に」開発上の様々な判断を下すことが求められます。このような考え方を「データ駆動型開発」と呼びます。
- データ駆動型開発を実現するために重要になるのが、「運用環境からユーザーの実際の使い方の情報を吸い上げる」ことです。このようなデータをテレメトリデータと呼び、運用環境での実際の情報を元に開発判断を下すことが望ましいです。このようなアプローチを「運用環境第一主義」と呼びます。
- DevOps インフラ
- データ駆動型開発や運用環境第一主義を実現するためには、A/B 両案を素早く作って素早く運用環境に配置し、運用環境からテレメトリデータを吸い上げ、それに基づいて決断を下して運用環境に反映させていく、という素早いサイクルが必要です。このために DevOps インフラが利用されます。
……とまあこの辺はよく語られるのですが、アジャイル開発の本質をよく言い当てているのが MVP アプローチです。これについて解説します。
[MVP アプローチ(Minimum Viable Product)について]
MVP アプローチとは、最終的な完成物を想定して段階的に作り上げていくのではなく、 「価値」を検証できる成果物をまず小さく作り、それを元に F/B を集め、軌道修正しながら最終成果物を目指すものです。これに関しては、Henrik Kniberg 氏のこちらの blog の下図が、極めて的確に本質を言い当てているので引用します。
イラストを見れば一目瞭然だと思うのですが、アジャイルのアプローチは、上図ではなく下図のようなものです。つまり、「どこかに行くときに素早く行ける乗り物が欲しい」というお客さんに対して、
- 上図のアプローチは、「きっと車が欲しいに違いない」と考え、最終成果物を先に想定してしまい、これを段階的(Incremental)に開発していく方法。
- 下図のアプローチは、「本当にお客さんが欲しいものはわからない」と考えて、とりあえずキックボードを作ってみて反応を伺い、そのあと自転車を作ってみて反応を伺い、最後にはスーパーカーを作って満足させる、という方法。
です。このケースにおいては当然下図のアプローチの方がよいわけですが、その理由は、
- 上図のアプローチは、価値検証が最後までできないため、開発のリスクが高い。(成果物の ROI が最大化されない)
- 下図のアプローチは、価値検証しながら進むため、成果物の ROI が最大化される。
というものですが、その一方で、下図のアプローチの場合は頻繁な作り直しが必要になるため、開発作業量は大きくなるという問題を抱えています(プログラミングの観点で言うのなら、無理な作り替えにより生じた技術的負債の適宜返済が必要になる)。最終成果物が最初からきっちり確定できているのであれば、上図のアプローチの方が最短経路でゴールにたどり着けます。
# 最終成果物が最初からきっちり確定できていることなんてない、と言われる方もいると思いますが、
# 例えば、サポートの切れた製品上で開発されたシステムをどうしても .NET などで再構築しなければ
# ならないような SoR 系のシステム場合には、最終成果物が概ね見えていることが多いです。
# このような案件では、上図のようなインクリメンタルなアプローチで開発した方がよいでしょう。
このことから、なぜアジャイル開発で ROI が最大化されるのか、そしてどのような開発にアジャイル開発が適しているのかに関して、以下のように整理できます。
現在の多くのエンプラ系のシステム開発案件は、既存資産まみれの中で開発することが多く、スクラッチでゼロから綺麗なシステムを構築するのではないケースがほとんどです。こうした条件下では、必ずしも MVP アプローチに代表されるようなアジャイル開発が最適とは限りません。そしてなにより、一定以上の規模の開発においては、頻繁な方針転換・作り直しをテキパキとこなせるだけの優れた高スキルなデベロッパーの頭数を揃えることが難しく、 結果として、MVP アプローチをやろうとしてもできない場合が少なくありません。
# ぶっちゃけですが、優れた開発者を頭数揃えられれば、どんな方法だってまあまあうまくいくはず;。
# 大規模開発で戦わなければならないのは、メンバーのスキルセットの平準化と底上げなんですよ;。
もちろん、アジャイルが無理だからといってウォーターフォールでやる、というのは短絡的です。以前のエントリにも書いたように、重要なのは、ウォーターフォール型開発をベースラインに置きながらも、アジャイルの手法をうまく取り入れることによって開発生産性の改善を目指す、すなわち開発プロセスを適切にテーラリングすることです。具体的な様々なテクニックについては拙著「業務システム開発 モダナイゼーションガイド」にいろいろ書いたのですが、ここでは「ウォータフォールとアジャイルのいいとこどり」という観点で、3 つほど具体的な方法を取り上げてみたいと思います。
[アジャイル開発技法の適用対象・活用手法]
本来のアジャイル開発(Scrum 開発など)をそのまま適用できないプロジェクトでも、アジャイル開発のプラクティス(技法)を部分的に活用した生産性改善は可能です。現場でよく利用される代表的なテクニックは以下の 3 つです。
- ① UX デザインフェーズにアジャイル開発技法を適用(アジャイルウォータフォール)
- ② CI/CD による下流工程の作業生産性の改善(頻繁なリリース(≠ 早期のリリース))
- ③ ボトムアップ型タスク管理を用いた予実管理と作業完了の推定(ミニアジャイル)
# 勝手に名前つけましたが、すでに業界的に標準名が決まっていたら教えてください;。
それぞれについて説明します。
① UX デザインフェーズにアジャイル開発技法を適用(アジャイルウォータフォール)
大規模開発を安定的に進めるためには、どこかのタイミングでいったん仕様を確定させる必要があります(=仕様のベースラインを決めて、そこからの修正については「仕様変更」として管理する)。UI/UX は試行錯誤による改善が求められるため、外部設計終了のタイミングで仕様を確定させる方法が一般的で、ここでアジャイル/ウォータフォールのアプローチを切り替える方法がよく取られます。すなわち、要件定義~外部設計までは(モックを高速に開発・提示して F/B を受けて修正する)アジャイル型で進め、外部仕様が確定した時点からはウォータフォール的に開発を進める、というものです。この方法はエンプラ系システム開発でも極めて取り組みやすく、実際の現場でも頻繁に使われていると思います。
② CI/CD による下流工程の作業生産性の改善(頻繁なリリース(≠ 早期のリリース))
下流工程での作業効率を高めるために、以下の CI/CD の仕組みを導入することは極めて有効です。ちなみに VSTS だとぜんぶ簡単にできるよ! と宣伝w。
- ソースコード管理
- 自動ビルド
- (カナリアサーバやテストサーバへの)自動リリース
- (部分的な)テストの自動化
- 手動テストの効率化
# これらについては拙著「業務システム開発 モダナイゼーションガイド」にいろいろ書いたので、ここでは割愛。
③ ボトムアップ型タスク管理を用いた予実管理と作業完了の推定(ミニアジャイル)
下流工程の一連の作業がきちんと予定工期中に終わるかどうかを確認するために、ボトムアップ型タスク管理を用いた予実管理を行うのも非常に有効性があります。こちらも以前のエントリにおいて「Scrum のスプリントプラクティス」にて解説していますので、興味がある方はご確認ください。
これら 3 つの技法のポイントは、基本路線としてはウォータフォール型開発を維持しつつ、アジャイル開発のプラクティスをうまく取り込んでいくものだという点です。特にエンプラ系の大規模開発(数億円を超えるようなプロジェクト)では、ベースラインをウォータフォール型に置いた方がよいケースが多く、いきなりフルアジャイル型でやろうとすると、特にお客様が(慣れていないために)対応できないことがほとんどです。最終的にフルアジャイル型を目指すにしても、段階を追って切り替えていく・成長していくことは重要です。フルアジャイルを実践している開発現場だって、いきなり現在の開発スタイルになったわけではないのですから。
[実際の作業ワークフローの設計例]
以上のような考え方に基づき、実際の開発では、開発作業のワークフローを下図のようなコンセプト図として整理することをオススメしたいです。ちなみに下図は、モバイルアプリ開発にエンプラ系企業が手を出そうとする際に、割とスムーズに受け入れられやすそうな形でワークフローを整理したものです。
上図の場合、作業ワークフローの設計上、以下のような点がポイントになっています。
- ユーザエクスペリエンスチームとサーバ/クライアント開発チームを分断している
モバイルアプリ企業の場合、ユーザエクスペリエンスチームとクライアント開発チームとが合体している場合も多いと思います。しかし、エンプラ系企業が開発するモバイルアプリの場合、UI/UX の裏側に実装するロジックもそれなりのボリュームになる場合が多く、外部仕様を固めてからアプリの開発に進まないと、開発の制御がしにくくなることがよくあります。このため、外部設計段階で仕様をいったん fix できるように、開発チームを分断しています。 - サーバ/クライアント開発チームを分断している
エンプラ系企業がモバイルアプリ開発に取り組む場合、バックエンドのサーバロジックはすでに基幹系として存在しており、API のみ追加開発するような場合も多いでしょう。一方、クライアント側のモバイルアプリ開発に関しては、言語からして Swift など異なるモノを使う場合も多く、スキルセットが異なります。さらに、開発のサイクルも、サーバ/クライアントで速度感が異なると考えられるため、これらのチームを分断するようなワークフローとして設計しています。 - 複数の開発・テスト環境を用意し、段階的リリース(リング配信)ができるようにする
現在開発中のアプリがすぐにみられるカナリア環境、ある程度開発が進んだアプリについて構成テストを行えるようにするテスト環境、さらにβチャネルを介して先行ユーザ配信を可能とする運用環境など、目的に応じた多段階配信ができるようにリリースシステムを設計します。
再三の繰り返しになりますが、このような設計がよいかどうかはもちろんケースバイケースです。チームやプロジェクトの実態に合わせて、開発プロセスをテーラリングすることがなにより重要です。
[アジャイルと言いながら偽装請負にならないために]
ここまではウォータフォール型にアジャイルを組み込む流れで説明しましたが、本当のアジャイル型で開発をやりたい場合に関して、一点だけ書かせてください。実際の開発現場でよく見かける光景なのですが、アジャイル開発は請負型ではダメ、ということでベンダーさんと準委任契約を取り交わしているにもかかわらず、お客様がアジャイルのチームに入ってこない、というケースがあります。例えばスクラムのチーム体制に基づいてイラストを書くと、下図のようになっている場合があります。
アジャイル開発で新しいシステム開発スタイルに変えていきたい、という前向きなお客様は結構いらっしゃいますが、このパターンに陥ると失敗する確率がかなり上がります。理由は簡単で、本来、プロダクトオーナーは業務要件を整理し、それらに対して適切な優先順位付けとスコーピングを行うことがゴールなのですが、お客様がチームの外にいると、なんでもかんでも押し込もうとしてしまうためです。お客様からの要件詰め込みの圧力に対抗するためには、実際にお客様がプロダクトオーナーの立場としてプロジェクトに参画しなければならず、この体制を最初に作れるかどうかが極めて重要です。
多くの場合、お客様側はアジャイル開発やスクラムに十分な知見を持っていないため、お客様からアジャイルやりたい、と言われた場合には、このようなリスクについて十分に事前に説明すること、そしてプロジェクトの立ち上げ時点できっちり体制を組むことを、特に気を付けていただけるとよいかと思います。
[まとめ]
というわけでここまでいろいろ書いてきましたが、要点をまとめると以下の通りです。
- アジャイルや DevOps のメリットを享受するためには、① 適用対象プロジェクトの見極めと、② プロセステーラリングの 2 つが重要。
- フルアジャイルの特性は、① MVP アプローチ、② 内製開発、③ データ駆動型開発、④ DevOps インフラの 4 つに代表されるが、これらを完全に適用できることは、エンプラ系開発だと稀。
- MVP アプローチが、アジャイルアプローチの本質を言い当てている。頻繁な軌道修正と作り直しが必要とされるため、万能な開発技法というわけではなく、プロジェクトに以下のような特性・要件が必要。
- SoE 型アプリ
- 初期段階で最終要件が確定できず、試行錯誤が必要になるもの
- 進化させ続けることが必要な戦略領域のアプリ
- スクラッチ型開発が必要そうなもの
- エンプラ系の大規模開発で、ウォータフォール型開発にアジャイル型開発のプラクティスを取り込む場合、以下の 3 つが代表的なテクニック。
- ① UX デザインフェーズにアジャイル開発技法を適用(アジャイルウォータフォール)
- ② CI/CD による下流工程の作業生産性の改善(頻繁なリリース(≠ 早期のリリース))
- ③ ボトムアップ型タスク管理を用いた予実管理と作業完了の推定(ミニアジャイル)
- 実際にアジャイル開発を行いたい場合、お客様側から開発チーム側に PO (プロダクトオーナー)を出してもらうことが極めて重要。ここを外すと偽装請負的な開発になってしまう。
アジャイル開発に関しては様々な考え方があると思いますし、このエントリが必ずしも正しいというわけではないと思います。が、このエントリが、皆様が開発現場でより良い開発手法を模索するための一助になれば幸いです。
# ご意見やアドバイスは、コメントやはてブ、Twitter などでいただければ嬉しいです^^。
# 皆様の知見に基づくご意見やアドバイスをぜひ共有してください~。