単なる自動化ツールを超えて
さて、ここまではCI/CDとは何か、何ができて、どんなメリットがあるかを見てきました。ここからは一歩進んで、CI/CDを活用することで、私たちのソフトウェア開発がどのように変わるかを見ていきましょう。大げさに聞こえるかもしれませんが、CI/CDはソフトウェア開発を行う組織(!)そのものまで変えてしまう大きな力を秘めています。ここからは、単なる自動化ツールを超えて、CI/CDがどのような影響をソフトウェア開発に与えるかを見ていきましょう。
継続的デプロイ
その前に一度、用語のおさらいをしましょう。まず大事なことは、継続的インティグレーション(CI)や継続的デリバリー(CD)の厳密な定義はありません。使う人や文脈によって意味が変わってきますが、一般的に継続的インティグレーションとはコードの変更を常に自動でテストすることを意味します。継続的デリバリーとは、テストをパスした変更をいつでも本番環境へリリース可能な状態にしておくことを意味します。しかし、CI/CDにはその先があります。それが「継続的デプロイ」と呼ばれるもので、テストをパスした変更を自動で本番環境へデプロイすることでリリースの自動化を行います。
継続的インティグレーションにより、ある変更がテストに通らなかった場合、その変更に問題があったことが瞬時に分かるようになります。言い返せば、テストをすべてパスした変更はリリースしても安全だということが分かります。
補足
もちろん現実はそんなに単純ではありません。すべてのシナリオに対してテストがあるわけではないですし、仕様バグなどはCI/CDを使っても取り除くことはできません。
こうなれば、複数の変更をまとめて一気にリリースしなくても、テストをパスした変更から順次本番環境へリリースしていくことができるようになります。
かなりレベルの高い開発チームでも継続的デプロイまで行っているチームはまだまだ少ないように思います。何年も前にAmazonは1日に最大1000回デプロイする、という話が話題になりました。この時からAmazonはCI/CDをいち早く活用して継続的デプロイをしていたようで、流石というしかありません。
継続的デプロイをすることで以下のようなメリットがあります。
- バグの迅速な修正
- リスクマネージメント
- 変更に対するフィードバックを素早く得る
バグの迅速な修正に関しては特に説明がいらないと思うので、ここでは残りの2つについて解説していきます。
リスクマネージメント
ソフトウェア開発に限らず、リスクマネージメントで大事なことは、発生する可能性のある問題を修正可能な範囲に抑え込むことです。つまり、問題が発生することをあらかじめ考慮して、もし発生したとしても対応可能なように計画を進めるということです。
例えば、2つの変更、AとBをリリースする場合を考えましょう。Aの変更量は3、Bは5とします。同じ内容の変更をまとめたCは8です。変更量の合計値はどちらも8ですが、別々にリリースして問題が発生した場合、AとBは個別に対応することができます。それに対し、Cは8の変更に対して一度に対応しなくてはいけません。仮に6以上の変更は複雑すぎて容易にロールバックできないとすると、最悪両方の変更に問題があったとしても、個別にリリースした場合は対応可能ですが、両方一緒にリリースした場合は対応ができません。リスクマネージメントの観点で考えると、AとBを別々にリリースしたほうが賢いと言えます。

前置きが長くなってしまいましたが、CI/CDによる継続的デプロイは前者のリスクマネージメントを可能とします。継続的デプロイができるということは、言い換えれば変更のロールバックも簡単にできるということです。問題があった変更点を取り消して再度デプロイすれば簡単にロールバックしたことになりますからね。重要なのはロールバックできる単位を小さくすることであって、デプロイのタイミングではありません。AとBを同時にデプロイしても、個別にロールバックできれば問題ありません。
この手法を使えば、別々の開発者がAとBを同じタイミングでデプロイしても、お互いが自分の修正に責任を持てれば、Cと同じビジネス価値(変更)をリリースしたことになります。同じビジネス価値なのにリスクは少ない、これがリスクマネージメントの力と言えます。
ロールバックという撤退戦略があるおかげで、開発者の仕事は劇的にやりやすくなります。仮に自分の変更に問題があったとしても、ロールバックすればいいだけなので、より創造的にコードを書くことができるようになります。もちろん、コードレビューをおろそかにしたり、見切り発車を推奨しているわけではありません。ここで言いたいことは、変更の粒度を小さくしてバグのリスクを下げることができれば、必要以上にバグを恐れる必要はないということです。筆者にとってこの"間違ってもいいんだよ"という考え方はCI/CDを通して学んだ最も大事な考え方となりました。
フィードバックを素早く得る
スタートアップビジネスに関する名著『リーン・スタートアップ』には、いかに効率良く最低限の機能を持った試作品を作り、顧客からフィードバックを得るかがスタートアップビジネス成功の鍵だと書かれています。まったく同じことがソフトウェア開発でも言えます。つまり、MVP(実用最小限の機能)を作り、それをリリースして、フィードバックを得る。このループを素早く繰り返すことで、ユーザーが本当に求めるプロダクトを効率的に開発できるようになります。
もっと極端に言えば、多少不安要素がある機能でもどんどんリリースして本番環境でテストする、くらいの気持ちが重要だと個人的には思います。もちろん、人命が関わったりするような間違いが許されないソフトウェアもあります。しかし、そうでない分野では入念なテストよりもいかに素早く機能に対するフィードバックを得て改良するかが重要となってきます。
"フィーチャーフラグ"という言葉をご存知でしょうか? テストしたい機能にフラグを設けて、それを外部からON/OFFにすることでその機能を見せたり、隠したりを簡単に実現する方法のことです。この方法を導入すると、ユーザーにとって価値があるかどうか分からない時でも本番環境でテストすることにより、フィードバックを素早く得ることができます。"本番環境でテスト"とはなんとも恐ろしい言葉に聞こえるかもしれませんが、10の仮説をテスト環境で検証するよりも、1度のリリースをして本番環境で検証するほうが効率的な場合は多々あります。何度もいうようにも、継続的デプロイができれば、簡単にロールバックできます。ロールバックの速さではフィーチャーフラグには一歩譲りますが、継続デプロイを使うことで本番環境からより早くフィードバックを得ることができるようになるのです。

素早いフィードバックループについてはそれだけで一冊の本が書けてしまうくらい重要なアイデアです。プロダクト開発だけではなく、組織の構成そのものも変えてしまうほどの力がありますが、話が抽象的になってしまうのでここでは取り扱いません。興味がある方は「Continuous Development Will Change Organizations as Much as Agile Did」などの記事を読んでみることをおすすめいたします。
まとめ
なぜ今CI/CDが注目されるのかが、分かっていただけたでしょうか? CI/CDを使うことでさまざまな作業を自動化できるだけではなく、デプロイとロールバックを自動化することでより効率的なプロダクト開発ができるようにないます。
さあ抽象的なCI/CDの話もそろそろ終わりにしましょう。読者の多くの方は、実際にCI/CDを設定するのか知りたくてウズウズされているころかもしれません。次回はクラウド型の代表サービスの一つである「CircleCI」を使って、もっと具体的にCI/CDの機能を見ていくのでご期待ください。
