継続的インテグレーション、デリバリー、デプロイメントの違い

しばらくの間ソフトウェア開発に携わってきたのであれば、CI/CDという言葉に出くわしたことがあるでしょう。

継続的インテグレーション、継続的デリバリー、継続的デプロイメントはどれも、フィードバックループを短縮し、反復作業を自動化することによって、ソフトウェアのリリースプロセスを加速化することを目的とした手法です。 正しく動作する価値の高いソフトウェアを頻繁にユーザーに提供するアジャイルの原理を実現する上で、これらの手法は重要な役割を果たしています。

独自のテンポをつかみ、定期的なリリースサイクルを支える CI/CD ツールとプロセスを確立しているチームの自信の源は、十分に機能するCI/CDパイプラインにあります。開発者自身の環境と開発者が製作している最終製品を改善するツールを使用している兆候です。

ところが、この手法を初めて採用する人にとっては、ビルド、テスト、そしてデプロイメントのプロセスを自動化されたシステムに変容することは、面倒で達成不可能に思えるかもしれません。 でも、必ずしもそうであるとは限りません。 CI/CDパイプラインの構築は、パイプラインを個別のステージに分解して、分解したステージをその前のステージの上に構築していくことで成り立っているからです。 それでは、それぞれのステージを見ていきましょう。

CI と CD の違いと、それぞれの主な特徴を見てみましょう。

継続的インテグレーション、デリバリー、デプロイメントの違い

継続的インテグレーションとは?

継続的インテグレーションは、従来的に「インテグレーション」中に少しずつ頻繁に行われていたステップを、コードが完成してからすべてを集めてテストするのではなく、開発プロセス全体で実行する手法です。

ソフトウェア製品に携わる人員は複数いると仮定した場合(ほとんどの商用ソフトウェアやオープンソースソフトウェアでは普通です)、ある時点で、各開発者が担当していた部品を合わせて、最終的な結果が目標通りに動作することを確認する必要があります。 継続的インテグレーションの場合、このプロセスは1日に少なくとも1回発生します。

その理由は単純です。 すべてのコードが記述されてからインテグレーションを実施する場合、ソリューションをビルドする上でコードをセクションごとに解いて書き直し、意図したとおりに動作するための作業に膨大な時間を費やさなければいけなくなる可能性が十分にあるからです。 コードは複雑です。 あらかじめ詳細に設計していた場合でも、ロジックが実際にどのように相互作用するのか予測して、あらゆる課題を回避することは非常に難しいのです。 コードの量が多いほど、複雑さも高まるため、何かが動作しない場合にはさらに多くのセクションを確認しなくてはなりません。

継続的インテグレーションでは、開発者は変更をソースコントロールに定期的(1日1回など)コミットすることで共有し、ソリューションが正しくビルドされ、テストに合格していることを確認することができます。 つまり、何らかの障害が発生した場合は、問題の原因を特定するために、はるかに少ない数の変更を確認すればよいのです。 フィードバックを素早く、作業内容の文脈を覚えている間に得られることも、課題の修正がより簡単に行えることにつながります。

適切なCIプロセスには、次のようないくつかの基本要素が必要です。

ソース管理の使用

ソース(またはバージョン)管理システムは絶対に不可欠です。 ソースコントロールシステムがない場合、またはコードの一部のみがソースコントロールの配下にある場合は、まず、すべてをソースコントロールに含めて、すべての人が使用するようにする必要があります。

早期にコミット、頻繁にコミット

ソースコントロールを使用し始めたら、早期かつ頻繁にコミットする習慣を付けましょう。 ここではタスクのサイズが影響します。作業内容をより小さな塊に分解すると、タスクを完了させて、変更内容をコミットできるようにローカルでテストしやすくなります。

コミット上にソリューションをビルド

プロジェクトの担当者とコードの変更を定期的に共有することが第一歩です。 次に、ソリューションが最新の変更を使ってビルドできるかどうかを確認します。 この作業は手動で行うこともできますが、ビルドを自動的にトリガーできれば、はるかに簡単で効率的です。ここで使用できるのがCIサーバーです。

テストを自動化

ビルドが正しく動作することは良い兆候ではありますが、さらに自信を持つには、複数のテストを実行しなければなりません。 ここでもまた、テストを手動ではなく自動的に実行できれば、より簡単で効率的です。 自動テストの作成には膨大な作業が要するように思えますが、素早いフィードバックを得るためにビルドごとに実行するようになれば、すぐに作成した甲斐が見えてきます。

フィードバックに耳を傾ける

テストから戻される情報を使わなければ、ビルドとテストを自動化する意味がありません。 CIツールには、ダッシュボードやラジエーターからインスタントメッセージングプラットフォームとの統合まで、さまざまなフィードバックメカニズムが備わっています。

DevOpsカルチャを作る

継続的インテグレーションのメリットを本来の意味で引き出すには、チーム内の誰もが破損したビルドや失敗となるテストの修正を職務とするチームカルチャを作る必要があります。 最後にコミットした人に責任を押し付けるのであれば、チームは早期かつ頻繁に変更をコミットしたくなくなり、非建設的です。チームのためになりません。

上記のすべての要素を採り入れることで、コードに対するフィードバックを素早く敵的に得られるようになります。 バグ修正や新機能または一部のリファクタリングにせよ、コードベースへの変更から少なくともテストに合格するクリーンなビルドを得られるようにしておけば、不良の土台に新しい作業を構築して作業のやり直しをやむなくされることを回避できます。 継続的インテグレーションを独自に実装することが、正しく動作するソフトウェアをユーザーに提供するプロセスを加速させる大きな第一歩です。

継続的デリバリーを理解しよう

継続的デリバリーは、継続インテグレーションで確立したビルドとテストの自動化を基礎に構築されます。

継続的デリバリーでは、ソフトウェアのビルドを本番にリリースするために手動で行っていたステップを自動プロセスで行います。

以前は、開発者からテスター、そしてテスターからリリースマネージャーへとハンドオフされていましたが、継続的デリバリーでは、チーム(さまざまな分野からの参加者が含まれることがあります)が製品のビルド、テスト、そしてリリースの全プロセスを所有することになります。 これには、次のようないくつかのメリットがあります。

  • 従来のサイロ方式を避けることで、開発チームが、製品をユーザーに提供する際のビジネスやオペレーションのニーズをより理解できるようになります。
  • このため、通常は手動で、多くの場合に非常に長期的であったプロセスに開発手法を取り入れる機会が生まれます。
  • 製品をライブにするために伴うステップを自動化することで、プロセスを加速できるだけでなく、エラーのリスクを軽減し、より安定性のある信頼の高い製品にすることができます。

ソフトウェアをユーザーに提供する際に伴う実際のステップ、そしてデリバリーパイプラインで必要となるステージは、ビジネスとユーザーのニーズによって異なりますが、製品がリリースされる前に、少なくとも1つの本番前環境にデプロイするのが一般的な手法です。

こういった環境は、セキュリティテスト、負荷テスト、およびパフォーマンステストなどの追加のテストレイヤー用のテスト環境であったり、サポートチームや営業チームが新機能を習得するためのサンドボックス環境であったり、QAや製品担当者が変更が意図されたとおりに動作するかを確認する承認テスト環境であったりします。

継続的デリバリーでは、正しく機能するそれぞれのビルドは、それぞれの本番前環境に自動的にデプロイされ、各ステージで品質が高まることを確信することができます。

これは、手法に投資する必要のある価値の高い目標です。

一度だけビルド

同一のビルドアーティファクトがパイプラインの各ステージで昇格されていくだけで、その前のすべてのテストステージをクリアしたという自信が持てます。

構成をソースコントロールに格納

すべての構成ファイルをソースコントロールに格納しておくことで、一貫した、反復可能なデプロイメントを確実に行えます。

デプロイメントを自動化

各環境へのデプロイメントは、毎回まったく同じ方法で自動的に実行されるように、スクリプト化されている必要があります。 ライブへのリリースも同じ理由でスクリプト化されている必要がありますが、継続的デリバリーでは、この最終ステップは自動で行われません。

環境をクリア

完全に一貫したアプローチを得るには、新しいデプロイメントのたびに環境そのものを同一の条件にリセットする必要があります。 これは、コンテナーを使えば、ローカルインフラストラクチャかクラウドのいずれかでの実装がはるかに簡単に行えるようになります。

環境に関するものは分離

同一のアーティファクトをそれぞれの環境に自動的にデプロイするために、アプリケーションそのものと環境固有の変数やパラメーターを明確に分離しておく必要があります。

パイプラインのメンテナンス

継続的インテグレーションと同様に、メンテナンスできるのであれば、自動デリバリーパイプラインに投資することをお勧めします。 CI/CDは、プロセスやツールだけでなく、チームカルチャにも大きく関係しています。 効果を発揮するには、チームが責任を持ってパイプラインをメンテナンスし、課題が浮上すればそれを修正する必要があります。コード内のバグによる課題であろうが、自動デプロイメントまたはテストの問題であるかに関係ありません。

継続的デリバリーでは、ソフトウェアの提供に関する責任はチームにあり、全プロセスを通じて適時に提供されるフィードバックを活用するのもチームです。 継続的インテグレーションと同様に、この手法も長期的に構築して改善していくことができます。

継続的デプロイメントの説明

継続的デプロイメントは、継続的インテグレーションとデリバリーの論理的な最終作業として、

ビルドがパイプライン内の前のステージをすべてクリアしていれば、自動的に本番にリリースします。 つまり、ソフトウェアへの変更がすべてのテストに合格すれば、ユーザーに提供されることになります。 継続的デプロイメントは、変更の品質を妥協することなく実世界での動作に関する情報を適時にチームに提供することで、コード変更から本番での使用までのフィードバックループを短縮することができます。

すべての製品や組織でソフトウェアを本番にデプロイするプロセスを自動化することが適しているとは限りませんが、個々の要素にはそれぞれの有効性があるため、それを達成するまでに必要なステップを検討する価値はあります。

テストに自信を持つ

本番に自動的にデプロイするには、パイプライン、特に自動テストに対する高い自信が必要となります。 チームがテストカバレッジとパフォーマンスに取り組み、新機能よりもビルドとパイプラインの修正を優先できる、素晴らしいテストカルチャが不可欠です。

本番を監視

上述したすべての手法を取り入れても、継続的デプロイメントにはリスクがあると感じられるかもしれません。バグが検出漏れして本番に組み込まれてしまったら?と考えてしまうでしょう。 時間、コスト、評判が危険にさらされてしまいます。 手動デプロイメントにおいても同じ問題が存在するわけですが、ショーストッパーとなる機能が「システム」によって自動的にリリースされてしまえば、関係者の自信も失われてしまいます。 そこで、バグレポートが提出される前に積極的に障害の兆候に目を見張ることが非常に重要です。 特にリリース直後の異常を計測した情報を監視しておくことで、ユーザー側で深刻化する前に課題を知ることができます。

リリースするものを選択

継続的デプロイメントの経験がない場合、開発者が早い段階で頻繁にコミットすれば、手動管理がなされていない状態のコードが提供されてしまい、ユーザーは機能が使用できる状態でない、未完成または生焼けの状態で提供されていると感じるのではないか、という共通した意見があります。 ブランチに頼って継続的インテグレーションのメリットを逃すのではなく、機能フラグを使用することがソリューションと言えるでしょう。 そうすれば、開発者がコードを記述する際に、ユーザーに見えるものと見えないものを管理できるようになります。

パイプラインを合理化

本番で実際に問題が起きた場合は、迅速に対処できることが重要です。 リリースを前のバージョンにロールバックすることも可能ですが、 多くの場合、それほど単純なことではありません。既知の課題に対してはデータベースの移行と修正で回避することは可能ですが、深刻化すれば、修正を公開するしか、対処方法はありません。 パイプラインのステップを省略すれば、テストを通常通り実行していれば検出できたはずの課題が導入される可能性が高まるため、不経済です。 そこで、省略するのではなく、ビルド速度からテストパフォーマンスまで、パイプラインを合理化することに取り組むのが賢明です。 これは、必要なときに変更をすばやくデプロイできるだけでなく、プロセス全体のフィードバックループを短縮できることにも繋がります。

ロールアウトを管理

継続的デプロイメントとは、前のステージにすべて合格していれば自動的にリリースすることではありますが、だからと言ってすべての管理を諦めるというわけではありません。 リスクを最小限に抑えてロールアウトを制御するために使用できるデプロイメント手法には様々なものがあります。 カナリアリリースでは最初に小規模のユーザーグループにのみ機能をテストさせることができ、ブルーグリーンデプロイメントでは新バージョンへの移行を管理することができます。

継続的インテグレーション、継続的デリバリー、および継続的デプロイメントはすべて、価値の高い機能ソフトウェアをユーザーに頻繁に提供する目標を達成する手段です。 インテグレーションとリリースを少しずつ頻繁に行えば、プロセスをさらに管理しやすくなります。このステップを定期的に実行することで、チームはプロセスに徐々に慣れていくでしょう。

プロセスに自動化を含めると、プロセスを加速させられるだけでなく、信頼性も高まります。 パイプラインの各ステップは前のステップを土台にビルドされるため、ある特定の時間にどれくらいの期間を設け、後でビルドしていくのかを決めることができます。

CI と CD の重要な相違点

継続的インテグレーションとデリバリーとデプロイの比較

継続的インテグレーション、デリバリー、およびデプロイは、ソフトウェアデリバリープロセスの一連のステージです。 チームがより短期間でソフトウェアをリリースし、フィードバックループを短縮し、反復タスクを自動化する役割があります。 継続的インテグレーションとデリバリーとデプロイの大きな違いを特定することは、これらのステップが相互にどのように作用して、確実かつ安定してユーザーにソフトウェアを提供できるのかを理解するのと同じくらい重要なことです。

継続的インテグレーションは、新しいコード変更をメインブランチにマージする手法です。 継続的デリバリーは、ソフトウェアをビルドしてテストするのに必要な手動タスクを自動化します(テストの自動化など)。 継続的デプロイは、ビルドとテストのステップを自動化する手法の論理的な延長であり、このステージにおいて、すべての必要なチェックポイントに合格すれば、ソフトウェアが自動的にデプロイされます。

まとめると、CI と CD の比較ではなく、安定性と信頼性に優れたパイプラインを得る上でこれらすべてのコンポーネントが一体となってどのように機能するかと言うのがポイントです。