Microsoft の DevOps への道のり

Yuki Hattori
35 min readMar 15, 2019

Microsoft の開発も最初から DevOps だったわけではありません。地道に 1 つ 1 つの技術や手法、組織の変更が積み重なって、今のような開発スタイルになっています。この投稿では Azure DevOps という Microsoft の DevOps の根幹となっているツールの開発チームが、どのように環境を DevOps にトランスフォームしてきたか紹介します。

DevOps についてはいろいろ議論があるところです。「ツールだけ揃えてもカルチャーが変わらなければ DevOps じゃないよね」とか「CI/CD してるだけで DevOps してるとか言ってるよ (笑)」とか。
個人的には、日本の Waterfall がメインの IT 業界 は、なかなか DevOps というか Agile の世界にも行けていない現状があるので、あるべき論よりも「とりあえず何か 1 つやろう。」という姿勢が大事な気がしています。下記のストーリーや技術、手法が 1 つでも役に立てば幸いです。

目次

Microsoft DevOps
・そもそも Microsoft は開発者の効率化を推進してきた会社
・Microsoft の組織
・ツールの普及とツールの進化

カスタマーフォーカス
・Customer Obsession なデータ分析と管理
・機能追加とフィーチャーフラグ

プロダクション マインドセット
・インシデント対応
・アラートの設定が検知スピード向上のためのキー
・インシデントに対応する際の役割
・デプロイを自動化するなら”完全に”

チームの自律とアラインメント
・ チームの構成の変更
・文化の生成
・プランニング
・Sprint 中のコミュニケーション
・これらのトランスフォーメーションのベネフィット

シフトレフトのクオリティ
・ バグキャップ (Bug Cap)
・統合テストからユニットテストへの移行

結果
どこから手をつけるか

Our Journey to DevOps at Microsoft

Microsoft DevOps

そもそも Microsoft は開発者の効率化を推進してきた会社

Azure DevOps とはマイクロソフトの DevOps ツールで、Git リポジトリやプロジェクト管理のためのカンバンボード、ダッシュボード、CI/CD のパイプライン作成など、様々な機能を有しています。このツール自体は長い歴史があります。

そもそも Microsoft は Microsoft Visual SourceSafe というソースコード管理ツールを出していました。初版は 1994 年で、作業を分離する概念がないツールでした。ファイル操作の際にはファイルはロックされるしマージも簡単にできません。その後、Visual Studio Team System が出て、Team Foundation Server(TFS) に名前が変わり、この時点ではもうソースコード管理以外にもデータの保存やプロジェクト管理などの基本的な機能が揃ってきました。TFS はオンプレのプロダクトですが、その後に TFS がオンライン化し、Visual Studio Online というサービスになりました。その後、サービスは Visual Studio Team Services(VSTS) と名前を変えましたが、昨今の Microsoft の OSS 化 に伴い、つい最近 Azure DevOps にリブランドしました。合わせて TFS も Azure DevOps Server になりました。

以前から、ツール自体はOSS 系の言語やフレームワーク、プラットフォームに対応していましたが、Visual Studio の名前のせいで「うちは C# のプロジェクトだからこのシステムに限っては VSTS 使おうかなぁ。」と用途が限定されているようなイメージを持たれてしまっていたのもリブランドの一つの理由だと思います。

Azure DevOps では下記のような機能を提供して DevOps を実現することができます。

Azure DevOps

さて、ここからが本題ですが、ソースコードやプロジェクト管理などのツールは Azure DevOps によって一通り揃えることができます。しかもこのツール自体、ほぼ無限とも言えるリポジトリが付いて、基本的な部分は無料で使い続けられる大盤振る舞いサービスです。

では、これを使ったら Microsoft のようなDevOps が実現できるのか? この問いの答えは Yes であり No でもあります。結局のところ カルチャーや組織、手法など様々な要因が関わってきます。

Microsoft の組織

Microsoft は官僚的組織とも揶揄されます。それぞれの大企業、いわゆる GAFA と言われる組織は下図のような構成になっていると言われています。(最近では ありがたいことに GAFA+M と言ってくれる人も多くなりました…)

http://www.bonkersworld.net/images/2011.06.27_organizational_charts.png

Microsoft に至っては下図のように表現されることがしばしあります。社内では政治がはびこり、もちろん Dev / Ops は分離しており、その他のチーム間でのコラボレーションもうまくいかない。実際はどうかは組織によっても違うのでなんとも言えませんが、色々なところでこのような組織構造について言及されていたという事実はあります。

変革が始まったのは 2014 年に CEO が Steve Ballmer から、Satya Nadella に代わったころです。この頃から 急激に OSS ラブな会社に代わり、エンジニアだけでなく様々な組織の構造も代わっていきました。下記のメッセージにもあるように、社内が効率化されるように構造が変わり始めたのが彼の就任後です。

エンジニアやプロダクトチームにとって、生産性を推進するシステムに取り組むことよりも、重要なことはありえません。
- Satya Nadella

今回の投稿のテーマである Azure DevOps のツールに関しても、2016 年に Xamarin の買収後、現在では開発チームの主要メンバーは実は Xamarin 出身者が多かったりします。そして DevOps ツールの組織のトップは Nat Friedman という GitHub の現 CEO が勤めています。
Microsoft 社員の情報は LinkedIn で探してみるとタイトルや組織含め わりと詳細に出てくるので面白いかもしれません。

このように、まず CEO がエンジニアリングの方法を変えるために舵を切り、外からの風をどんどんチームに取り込み、組織をどんどん変えていったという組織的背景があります。

ツールの普及とツールの進化

社内の Azure DevOps (VSTS) 普及スピード

Satya Nadella が 2014 年に CEO になってからこういったツールの普及と統一がどんどん進んでいきます。

Azure DevOps チームは、Azure DevOps を使いながら Azure DevOps を開発しており、Scrum で 3週間の Sprint を繰り返しています。マイクロソフトの開発チームの開発手法といっても、組織内で様々な違いがありますので、このサイクルは製品チームによってバラバラだと思います。

Azure DevOps チームは Azure DevOps の開発をしながら 社内、社外のフィードバックを元に製品を進化させていき、そのフィードバックをもとに社内の Waterfall スタイルを Azure DevOps によって Scrum に変えていきました。Azure DevOps を進化させることが社内の DevOps 化に繋がるという状況だったわけです。

さらに文化的な部分については、DevOpsDays Tokyo 2019 において 弊社の Edward Thomson が詳しく話す予定ですので、Deck が公開されるかは不明ですが、情報を追っておくと面白いと思います。

では、どのように DevOps をするか。まず大枠のリズム感を知るのに良い素材としては、Azure のアップデートブログがあります。Azure のアップデート情報は Azure updates にすべて纏められていますが、Azure DevOps のアップデートだけにはなぜか “Sprint” という文字が入っています。例えば下記は Sprint 148 のアップデート。

お分かりの通り、この Sprint は Scrum でいう Sprint です。内部的に行われている Sprint がどのような規模なのか、皆さんもこの情報から垣間見ることができます。そして、開発に関してもかなり詳細に 1 スプリントでやる内容が決まっているので、下記のように ロードマップも詳細に示して公開することができています。

Sprint 1 が始まったのは 2010 年 8月、製品名が Visual Studio Online だった頃です。

Azure DevOps のスプリント

では、それぞれの開発でどのようなことを行なっているのかに付いて、下記のテーマに沿って紹介していきます。CI/CDプロセスの組み方や技術的な説明ではなく、もう少し概念的な説明になります。

  • カスタマーフォーカス
  • プロダクションファースト マインドセット
  • チームの自律とアラインメント
  • シフトレフトのクオリティ

カスタマーフォーカス

Microsoft の DevOps の定義はこちらです。

DevOps is the union of people, process, and technology to enable continuous delivery of value to customers.

DevOps とは、顧客に対する価値の継続的デリバリーを可能にする人員、プロセス、テクノロジの集まりです。

詳細はこちら。まだ日本訳がないので、今度訳そうと思います。

Microsoft の DevOps の定義の根幹には顧客に対する価値があります。この DevOps の定義は “Customer Obsession” という Microsoft のカルチャーから来ています。Obsession という言葉はとても強い意味をもつため、Customer と合わさった場合、ただの “顧客志向” ではなく、「もうお客様を愛してやまない!」という念に取り憑かれているような表現になります。

Customer Obsession なデータ分析と管理

Customer Obsession の背景があり、Azure の開発においては ユーザーのフィードバックが最重要視されます。feedback.azure.com というサイトがあり、ここで要望が投稿され、それに対して同意するユーザーは Vote という形で意思を示すことができます。Azure は実際にこれらの要望はすべてチームが逐一チェックし、精査された後バックログに入っていきます。

我々も Azure の昨日追加要望を依頼された時に言っていることが「できれば、まず feedback に書いて Vote してください。」ということです。このフィードバックは本当に開発チームにとって重要です。この feedback に基づいて Azure に実装された機能は山ほどあります。

その他にも Azure ポータルからのフィードバックや Stack Overflow のウォッチ、Azure DevOps 自体の使用率のチェックも欠かしません。

集めるデータはもちろん ユーザーのデータだけではなく、プロダクションにおけるテレメトリを収集して仮説検証を繰り返しています。

Application Insights Analytics

このプロセスにおいては、構造化 / 半構造化データを検索し、大量のデータを分析しています。
この分析は皆様も、 Azure の Application Insights を使うことで実現できます。アプリケーションにライブラリを追加して 2, 3 行コードを追加するだけで下記のようなクラウドのアプリ分析ダッシュボードが完成するサービスです。

また大量のデータになる場合は Azure Data Explorer というツールを使うことによって、データを扱うことができます。Mobile 開発のための Azure App Center も Azure DevOps の Mobile 開発版として存在しますが、こういったツールもダッシュボード を提供しています。モバイルからウェブまでユーザーの行動を把握するようなプラットフォームは揃っているので、今では皆様もデータを簡単に収集することができます。

こういったツールはどこから来ているかというと、多くは社内ツールとして出来上がったものなのです。そもそも Azure Data Explorer も 社内では Kusto と呼ばれており、Azure のログ解析に長く使われてきました。

Azure のこれらのツールの多くはもともと Azure のユーザーの動作やそれに伴うサービスの挙動を捉えるために出てきたもので、Azure のプロダクトチームの経験を詰め込んだようなサービスになっています。

一方で、監視項目は Azure DevOps のチームにおいては下記のようになっています。青いものが 重要な KPI として位置付けられており、赤いものは ”積極的に” ウォッッチしない項目です。実際にはバグの数やバーンダウンなども Azure DevOps からはみることができますが、重要なものはあくまでも顧客であり、社内の人間やチームの評価ではありません。

インシデントが発生した際にも、顧客ごとに SLA を分析し、積極的にコミュニケーションを取ることを優先しています。

機能追加とフィーチャーフラグ

また、機能追加の際の検証もすべて顧客ベースの仮説と検証によって組み立てられています。

仮説検証と学習のプロセス

こういった顧客ベースで検証された機能は実際に実装され、外に出ることになるのですが、デプロイにおいては、フィーチャーフラグが使われます。

これは機能ごとにフラグをつけた状態で全ての機能をデプロイし、フラグによって公開を制御する手法です。顧客ごとにデプロイし直すことなく機能のオンオフが可能で、一部のユーザーに対して実験を行なうことを可能にしています。ダークローンチと言われることもありますが、これによって新サービスと既存サービスの互換性や、新サービスにおけるサービスパフォーマンスを測ることができます。

そのため、大々的なローンチの前に一部のユーザーやインターナルユーザーでテストすることで、より安心してサービスをローンチすることができますし、何かバグが見つかった時にもフィーチャーフラグのトグルをオフにすることによって元に戻すことができます。

Feature Flags

プロダクション マインドセット

インシデント対応

問題の解決のために、Live Site Incident(LSI) Conference Bridge が作られました。これはインシデント時の社内外、チーム内外を横断するコミュニケーションおよびコールのことで、根本的な原因のデータを収集し、顧客への影響を軽減するために存在します。

すべてのアクションは記録され、LSI の長期稼働中に人を交代させる計画は綿密にたてられています。人間は寝なければ生きていけませんので障害対応中にはどこかで担当者をスイッチさせる必要があります。

私は 1 ヶ月間 Redmond で Microsoft HQ の Customer Experience Team(CXP) というエスカレーションされたインシデントの対応をするチームにいたことがあります。その際にブリッジコールに参加する機会が何回かありましたが、US・インド・ダブリン で展開される 24 時間体制は素晴らしいものでした。どんどん対応する人間が入れ替わっていき、朝になったらどこかのタイムゾーンのチームが問題を緩和している、という風景には非常に驚いた記憶があります。

実際にこのように「一人ががんばらない」仕組みをどのように組み上げられるかが、DevOps を成功させるかの秘訣になるのかもしれません。

ブリッジコールの後は再発を防止し、検出時間を短縮するための修復アイテムの作成と追跡を行います。

クラウドの運用では SLA が設定され、常に信頼のあるプラットフォームを提供することがキーとなります。そのため上記のようなインシデント対応における透明性と上記の対応を行うことがとても重要になります。下記のように透明性を持ったレポートは障害の後に作成されるようになっています。

アラートの設定が検知スピード向上のためのキー

アラートの設定の仕方で、インシデントに対してどのくらい早く対処できるかが変わります。Azure DevOps チームはアラートを見直してきました。

・同じ問題に対する冗長なアラートコメント
・ステートレスなアラートがさらなる混乱に発展

つまり、アラートの柔軟性を Application Insights などで持たせるのは良いが、結局のところ手元に送られてくるアラートがよくわからない 生JSON だったり、「問題が起きています。」だけのコメントがかかれたアラートだったりすると運用上良くありません。アラートを受け取った側はどんなアクションをしたら良いかわからず、よくわからないユーザーが関係ない人をどんどん巻き込んで大ごとになってしまいます。

そのため、Azure DevOps のチームは、すべての警告を ”アクショナブル” つまり、アラートを受け取ったらすぐに何らかのアクションを実行できる形に作り変え、またシステムの実際の問題を表す表現になるように変えました。アラートは緊急性をレシーバーに感じさせるべきで、そのアラートのコメントが間違っている、不明確なだけでそういった緊急性もうまく伝わらなくなってしまいます。

Azure DevOps チームではこの問題を自動で直接責任者にダイヤルできるような仕組みを確立しています。

Azure DevOps チームの最大の成果の1つは、人間のエスカレーションを必要とせずに責任者を自動ダイヤルするために、十分正確なアラートを調整したことです。このためには、ノイズの多い冗長なアラートを排除し、可視化し、アクションが実際に必要となる時期を示すダッシュボードを作ることが必要不可欠です。これによって、2015年2月までに、アラートの精度が40倍向上しています。

インシデントに対応する際の役割

Azure DevOps チームのエンジニアは、Service Delivery Team と共にプロダクション環境に責任を持っています。サービスの問題については24時間365日のオンコール対応(12時間ごとに交互)で、 勤務時間内は5分、コアタイム以外は15分以内に駆けつけることになっています。

責任者は毎週ローテーションをし、ダッシュボードを介して製品アラートを処理します。なお、プロダクション環境へのアクセスに関しては細心の注意を払い、カスタム仕様の保護されたラップトップを介したジャストインタイムアクセスを行っています。

一方で、SREはプラットフォームの問題をハンドルします。フルプロダクションアクセスを持ち、まだ自動化されていないタスクを実行していきます。

デプロイを自動化するなら”完全に”

デプロイに対する “部分的” な自動化は避けるべきです。例えば下記のように1回しか使わないコードものは避けるようにします。

OneNote や email からこのコマンドをコピペして実行することは惨事を引き起こす原因にもなりかねません。日本の場合特にですが、いつの間にか 2 バイト文字のダブルクオテーションになっている、なんてことが起こるかもしれません。Azure DevOps チームも 1 日の成果物を部分的な手動処理によって丸ごと潰したことがあります。

そのため、すべてのコマンドはスクリプト化し、デプロイの成否に関してもモニタリングをしています。

Deployment Dashboard

また、Azure DevOps チームにおけるデプロイメントはカナリアリリースが用いられています。これによって各ステージにおけるクオリティを担保しています。

  1. カナリア(内部ユーザー)
  2. 最小の外部データセンター
  3. 最大の外部データセンター
  4. 国際データセンター
  5. 残りすべて

チーム自律とアラインメント

チームに自律性を持たせ、一緒の方向を向かせることが重要です。

Let’s try to give our teams three things….

Autonomy, Mastery, Purpose

チームに3つのことを伝えましょう…

自律性、熟達、そして 意義

Daniel H. Pink DRiVE より

アラインメントというと日本語に訳すのが難しいですが、みんなが一致団結して同じ目的を共有しているような、状態と言いましょうか。

チームの構成の変更

DevOps のガバナンスのために 開発チームは 組織構造を変更しました。

従来、PM、Dev、Testing だったチーム編成が、PM、Engineering、OPsに変わりました。

その後、チームはさらに統合を進めて下記のように各機能ごとに顧客とエンゲージできるような垂直統合型の組織になりました。

図にして表すと下記のように変化しました。

チームは物理的な部屋を持ち、10~12 人のメンバーから成ります。同一の責任範囲を持つ個人が集まったチームではなく、それぞれ個人の役割はクロスしており、それぞれの組織が自律して管理されます。クリアな12~18 ヶ月の目標を持ち、それぞれプロダクションのフィーチャーおよび、デプロイメントを持ちます。

文化の生成

マイクロソフトでは、ポストイット エクササイズ で チームの自己生成を促しています。これによって正式なインタビューやトップダウンの命令なしにチームを変更する機会が与えられます。これ自体はマネージャー主導でなく、メンバー手動で行われています。またチームが新しいことを学ぶ機会をつくり、才能を交差させることによってミクロな文化を構築させています。

sticky note exercise

プランニング

各チームはそれぞれ違う範囲で責任を持ちます、特に Azure DevOps のチームは Azure DevOps Service、Azure DevOps Server などのサービスを持つ巨大チームで、Azure Pipelines や Boards、TestPlans など様々なコンポーネントを司る PM や エンジニアから構成されています。多段構造になっているツリー構造のチームをまとめる際に、ツリーのトップがアプリケーションの詳細まで追っていたらキリがありません。

責任範囲の分岐は基本的にそれぞれのスプリント単位で決まっていますが、ここも開発チームごとにリリースのタイミングがまちまちであるため、リズムも異なるでしょう。上述した通り、弊社の全てのプロジェクトが 3 週間単位のスプリントになっているわけではありません。

マイクロソフトでは、Ignite と Build という大きなイベントが年に 1 回ずつあるので、Azure の大半の新機能はそこで発表されます。この前の Ignite 2018 では 200 以上のアップデートがありました。多くの Azure のサービスはそうしたリリースタイミングは意識している傾向にありますが、 Azure DevOps は割とコンスタントにアップデートを出しています。

かつて私は Azure 更新情報という Azure のアップデートをひたすら訳していくサイトを運営していましたが、その際にも Azure DevOps は非常にコンスタントにリリースのペースを守っていました。このペースが崩れたこともなかったので、今こういった情報をまとめながら考えてみると、Azure DevOps のリズムの規則性は非常にすごいと感じます。

Azure DevOps のチームではリーダーは全体像を把握して推進していくのに対し、チームは細かい機能単位で責任を持っています。

プランニングはそれぞれ下記のように更新されていきます。 それぞれのプランの粒度は違いますが、更新される規則はきちんと定められています。

これによって何がもたらされたかというと、上述したようなコンスタントなリリースです。いわゆる Waterfall 開発だと、下図の左のようになります。

今の日本の IT 業界だとこのような構造を持つケースが多いと思います。上記のようなリズムをチーム編成や新しいカルチャーの導入、自動化によって作っていくと、図の右のように 3 週間に一回必ず何かの成果物を出すことができるような環境が整います。

ただし、結局のところ、3 週間ごとに何かがリリースできたからといって、そのペースを守ることが目的になってしまうことは避けなければいけません。

Sprint 中のコミュニケーション

では、Sprint 中にはどのようにシンクするか。チームの連携をしていくことがキモになります。
Azure DevOps チームで特筆すべき コミュニケーション方法は以下の 3 つです。

  1. Sprint メール
  2. Teams チャット
  3. エクスペリエンス レビュー

Sprint メール

これはチーム横断的に出されるメールで、Sprint プランと達成した内容を共有するメールです。シェアされるメールには バックログやダッシュボードへのリンク、ユーザーボイスに加えビデオコンテンツなどが含まれます。

Teams のチャット

3つの質問をベースとした会話が行われます。

  1. あなたのバックログで、次は何をする?
  2. 今の債務の状況は?
  3. イシューはあるか?

特定のコミュニケーションチャネル作り、”ロスト イン トランスレーション” つまり、会話の中で特定の議題やコンテキストが失われないように、また取り残された議題がいつのまにか失われてしまわないようにします。これは Microsoft の場合 Teams で行なっていますが、 Slack とかお好みのツールで良いと思います。ただしツールによってはチャネルのスレッドの中で、会話が埋もれてしまうケースもあると思います。チャネルの運用ルールは事前に決めておくと良いでしょう。

エクスペリエンス レビュー

  1. カスタマーエクスペリエンスの ストーリーボードを作成、レビュー
  2. ハイレベルなスプリント実行プラン
    この際、実行プランは時間で決めず、カスタマーエクスペリエンスベースで決めます
  3. フィードバック、フィードバック、フィードバック

これらのトランスフォーメーションのベネフィット

これらの変更によって、それぞれのチーム自体がカスタマーエクスペリエンスを共有し、改善する責任があると感じるようになっています。

チームは継続的に計画をしており、計画は継続的な学習によって推進されています。サービスや特定のフィーチャーの仕様に関しての遠隔測定を怠らず、また高速失敗を繰り返し、そのレビューも早く、継続的にすることで新しい問題に対処できるような環境が揃いました。

シフトレフトのクオリティ

シフトレフト はアプリケーション・ライフサイクルにおいて、デザインとテストの強化によって運用の効率を向上させることです。

バグキャップ (Bug Cap)

Azure DevOps のチームはシンプルな バグキャップというルールに従っています。

エンジニアの数 x 5 = バグキャップ

Azure DevOps チームのバグ数は常に上記に収まるようにしています。
そのため、ルールとしてバグ数がメンバーのバグ上限を超えていたら、この上限に戻るまで新しい機能の開発を中止する必要があります。

例えば、エンジニアの数が 10 人いたとすると、50 がバグキャップです。

10人 x 5 = 50 (バグキャップ)

リリースの直前までに溜まりに溜まったバグをゼロにするように頑張るのではなく、常にバグを最小限に抑え、出口 (リリース時)にバグがゼロになっているように調整します。(ゼロバグバウンス-ZBB )

そもそも Sprint のような短距離走をやっている場合、Waterfall の長距離走のように、最後の1周だけ死ぬ気で力を振り絞って走る、ということができません。そのためバグのキャップを作ってメンテしながら進んでいくことが必要不可欠です。

Microsoft のプロジェクトも最初はバグキャップルールがなく、最後の最後で帳尻を合わせる開発をしていました。例えば TFS 2010 のリリースまでのバグのバーンダウンが下図です。
beta1、beta2、RC、RTM とビルドをしていきましたが、バグフィックスの過程で新しいバグが発見されたり、さらに新しいバグが生み出されていきました。そのため、最後の最後でようやくバグ数が少なくなるようなチャートになっています。

サイクルも現在のように Sprint のような短距離走ではなく Waterfall 的な長距離走でした。下図のようにプランニングをして、コードを書いて、コードが終了したら テストと安定化につとめその後にまたコードを書き始める・・・ このサイクルは変更する必要がありました。

現在はリリースサイクルが安定し、バグキャップも機能するようになりました。CI/CD のプロセスのおかげでもありますが、これも CI/CD を導入したからこうなれただけではなく、上述したような組織構成やカルチャーの変革やバグキャップなどのルールを徹底したおかげでもあります。

統合テストからユニットテストへの移行

Azure DevOps チームでは 統合テストからユニットテストへの移行をしました。

どのように移行したかはブログに詳しく記載があり、公開されています。

これから書く内容も上の記事を参考に要約して書いてある部分がありますので、詳しくは上のリンクをご参考にしてください。

Azure DevOps チームは 継続的デリバリーの目標に対する最大の障害の 1 つがテストであることに気付きました。テストと一言に行っても、テストに関しては組織、ロール、フレームワーク、分析など、様々なことが関連して問題になっています。

ユニットテストに移行する前には何万ものテストがありました。それらはデベロッパーによって書かれたコードをテストするために、テスターによって書かれたテストコードでした。このモデルには、テストの明確さや、測定、制御の容易さ、テスト分野におけるテスターの専門知識およびキャリアの成長など、いくつかのメリットがありました。

一方でデベロッパーに関しては、説明責任の欠如、遅いフィードバックサイクル、開発者が自分たちのコードを「テスト可能」にする動機がない、コードアーキテクチャとテストアーキテクチャのギャップなどが起因してリファクタリングの難易度が上がるなどのデメリットが多くありました。

当時のテストの多くを占めていたのが、エンドツーエンドの機能的な統合テストでした。多くのケースで、それらのテストは UI または CLI における処理を自動化しました。しかし一方で、テストが小さい/表面的な変更に対して非常に脆弱なことを意味していました。

特にUI テストコードの設計は難しく、ランダムなタイミングの問題がしばしば発生し、テストコードには UI が安定状態に達するのを待つために “Sleep(5000)” が散らばっていました。信じられないほど壊れやすいだけでなく、長い時間がかかっていました。

そこで、チームはテストを完全にやり直す道を歩み始めました。上述した通り、開発組織とテスト組織を統合した エンジニアリング組織 を洗ったに作り、コードを書く人とテストをする人の間の区別を排除しました。もちろん、すべての人がそれぞれの同じ量をするというわけではありませんが、すべての人は作り出すものの品質に責任があります。また、8年かけて作成したテストを、まったく異なる方法で新しいテストに置き換えるのに、数万回のテストを完全に捨てることにも着手しました。

チームは、脆弱で遅い UI 自動化テストへの依存を減らす必要があることに気づいていました。そこでさまざまな種類のテストについて考えるのに役立つ分類法を作成しました。

  • L0
    古典的な単体テスト。API を実行し、インストールされている製品には依存しません。そのためテストの内容に定義された状態以外にはなり得ません。
  • L1
    単体テストに似ていますが、SQL Server が環境内にあることに依存できるテストです。VSTS(現Azure DevOps) は SQL Server に非常に依存しているため、単純に SQL をモックしようとすることは懸命な判断ではなく、さらなるカオスを招く可能性があります。また、コードの大部分は SQLServer のストアドプロシージャに入っているので、それもテストする必要があります。
  • L2
    完全に展開されたTFS / Team Servicesの インスタンスに対して作成されるテストです。いくつかの重要な点が模擬されています。モックはテストを単純化し脆弱性を排除するために行われます。例えば、認証をモックアウトすることで、テスト ID の作成、秘密の管理などを処理する必要がありません。
  • L3
    本番 TFS / VSTS(現Azure DevOps) インスタンスに対するエンドツーエンドの機能テストです。ただこれらの多くは UIテスト の自動化です。

基本的には、すべてのプルリクエストの一部として L0 テストと L1 テストを実行します。したがって、すべてのチェックインで多くの検証が行われます。そして一日かけて、L2 のローリングランを実行します。その間の大部分は、テスト対象のインスタンスのインストールと設定です。L3を実行するための一貫したプラクティスは確立されていませんが、展開後を検証するためにすべてのリリース定義の一部として実行される予定です。

最終的には L0 の割合が増えるように目標をたてて移行していきました。

テスト方法の移行の道のりが下記のようになっています。

VSTS(現Azure DevOps) の L0 / L1 / L2 / L3 テストはすべて MSTest V2 を使用しています。1日に最高 450 回実行し、各実行には最高 45300 回のテストがあります。合計1日あたり2,000万回のテストを実行していることになります。

結果

上記を実施することで、Azure DevOps のチームは下記のように変わりました。

  • 4~6 ヶ月のマイルストン ➡︎3 週間のスプリント
  • 水平統合組織 ➡︎ 垂直統合組織
  • 個人オフィス ➡︎ チームルーム
  • 長期間のサイクル ➡︎ 継続的プランニングと継続的学習
  • PM、Dev、Test チーム ➡︎ 1 つのエンジニアリング組織
  • 年ベースのエンゲージメント ➡︎ 継続的なカスタマーエンゲージメント
  • フィーチャーブランチ ➡︎ みんながマスター
  • 20以上のチーム ➡︎ 8~12 人のチーム
  • 秘密のロードマップ ➡︎ 公開されたロードマップ
  • 大量のバグ負債 ➡︎ ゼロ負債
  • 深い組織ヒエラルキー ➡︎ よりフラットな組織ヒエラルキー
  • ソフトのインストール数による評価 ➡︎ ユーザー満足による評価
  • 1 年に 1 度の機能シッピング ➡︎ 毎スプリントでの機能シッピング

この投稿の冒頭では、「Microsoft が定義する DevOps とは」というところから入りましたが、やはり CI/CD だけでなく、継続的モニタリング、プランニング、学習が必要です。また、それらのツールやダッシュボードを手に入れた上でカルチャーを作っていくことも非常に重要だと言えます。

どこから手をつけるのか

自己完結している組織であればあるほど DevOps を実現するのは簡単だと思います。一方で、日本の多くの企業のように多段のレイヤーがあり、IT 子会社にアウトソースしている場合、Dev 企業と Ops 企業がそもそも違うなどの理由で DevOps が実現されなかったりします。

この前、ドイツの同僚に「日本は大企業に内製の文化がなくて DevOps あまり進まないのだけど、あなたの国ではどうしてるの?」と聞いてみましたが、「いや、ドイツも内製していない企業はいっぱいあるよ。だけどプロジェクトチームとして、パートナー企業との壁を取っ払って、場所も確保してv-チームを構成してやっているんだ。そうすると結構プロジェクト成功してアジャイルになるよ」と教えてくれました。

つまり「プロジェクトチーム」として企業間の壁を取り払う必要があり、PM、Dev、スクラムマスターの役割を対等な関係として企業横断の Scrum チームを構成して作業をするのが良さそうです。
しかしそうすると契約形態もおそらく変える必要が出てくるはずです。共同の「プロジェクトチーム」とするには準委任契約の方が適しており、発注する側のある程度の覚悟も必要になります。

また、社内のエンジニアがいないことや、受託開発自体を問題とするのではなく、「丸投げ」という行為を問題とし、きちんと一人一人のロールを決めて、アラインメントを図り、一つの目的に向かっていけば DevOps の実現は近いのではないかと思います。

その前提として、どのようにコミュニケーションをとるのか、ツールを一箇所に固め、チームの土台を作ることが非常に重要になってきます。

Azure DevOps は無料で色々できる最高なツールなので、気になった方はぜひ使ってみてください。非常にオススメです。

私は個人的な利用含め、タスク管理やリポジトリやリソース管理の多くを Azure DevOps でやっています。最高です。

--

--

Yuki Hattori

Architect at GitHub / Board Member at the InnerSource Commons Foundation