目次


考え方を変えてクラウドの能力を最大限に引き出す

第 3 回 経験から学んだ教訓、トップ 11

私たちの経験をクラウド開発プロジェクトで活かす

Comments

コンテンツシリーズ

このコンテンツは全#シリーズのパート#です: 考え方を変えてクラウドの能力を最大限に引き出す

このシリーズの続きに乞うご期待。

このコンテンツはシリーズの一部分です:考え方を変えてクラウドの能力を最大限に引き出す

このシリーズの続きに乞うご期待。

クラウド対応アプリケーションの具体的な特徴と、これらのアプリケーションがアジャイル開発をどのように実現するかを理解したところで、実際のプロジェクトでの課題とそこから学んだ教訓を見て行きましょう。

教訓 1: チームの編成と役割を再検討すること

皆さんは意外に思ったかもしれませんが、これまでの記事で、私たちは開発者とテスターの両方について言及しました。従来の開発プロセスでは、この 2 つの役割は明確に区別されました。それぞれが固有のスキルを持ち、通常は 2 つの完全に異なる、独立した存在として活動し、時には互いに衝突することもありました。

一部の仲間うちでは、開発者は (場合によっては実際の環境、構成、導入パスなどに関する詳細な情報がなくても) 何もないところからモノを作り出し、その動作を定義することができる、神のような存在として見られています。一方、テスターは、コードをおとなしく受け入れて、実際のユーザーや運用チームのスキルにごく近いスキルを持った担当者としてコードの品質を検証する役割として見られることが多いです。

私たちは自分たちのプロジェクトで何年もの間、開発者とテスターをまとめて 1 つのファミリーにしようと、同じ管理系列に置いたり、同じ場所に配置したり、ジョブ・ローテーションを組んだりするなどしてきました。しかし残念ながら、開発者とテスターの間の壁を取り除く方法は見つからなかったのです!

組織の全員が全体論的な視点を持つようになって、各個人がコーディングを行い、テストを実施して、顧客の要件を理解することができれば理想的ですが、そのような状況を短期間で実現するのは容易なことではありません。それは第一に、スキルへの莫大な投資が必要になるためです。

そこで私たちは Spotify や Pivotal などの会社で採用している方法に従い、複数の部隊でチームを編成することにしました。それぞれの部隊は、(製品機能などの) 特定のミッションを担う 6 名から 8 名の小規模なグループになっており、開発者、テスター、情報開発者、デザイナー、そして要件分析と顧客フィードバックの担当者で構成されます。

コードの開発期間中は、開発者とテスターが同席してコードをテストします。このプロセスでは、開発者とテスターの間でのスキルの融合を目にします。現在、私たちチームの開発者はコーディング、ユニット・テスト、そして機能テストを担当しているので、無人で自動的にコードを実行することができます。

教訓 2: 継続的デリバリーにコミットすること

やむをえない妥協が招いた興味深い結果の 1 つとして、差し当たってクラウド・サービス・オファリングを準備している間は、私たちはビルド自動化システムに最も力を入れることに決めました。私たちはすでに、ある種のセルフサービスの手法を用いて製品のインスタンスを生成していました。私たちチームの開発者はこの手法を、製品自体を完全にインストールせずにコードを迅速に検証する方法として使用していました。これは私たちが採っていた DevOps 手法であり、製品のビルド定義の一項目で、特定のコード・レベル (個人用または本番用) と一連の構成パラメーターを選択できるようにしておき、その後で仮想インフラストラクチャーを利用して完全に自動化された無人の方法で、製品のインストールと構成を行うというものでした。

このシステムはとても上手く行ったので、システムをシステム・テストにまで拡張することにして、最も一般的な構成を表す環境をテスターが簡単に起動できるようにし、あまり一般的ではない特定の構成に関してのみ手作業で行うようにしました。

この説明からわかるように、ビルドとテストを行う環境はとても複雑になり、複数のツールが関わってきました。そのため、システムの保守と機能強化だけを専任で担当する部隊を作りました。この部隊のミッションは、ビルドに関するすべての問題を解決することではなく、他のすべての部隊からも使用できる、信頼性と高可用性を備えた継続的デリバリー・パイプライン・サービスを作成し、保守することでした。この継続的デリバリー部隊によって、他の部隊が環境にソース・コードやバイナリーをさらに追加しなければならない場合に使用できるインターフェースが定義されました。

教訓 3: サービスとしての開発環境を構築すること

継続的デリバリーの興味深い側面としては、本番環境さながらの環境でコードを開発およびテストできることも挙げられます。これは、よく知られている DevOps の原則です。

マイクロサービスや完全に疎結合のアーキテクチャーについて考える場合、1 つの特定のコンポーネントまたはマイクロサービスの開発およびテストだけが可能なように極めて単純化された開発環境を思い描くのではないでしょうか。かつて私たちは、手作業によるステップで特定の個人データ (Rational Team Concert の資格情報など) に適応させることが可能な仮想マシンを複製したものでした。これらの仮想マシンには、開発環境を容易に構築するために必要な開発ツール (Eclipse など) とビルド構成のすべてが組み込まれていました。しかし、このプロセスには、自動的に本番環境に似た環境を生成したり、そのような環境に接続したりするための手段はないため、手作業で介入する必要があります。新世代のクラウド・ソフトウェア・ツールは、このような複雑さをほとんど伴わずに開発することができます。それは、これらのツールは、大々的なツール・サポートを必要としないプログラミング言語 (Python、Ruby、Chef、Ansible など) を使用するからです。

私たちは、開発者が目的のトポロジーを指定することや、(OpenStack によって管理される) ベースとなるハイパーバイザー、さらには使用するビルドを指定することができる、セルフサービス・ポータルを提供しており、本番環境に似た環境がゼロから生成されて、追加の仮想マシンがその環境に接続されます。この仮想マシンには、開発に必要なすべてのツールが含まれており、指定されたトポロジーのミドルウェアとインフラストラクチャーを利用するように自動的に構成されます。開発者は自分が使用している Rational Team Concert (RTC) リポジトリーを同期させるだけで、すぐにコードを作成して本番環境さながらの環境に対してテストを実行することができます。

教訓 4: 進捗状況をモニターすること

動的環境では、チームが現在いる地点を認識し、進捗の妨げになっている問題や、未解決の依存関係、進捗の遅延などがないかどうかを把握することが重要です。そのための簡単な手法は、毎日の打ち合わせでホワイトボードを使用して、現在のステータスとあらゆる問題をリストアップして更新するというものです。チームが同じ場所に配置されていれば、ホワイトボードは有効な手法となりますが、そうでない場合は、電子版ホワイトボードを利用することができます。その場合、一連の列に各アイテムのライフサイクル (設計、コーディング、テスト、デリバリーなど) を表示する、かんばんボードのような表現を利用しているツールを使用することをお勧めします。RTC を使い慣れている方は、そのダッシュボード機能を利用することができます。これも、通常のかんばんボードの表現にすぎません。

かんばんボード (IBM Cloud Manager with OpenStack チームの厚意により掲載)
かんばんボードのスクリーンショット
かんばんボードのスクリーンショット

上記のかんばんボードには、内部開発プロセスだけが表示されていて、クラウド上での実際のコードの公開については表示されていません。それは、3 ヶ月ごとの定期的なバイナリー更新に向けてまだ作業中だったからです。色分けは、タスク/欠陥/ストーリーが実際のスプリントで完了する確率を示しています。

  • 赤: リスクあり。おそらく現在のスプリントでは完了しない見込みです。
  • 緑: 順調。現在のスプリントで完了する見込みです。

RTC のかんばんボード・ビューを使用する利点は、進捗を妨げている問題と依存関係についても同じパネルで確認できることです。かんばんボードを定義する際に考慮すべき重要な側面には、タイム・スパンと粒度があります。この 2 つはもちろん、誰を対象に表示するかによって決まります。例えば、部隊自体がかんばんボードを利用するなら、かんばんボードに単一のスプリントを表現し、そのスプリントで処理するすべての項目 (ストーリー、タスク、欠陥) を含めるようにするとよいかもしれません。一方、経営陣に見せるためのかんばんボードであれば、スプリントごとに 1 つの詳細をストーリー・レベルで示すだけで十分でしょう。

教訓 5: 部隊をできるだけ同じ場所に配置すること

世界中に広がる組織では、開発者チーム全体が同じ場所に配置されることはまれなことです。通常はチーム・メンバーが世界中に散らばっているため、簡単にコミュニケーションを取れなかったり、効率性が下がったりします。そこで、私たちはリソースをできる限り集約するために、3 大陸 8 ヶ国のメンバーで編成されていたチームを、1 大陸 3 ヶ国のメンバーになるよう再編成しました (常に部隊を同じ場所に配置して編成できるとは限りませんでした)。

この再編成により、たちまち品質と生産性に違いが表れてきました。

  • テスターと開発者が同じ場所に配置された部隊では、実際に同じデスクにいるメンバーと共同作業するようになったことから、新しいコードを短時間で生成して直ちにテストし、問題を素早くデバッグできるようになりました。チーム・メンバーの間では同じプロジェクトに属しているという連帯感が生まれ、メンバー全員が成功または失敗を分かち合うのだと感じるようになりました。
  • 一方、メンバーが同じ場所に配置されていない場合は、メンバー間に壁があるような行動が見られました。例えば、「これは私のコードなので、私の作業が終わってからでないと、あなたはこのコードを確認できません」、「欠陥をオープンしたので、その欠陥を修正し、私がそれを検証できるようになったら知らせてください」といった言動です。

私たちは、リモートでのやりとりを容易にするためのツールを使用していました。例えば、開発者に自分たちの環境で共有セッションを開始させて、テスターがそこに接続してやりとりできるようにしていたのです。その結果、テスターは 1 時間以上作業に集中できなくなり、周りで起こっていることに気を取られるようになりました。同様の問題は、テスターが欠陥を見つけて、それをすぐに開発者に見せたいと思ったときにも持ち上がりました。開発者からは「後に回せませんか?今すぐ確認することはできないので、欠陥をオープンしておいてください。」という返事が返ってきます。従って、私たちが推奨するのは、部隊をできるだけ同じ場所に配置することです!

教訓 6: ミッションを完了すること

各部隊にはミッションが与えられます。私たちのケースでは、各部隊のミッションは、製品所有者が顧客の意見と要望に基づいて決定します。ミッションとなるのは通常、新しい機能または新しい機能の強化です。部隊は、ミッションを完了する方法に関して技術的決定を下す役割を担っています。部隊は外部インターフェースに対して完全に自律しており、共通の製品目標に向けて努力しながら、小さな新興企業のように活動します。

原則的に、スプリントの期間をどれぐらいにするべきか、どの開発ツール、テクノロジー、プログラミング手法を使用するべきかは、部隊が決定することができますが、実際のところ、大規模な組織では部隊ごとに異なる開発環境を使用するだけの余裕はなく、さらにスプリントの期間がまちまちだと、保守や追跡が悪夢のような作業になってしまう可能性があります。

例えば私たちは、始めは 2 つの異なるコード・リポジトリー (Git と RTC) を使用していましたが、自然の成り行きで、部隊間での相互作用と浸透を促すためにリポジトリーを 1 つ (RTC) に統合することにしました。

スプリントの期間については、2 週間が最も効果的な時間枠であることがわかりました。1 日目は設計、計画、他の部隊との同期に費やし、続く 4 ~ 5 日間で開発を行います。残りの時間は、高度なテスト、欠陥の修正、ドキュメントの改善に充てます。最終日の数時間は、利害関係者に進捗状況をデモするために確保しておきます。

ここで大きな課題となるのは、自律性に責任を伴わせることです。従来の開発プロセスより遥かに大きな自由が許されるものの、それと同時に、顧客と直接向き合うことにもなります。いずれかの部隊が作り出した最も低いレベルのコードが、製品全体のレベルになります。

理論的には、各部隊が独自のタイムラインとデリバリー期限を管理し、複数の部隊の間で共通の目標を達成するために作業を同期させます。重複する作業や保守を回避する目的で、私たちは継続的デリバリー・インフラストラクチャーを担当する特別な部隊を指名することにしました。この部隊のメンバーが、ビルド、パッケージ、そして自動化されたテスト・インフラストラクチャーが常に稼働状態であることを確実にします。すると、各部隊がそのインフラストラクチャーを拡張したり、ツールを追加したりして、特定のニーズを満たします。要するに、この継続的デリバリー部隊は、他の部隊がコードをビルド、テスト、デリバリーできるようにしているのです。

教訓 7: スキル・トランスファーを計画すること

各部隊のすべてのメンバーが開発とテストの両方を担当できるのが理想の世界ですが、これは現実的ではありません。この考えを念頭にゼロからチームが作られたのでなければ、なおのこと現実的ではありません。実際には、より従来型の開発プロセスに慣れている人々に頼らざるを得ません。つまり、自分が作成する一部のコードしか目に入らない開発者と、製品の構成と統合に熟練しているものの、コードを作成する準備ができていないテスターです。

この問題を克服するには、スキル・トランスファーを計画する必要があります。短時間で開発者とテスター両方のスキルを高める最善の方法の 1 つは、開発者とテスターをペアにしてプログラミングを担当させることです。最初は、開発者が主体となってコードを作成し、テスターがそれをすぐにテストして、考えられるシナリオを提案します。そのうちに、テスターはコードを理解する方法を学び、コードを見るだけでバグを発見できるようになり、開発者は製品を構成する方法を学んで製品全体を理解できるようになります。最終的には、テスターと開発者の区別がつかなくなるはずです。

もちろん、新しく採用したメンバーに早くスキルを身に付けてもらう目的でも、この手法を用いることができます。ご想像のとおり、このプラクティスが最も効果を発揮するのは、メンバーが同じ場所に配置されている場合です。

教訓 8: 部隊の各メンバーに権限を持たせること

小規模なチームにミッションを与え、そのチームはミッションを完了する方法を理解し、その部隊が設計から、本番へのデリバリー、そして保守に至るまで、作成したコードのライフサイクル全体を所有するように、開発プロセスを変更するには、多くの規律が必要となります。

このような開発プロセスでは、開発者、テスター、サポート・エンジニアの区別がなくなり、部隊の各メンバーがコードを作成し、テストを行い、製品を保守します。それぞれのメンバーには、コードを変更してビルドする権限が与えられます。部隊は通常 6 人~ 8 人で構成されるため、何もかもがあからさまになります。毎朝、チームで現在の問題のリストを分析し、最初に達成/解決しなければならないタスク/問題を、最初に手の空いたメンバーが担当します。

チームの中で 1 人のヒーローに注目が集まることはなくなり、チーム全体の結果だけが重要になります。あるメンバーの作業が遅ければ、チーム全体の作業が遅れます。コードが機能しなければ、それはチーム全体の責任です。メンバーのそれぞれが、コードのあらゆる部分を扱えなければなりません。そうでないと、上記のモデル (最初に手の空いたメンバーが、リストで次に処理可能な項目を担当するモデル) は失敗してしまいます。従って、セッションの計画はメンバー全員を考慮して行う必要があります。特定の 1 人のメンバーの作業スピードではなく、チーム全体の平均スピードに基づく見積りでなければならないためです。チームで効率的に作業できないメンバーは、自然と孤立していきます。

教訓 9: テストおよびテスト自動化に関して手を抜かないこと

私たちのプロジェクトでは、従来の開発チームをアジャイル指向の継続的デリバリー・チームに変容させるという課題に直面しました。当初、すべての問題の原因は、誰もが嫌がっているものの誰も変えようとしない、時間のかかるビルド・プロセスにありました。ビルド・プロセスが最適化されて、その所要時間が 80% 短縮された後、真の問題が明らかになってきました。それは開発者が、コード開発に取り掛かる方法をテスターに教える時間を 1 分たりとも割こうとしないことでした。これが、チームの生産性のボトルネックとなっていました。その結果、単純なテストを開始する場合でも、透過的な情報フローがないため、テスターは時間を無駄に過ごしていたのです。

障壁となっていたのは、同じ場所に配置されていないことでも、スキルが欠けていることでもなく、新しいプロセスに関する理解の欠如と、協力しようとしない姿勢でした。多くのチーム・メンバーは、スプリントの終了時にデリバリーするコードが利害関係者を満足させるだけの量に達していないことに不安を感じるため、テストされていない、品質保証がゼロの大量のコードが作成されます。このようなコードは、何週間も本番に移すことができません。「どうして自動化したテストを作成しないのか?」と聞かれると、私たちは「時間がない!」と答えていました。私たちが直面した精神面での最大の問題は、デリバリーする量が十分でないという不安と、ソフトウェアのテストは副次的なアクティビティーであるという考えです。

チーム・メンバーは、自分たちの時間は自分たちで支配していること、そしてテストされていないコードは、存在していないのと同じであることを理解する必要がありました。テストされていない 500 のクラスがあるより、十分にテストされた 1 つのメソッドを用意したほうが良い結果を招きます。何回かのスプリントを経ると、弁明の余地なく、チームのスピードは利害関係者に明らかになってきます。

当初、私たちのスプリントの期間は 2 週間でした。これは、私たちは規範的でなければならないことを意味していました。2 週間のスプリントでは、コードの作成には 4 日間しか費やすことができず、残りの時間は、計画、レトロスペクティブ、テスト、テスト自動化の作成、欠陥の修正、ドキュメントの作成に必要でした。チーム全体での感じ方は非常に悪く、開発者たちは十分に生産性を上げられなかったと感じました。彼らは本当であれば、スプリントの最終日までコードの作成を続けたかった (しかしそうすると、全体的な品質が低下します) のです。

教訓 10: 早いうちに失敗して素早く学ぶこと

前進する上での重要なステップは、開発者を現実の世界にさらすことでした。私たちは、開発者に 2 週間ごとに何らかのコードを本番へ移行するよう要求していました。各部隊は、毎回スプリントが終了する時点で、実際に稼働している本番システム上で、新しい機能をデモしなければなりませんでした。何もデモするものがなければ、それは何も達成しなかったことを意味します。この決まりがきっかけとなって部隊間に健全な競争心が生まれ、何度か失敗はあったにせよ、最終的にはこの手法が有効であることがわかりました。

この手法によって、チームは早いうちに失敗する方法を学んだのです。各スプリントの終わりに何らかの成果を披露することができれば、ネガティブなコメントを受け入れて、次のスプリントを開始することができます。つまり、失敗で時間を無駄にするのはそのスプリントの期間に限られるということです。

教訓 11: 他の部隊を支援すること

私たちが克服しなければならなかったもう 1 つの精神的な障壁は、コードの所有権と部隊間の依存関係の扱いです。開発者は特定のコンポーネントの自分が担当する特定のコードだけを触っていたことから、自律部隊を結成するという概念によって、開発者のコード所有権に対する意識が一層強まりました。「部隊は自律しているので、自分のコードは自分の部隊以外は誰も見たり触ったりできないよう制限しても差し障りない」という考えです。この考え以上に悪いものはありません!自律が意味するのは、「孤立」ではありません。

実際、目的の機能を短時間でコーディングしたいのに、依存している他の部隊のコードがバックログに埋もれているとしたら、一番確実な方法は、自ら積極的に他の部隊のコードに必要な変更を加えることです。こうすることが、長期的にはデリバリーを加速させ、チームで協力して作業する雰囲気を高め、製品コード全体の知識を強化することになります。

まとめ

このシリーズの第 1 回では、クラウド対応ソフトウェアは、通常の Web アプリケーションとどのように異なるかを説明しました。第 2 回では、クラウド対応アプリケーションの特徴が、本番に向けた機能の継続デリバリーによる真のアジャイル開発を促進する理由を説明しました。最終回となるこの第 3 回では、実際のプロジェクトでの私たちの経験を基に、プロセスで直面する可能性がある課題と、そのような障害を克服するのに役立つ教訓とベスト・プラクティスを説明しました。


ダウンロード可能なリソース


関連トピック


コメント

コメントを登録するにはサインインあるいは登録してください。

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=60
Zone=Cloud computing, DevOps
ArticleID=1028996
ArticleTitle=考え方を変えてクラウドの能力を最大限に引き出す: 第 3 回 経験から学んだ教訓、トップ 11
publish-date=04072016