検索
ニュース

CI/CDパイプラインで知っておくべき「9つの要素」 一般的な記事のおよそ5倍の大ボリュームで解説基礎知識からメリット、課題、具体例にベストプラクティスまで

TechTargetは「CI/CDパイプラインについて知っておくべきこと」に関する記事を公開した。CI/CDパイプラインとは、近代ソフトウェアのビルド、テスト、リリースの明確な取り組み方法を提供することを目的としてソフトウェア開発のワークフローとツールセットを形式化するものだ。

Share
Tweet
LINE
Hatena

 TechTargetは2024年9月4日(米国時間)、「CI/CDパイプラインについて知っておくべきこと」に関する記事を公開した。CI/CD(継続的インテグレーション/継続的デリバリー、または継続的デプロイ)は、組織の効率を大きく向上させる可能性があるが、実際には多くの要素を考慮する必要がある。

画像
CI/CDパイプラインについて知っておくべき全てのこと(提供:TechTarget)

 近代のソフトウェア開発の鍵となるのは“スピード”だ。従来のウオーターフォール型の開発モデルでは、プロジェクト全体を一度にリリースする「モノリシック」な方式が主流だったが、現在では迅速な反復を重視した「アジャイル」「DevOps」「継続的インテグレーション」「継続的デリバリー」「継続的デプロイ」などの手法が主流となっている。

 各手法にはわずかな違いはあるが、いずれも継続的な反復に重点が置かれており、開発の在り方や効率に大きな変革をもたらしている。これによって、企業は新しい機能やアーキテクチャを低リスク、低コストで試しつつ、市場への投入速度を向上させ、製品を段階的に改善できるようになった。

 こうした反復的手法を成功させるには、十分に計画されたパイプラインが不可欠だ。CI/CDパイプラインは、開発サイクルのさまざまなフェーズで複数の反復(イテレーション)を同時にサポートし、開発チーム全体が時間のロスなく機能するように設計されている必要がある。例えば、完成に近いビルドがステージングや本番環境にリリースされている一方で、別のバージョンのテスト、検証が行われており、並行して別のバージョンの初期的な開発が進み、さらに将来的なビルドに向けた設計が進行している、といった具合だ。

 本稿では、CI/CDパイプラインについてメリットや課題、ベストプラクティスなどについて詳しく説明する。紹介するのは以下の9項目だ。

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

 CI、つまり“継続的インテグレーション”は開発パイプラインの初期フェーズに重点を置いている。このフェーズでは、コードへの変更が成果物(アーティファクト)に組み込まれると、そのアーティファクトのテストを自動的に実行する。CIのおかげで、複数の開発者が、同じコードベースで同時に作業し、コードリポジトリに頻繁にコミットできる。ビルド頻度はプロジェクトの進行に応じて毎日、もしくは1日に数回になることもある。このように小さい単位で頻繁にビルドすることで、リスクの少ない簡単な実験が可能になるだけでなく、望ましくない結果を簡単にロールバックまたは破棄することが可能になる。

 CIでは、さまざまなツールと自動化技術を使用してビルドが作成され、そのビルドに対し、初期テスト(スニフテストや単体テストなど)と包括的なテスト(統合テストや回帰テスト)を実施する。CIは、詳細なフィードバックが迅速に得られるというメリットがあり、開発者やプロジェクトマネジャーがチームの作業結果をタイムリーに確認できる。各イテレーションの性質は限定的で、変更は意図的に小さく行われるため、バグの識別、バグの箇所の特定、報告、修正が比較的簡単になる。

 ビルドの初期テストが正常に完了し、より包括的なテスト(ユーザー受け入れテストなど)に移行する準備ができた時点でCIは終了する。ビルドのテストが失敗すると、そのビルドのブランチに目を向けられ、バグの修正や追加の対応を実施する。このビルドとテストのサイクルは、ビルドが成功するまで繰り返す。

 CIプロセスで重要になるのがバージョン管理だ。開発者がコードリポジトリからコードを取得すると、現在のコードベースの一意のバージョンを表すブランチが作成される。ブランチのビルドとテストが正常に終わると、通常は結果のブランチには新しいバージョン番号が付けられ、メインのコードベースにマージまたは統合(インテグレーション)される。これによって、他の開発者はコードベースでの作業を続けながら、ブランチや変更が多くなり過ぎて適切にインテグレーションできなくなるのを防ぐことができる。

 CIの最終準備としては、ビルドをデプロイ可能なイメージ(「Docker」「Apache Mesos」コンテナ、または従来の仮想マシンイメージなど)にパッケージ化してから、専任のテスト担当者が利用できるようにし、ビルドをステージングやデプロイメント環境に移行する準備をする。

» トップへ戻る

継続的デリバリーとは

 CD、つまり“継続的デリバリー”は、CIの次のフェーズに当たり、CI/CDパイプラインの後半に重きを置いている。CDでは、完成したビルドを徹底的にテスト、検証し、デプロイメント用にデリバリーする。テストと検証が正常に終わったビルドはデプロイする準備が整うが、必ずしも自動でデプロイされるとは限らない。

 多くの場合、ソフトウェアデリバリーはマージに成功した結果として実行される。変更が加わったブランチをメインのコードベースに統合することで、この短いループは終了する。開発者は新たなコードを取得して新たなブランチやアップデートの作成を始めることができる。

 正常にテストを終えたビルドをデプロイメント用にパッケージ化して、ステージング環境(テストサーバなど)にデリバリーする場合もある。その後、そのビルドをデプロイするか、実際の条件下でビルドをテストして結果を開発者に報告するか、ビルドのデプロイメントを見送って開発作業を継続するかは人間の管理者が判断できる。

 CIと同様、CDもツールと自動化に大きく依存している。ビルドに対して高度なテスト(ユーザー受け入れテスト、構成テスト、負荷テストなど)を実施するためだ。こうした高度なテストによって、ビルドが要件を満たし、運用環境で利用する準備が整っていることが確認される。また、小規模なイテレーションによってテストで判明した問題は、従来型ソフトウェア開発アプローチよりも迅速かつ低いコストで特定、修正ができる。

画像
継続的インテグレーションと継続的デリバリーがどのように連携するか

» トップへ戻る

継続的デプロイメントとは

 略称としては同じくCDだが、こちらは“継続的デプロイメント”だ。基本手順は継続的デリバリーと変わらないが、継続的デプロイメントでは、検証済みの各ビルドが意図的かつ自動的に運用環境にデプロイされる。一方、継続的デリバリーは、手作業でのデプロイメントや人間の承認を得る目的で、検証済みのビルドが単純にステージング環境に移される。この点がデリバリーとデプロイメントの主な違いだ。

 継続的デプロイメントでは、ビルドの検証からデプロイメントまでの時間を短縮することで、反復的ソフトウェア開発プロセスのスピードを向上させる。ただし、検出されなかった欠陥や脆弱(ぜいじゃく)性が、テストをすり抜けて運用環境に持ち込まれる可能性があることから、検証済みのビルドをリリース前に人間がレビューし、テストと分析もできる継続的デリバリーを選択する企業は多い。継続的デプロイメントを採用する企業は通常、強固なロールバックプロセスを実装しており、デプロイしたバージョンで予期しない問題が発生した場合に、以前の安定したバージョンに戻すことができるようにしている。

 これら3つの継続的手法に共通するテーマは、パイプラインのワークフローを後押しするために、自動化とテストを大きく取り入れることにある。理想は、開発者が「ボタンを押す」だけで、コードリポジトリから新しいビルドをテストに送り、デリバリーやデプロイメントにまで進めることだ。この魅力的な提案を実現するには、テストの品質、それを支える自動化の完全性、テスト担当者とソフトウェアエンジニアの細心の注意が必要になる。

» トップへ戻る

CI/CDパイプラインのメリットと課題

 CI/CDパイプラインは、複数の開発サイクルが同時に進行できるように設計されている。あるイテレーションではコーディングが進み、別のイテレーションではテストを実施し、また別のイテレーションはデプロイメントの準備に入っている、といったことが可能だ。CI/CDには多くの利点があるがデメリットもあるため、それぞれのトレードオフについて理解することが重要だ。

 CI/CDパイプラインのメリットは以下の通り。

ソフトウェア開発を効率化できる

 イテレーションを小さくする(各ブランチでの変更を少なく軽量にする)ことでテストが容易になり、効率が上がる。新しいイテレーションでのコードのスコープが限定されるため、バグの検出と修正も容易になる。機能の有用性やユーザーの受け入れ度合いの評価も迅速にできるため、不必要な機能は早期に調整または破棄が可能となり、開発リソースが無駄になりにくい。

競争力のあるソフトウェア製品を開発できる

 従来のソフトウェア開発アプローチは、リリースまでに数カ月から数年かかることがあり、ユーザーニーズや競争が動的に変化する環境にはあまり適していなかった。CI/CD開発では、新しい要件や要件の変化があっても次のイテレーションですぐに実装できる。市場により早く投入できるため、成功する可能性も高まる。

失敗を許容する環境を構築できる

 CI/CDは開発サイクルが速い。そのため、革新的なコーディングスタイル、独創的なアルゴリズム、型破りなアルゴリズムなどを、従来型ソフトウェア開発よりもはるかに少ないリスクで、試すことができる。実験がうまくいかなかければ、運用環境には移さず、次の迅速なイテレーションで元に戻せばいいからだ。企業は競争力のあるイノベーションを追求しやすくなる。

ソフトウェアの保守が容易になる

 従来型ソフトウェア開発は、バグの修正に数週間から数カ月かかることがある。だが、CI/CDパイプラインは迅速かつ確実にバグに対処できる。製品は時間の経過とともに安定度を増し、信頼性も高まるため、ソフトウェアの品質向上にもつながる。

運用サポートが向上する

 ソフトウェアの定期的なリリースによって、運用チームはソフトウェアの要件と監視のニーズを常に把握できるようになる。管理者は、デプロイメントのエラーや不要なトラブルシューティングを減らしながら、ソフトウェアアップデートをデプロイし、ロールバックを処理できる。同様に、自動化技術によって、設定エラーや構成エラーを減らしながらデプロイメントの速度を上げることができる。

分析を活用できる

 CI/CDパイプラインに関係するツールの多くは統合されており、開発作業や品質結果に関連する多くの指標(メトリクス)やKPIを収集できる。よく利用されるメトリクスは“開発速度”で、時間の経過とともに変更、追加されたコードの量で測定できる。他には、時間の経過やビルドで生成される問題やチケットの数に関連する欠陥の量もよく利用される。分析は、CI/CDパイプラインの効率を確実に高め、対処すべきボトルネックや問題点を特定するのに役立つ。



 これらは魅力的なメリットだが、業務部門の責任者や開発チームは、CI/CDパイプラインに潜む幾つかの落とし穴も考えておく必要がある。

自動化への依存

 CI/CDでのビルド、テスト、デプロイの実行は、「確立済みのツールセットの一貫性」と「強力な自動化フレームワーク」に依存している。自動化の実装と管理には多大な学習コストがかかる。習得も難しく、継続的な注意が必要になることがある。また、開発プロセスやツールセットを変更すると、CI/CDパイプラインに深刻な影響が及ぶ可能性がある。こうした背景からCI/CDは、成熟した、活発な開発環境で採用されることが多い。

スタッフの規律と計画

 CI/CDプロセスを最大限に活用するには、新しいビルドを継続的に生成し、リリース候補をテストし、選定されたビルドを本番環境にデプロイする必要がある。そのためには、慎重な計画とプロジェクト管理の専門スキルが必要になる。開発者は、品質標準、スタイル標準、アーキテクチャ標準を確保するため、確立済みの開発ガイドラインに従わなければならない。一方、業務部門の責任者やプロジェクト関係者は、継続的デプロイメントでの自動デプロイメントに大きな不安を感じる可能性がある。手作業でデプロイメントの可否を決める会議は、未知の結果や予期しない結果に対するストレスがあふれているからだ。その結果、新しいビルドがパイプラインを通過している間に、不必要な遅延が発生する可能性がある。

コミュニケーションとコラボレーション

 自動化やツールをどれだけ導入しても、開発者、運用チーム、プロジェクトマネジャー、プロジェクト関係者の間でのコミュニケーションとコラボレーションの代わりにはならない。チーム間の効果的な連携によって新しいアイデアを素早く試し、評価することができる。この迅速な実験と改善のサイクルがCI/CDの真の強みだ。自動化やツールはそのための手段にすぎない。

» トップへ戻る

優れたCI/CDパイプラインを構成する要素とは

 優れたCI/CDパイプラインが備える一般的な特性は以下の7つだ。

スピード

 CI/CDパイプラインには多くのステップやパーツが含まれる。だが、各ビルドはパイプライン(インテグレーション、テスト、デリバリー、デプロイメント)を短時間で通り抜けることが重要だ。通常、インテグレーションは数分、テストであっても数時間で完了する。1つのビルドがパイプラインを通り抜けるのに数日かかるようであれば、貴重な時間が無駄になる。その場合はプロセスの調整が必要になる。

一貫性

 プロセスやコンポーネントは、全ての場所やサイクルで同じ方法で使用する。例えば、ビルドの結果がDockerコンテナになる場合は、そのコンテナがテストされ、デリバリー、デプロイメントされる対象物となる。開発者がスクリプトや自動化プロセスを作成する際も、安定した結果が得られるよう設計されている必要がある。バリエーションや手動のステップがあると、パイプラインが遅延し、エラーや非効率を招く可能性が高まる。

厳密なバージョン管理

 リポジトリやコンポーネントのドキュメントを整備しておけば、ビルドの包括的なブランチ作成やマージ処理がスムーズになり、新しいビルドやデプロイメントがうまく機能しない場合に迅速に以前のビルドに戻すことができる。適切なバージョン管理によって、必要に応じて以前の作業バージョンに迅速、正確かつ確実にロールバックできる。

自動化

 広範囲にわたって自動化することで、手作業による操作をほとんど、あるいは全くせずに、新しいコードのインテグレーション、テスト、デリバリー、デプロイメントが実行できるようになる。理想的には、人間がコードを開発してコミットし、必要に応じて、承認済みのプルリクエストと承認を待ってからデプロイメントするだけになることだ。手作業のステップやプロセスに依存したパイプラインはスピードが低下し、エラーが発生しやすくなる。

フィードバックプロセスの組み込み

 CI/CDパイプラインは、多くの反復ステップによってプロジェクトを完了する1つのループで、問題が発生した時点で最初のフェーズに戻るループも用意されている。ソースコードに問題があるとビルドは生成されないし、ビルドに問題があればテストに進まない。テスト中やデプロイ後に問題が起きた場合はソースの修正が求められる。問題点を特定するフェーズが早いほど、修正も迅速、簡単かつ安価になり、パイプライン全体の稼働を維持できる。CI/CDプロセスの最適化には、計測機能を追加することが効果的だ。計測機能によって重要な指標を収集し、詳細なレポートを生成できる。こうして得られる新たなフィードバックは、プロセスの改善に大きく役立つ。

全体にわたるセキュリティ

 プログラミングやテストにおける見落としやミスは、脆弱(ぜいじゃく)性を生み出し、ソフトウェアを悪意のあるアクティビティーにさらす恐れがある。従って、CI/CDパイプライン全体にセキュリティのベストプラクティスを取り込むことが不可欠だ。脆弱性チェッカーなどのツールは、パイプラインを流れるコード内に潜むセキュリティ上の欠陥を見つけるのに役立つが、テスト段階でも追加のセキュリティ評価を実施する必要がある。

強固なツールの相互運用性

 CI/CDパイプラインには多くのツールが含まれる場合がある。パイプライン全体の各ツールは、適切に統合されている必要がある。もしくは、1つのツールの成果出力がパイプライン内の次のツールの入力として使えるように、ある程度の相互運用性をサポートしておくべきだ。適切な統合や相互運用性がなければ、パイプラインにおいて手作業による変換作業やその他の人的介入が必要になる可能性があり、エラーや非効率につながる可能性がある。CI/CDツールを選択する場合、相互運用性とタスクへの適合性を中心に検討することが重要だ。

» トップへ戻る

CI/CDパイプラインの各フェーズの役割

 CI/CDパイプラインは、4つの主要フェーズ(ソース、ビルド、テスト、デプロイ)で構成され、継続的インテグレーション、継続的デリバリー、継続的デプロイメントを実現する。各フェーズは、詳細なプロセス、標準、ツール、自動化で管理されている。製造業において、製品の製造プロセスを効率化するために機械をカスタマイズするように、ソフトウェアのパイプラインもプロジェクトやビジネスのニーズに合わせてカスタマイズされることが多い。

ソース

 CI/CDパイプラインの最初のフェーズはソースコードの作成だ。開発者はこのフェーズでソフトウェア要件を機能アルゴリズム、動作、機能に変換する。ソースコードの作成に使用するツールは、開発チームが使用する開発言語に左右される。開発言語は「Java」「.NET」「C#」「PHP」など多岐にわたる。統合開発環境(IDE)は、さまざまなコードチェック機能(機能基本的なエラー検出、脆弱性スキャン、確立済みコード品質基準への順守など)に加えて特定の言語をサポートするため、コードの作成によく利用される。その他のソースコードやパイプラインをサポートするツールには、「Git」のようなコードリポジトリやバージョン管理システムが含まれており、これらは通常、ビルドとテストフェーズの基盤となる。

 ソースを作成する単一のパイプラインは存在しない。「C++」を使用するサーバ側プラットフォーム、Javaを使用するWebサイトアプリケーション、「Go」を使用するモバイルアプリケーションなど、企業では開発中のさまざまなプロジェクトに応じた、複数のCI/CDパイプラインのソースが存在する可能性がある。同様に、エンタープライズ製造システムとコンシューマーアプリケーションなど、プロジェクトごとに標準や脆弱性は異なるため、コーディング機能もIDEやプロジェクトごとに異なる可能性がある。

ビルド

 ビルドフェーズでは、リポジトリからソースコードを取り出し、関連するライブラリ、モジュール、依存関係へのリンクを確立し、これら全てのコンポーネントを実行可能ファイル(exeファイル)または他の適切な構造にコンパイルまたはビルドする。このフェーズでは、ビルドプロセスのログを生成し、調査して修正すべきエラーを示し、ビルドの完了を開発者に通知するツールを使用する。

 ソースコードの作成と同様、ビルドツールは通常、ソースコードの作成時に選択したプログラミング言語によって異なる。ビルドを生成するために独立したツールを使用する開発チームもあるが、多くのIDEにはビルド機能が組み込まれているため、CI/CDパイプライン内のソース作成フェーズとビルドフェーズの両方を効果的にサポートする。

 ビルドフェーズでは、スクリプトなどの追加のツールを使用して、実行可能ファイルにパッケージ化するか、OSや関連コンポーネントを完備するデプロイ可能な実行環境(仮装マシンなど)に変換するか、ライブラリや依存関係を備え、オーケストレーションや自動化に「Kubernetes」を使用するコンテナ(Dockerコンテナなど)に変換する。

テスト

 ソースコードが静的テストを経て、完成したビルドが次の段階である動的テストに移行する。テストフェーズでは、通常、新しい機能や関数が意図通りに動作することを確認する基本的な機能テストや単体テストから始まり、新しい変更や機能の追加によってそれまで動作していた機能に悪影響を及ぼしていないかどうかを確認する回帰テストへと進む。その後、変更したコンポーネントと他のコンポーネントと引き続き適切に動作することを確認する統合テストやユーザー受け入れテスト、パフォーマンステストを実施する。テスト中にエラーが発生したら、結果を開発者にフィードバックし、次回のビルドで分析と修正をする。

 ビルドの動作を検証するために膨大な数のテストとテストケースにかけられるCI/CDのテストフェーズでは、特に自動化が重要になる。人間がテストをすると、時間がかかり過ぎ、エラーや見落としが生じる恐れがあるため、信頼性の高い客観的なテスト結果を確保できない。テスト担当者は包括的なテストケースとテストの基準は作成するとしても、時間に制約のあるパイプラインでのテストと検証にはテストツールを利用する。

デプロイ

 テストに合格したビルドは、運用環境にデプロイされる候補と見なされる。継続的デリバリーのパイプラインでは、ビルドは人間の関係者に送られ、承認を受けてから、必要に応じてデプロイされる。継続的デプロイメントパイプラインでは、テストスイートに合格したビルドはそのまま自動でデプロイされる。

 デプロイメントプロセスでは通常、デプロイメント環境の作成(データセンター内でのリソースとサービスのプロビジョニングなど)と、サーバなどデプロイメント先へのビルドの移動が含まれる。デプロイメントの各ステップは通常、スクリプトか自動化ツールのワークフローによって自動化される。また、デプロイメントでは、ビルドのデプロイ後に予期しないエラーを検出して開発者に警告するために、エラーレポートツールやチケットツールに接続するのが一般的だ。リリースで実際に発生するエラーや実際に認識したエラーを示すために、ユーザーからもバグチケットを送信できるようにする。

 デプロイしても問題ないと思える候補であっても、運用環境に無条件でコミットすることはめったにない。デプロイメントには、予期しないソフトウェアの問題を削減またはロールバックし、ビジネスへの影響を最小限に抑えるためのβテスト、A/Bテスト、ブルー/グリーンテスト、その他のカットオーバー作業期間など、追加の予防措置とライブテスト期間が必要になることが多い。

画像
継続的デリバリープロセスでは、最終的なテスト承認と本番環境へのリリースに至るまでに、複数のチェック、ゲート、フィードバックループが組み込まれている

» トップへ戻る

代表的なCI/CDパイプラインの例

 CI/CDパイプラインの構築に「これが正解」という方法はない。プロジェクトのスコープや要件に応じて、パイプラインごとに異なるツールを使用することもあれば、異なるバリエーションや手法を含めることある。どのようなアプローチにするにせよ、CI/CDパイプラインは次の3つの基本目標を満たすのが理想だ。

  • ソフトウェアの品質を向上させる
  • ソフトウェ開発の速度を上げ、アジリティを高める
  • 運用環境へのソフトウェアデプロイメントの信頼性を高める

 ここでは、代表的なCI/CDパイプラインの各フェーズでのアクティビティーを考え、そのアクティビティーに対処するツールを紹介する。

ソース

 開発者は、コードの作成にエディタやIDEを使用する。チームで取り組み際には、さまざまなプロジェクトの複数の言語をサポートするため、複数のエディタやIDEが使われることもある。

 ソフトウェアIDEの例には、オープンソースの「Atom」「Cloud9 IDE」、Microsoftの「Visual C++」「Visual Studio」、JetBrainsの「PyCharm」、Appleの「Xcode」などがある。

 複数の開発者が同時にコードベースにアクセスして作業できるように、ソースコードは共通の共有リポジトリに保存されるのが一般的だ。通常、ソフトウェア開発プロセスの他のコンポーネント(コンパイルやリンクのアーティファクト、ライブラリ、実行可能ファイル、モジュール、テストスクリプト、スイートなど)もリポジトリに保存される。リポジトリは、包括的なバージョン管理システムを提供し、開発者が最新のコードベースで作業できるようにし、ビルドプロセスでは最新コンポーネントのインテグレーションを可能にする。

 リポジトリとして広く使われているのは「GitHub」だ。他にも、GitLabの「GitLab」、Cloudsmithの「Package」、コンテナプロジェクト用Dockerの「Docker Hub」、JFrogの「Artifactory」、オープンソースの「NuGet」「SVN」などが使われている。

 開発者がコードベースに変更をコミットすると、その変更がリポジトリのバージョン管理システムに保存され、新しいビルドが自動的にトリガーされる。

ビルド

 ビルドプロセスは、リポジトリからソースコードコンポーネントを取得し、そのコードをコンパイルして、ライブラリや他のモジュールをつなぎ合わせるという複数のステップで構成されるのが一般的だ。ビルドプロセスによって、シンプルな実行可能ファイルや複雑なアセンブリ(デプロイ可能なコンテナやVMなど)が作成される。ビルドプロセスに関係する全てのアーティファクトは、通常、リポジトリに保持される。ビルドに問題やエラーがある場合、ビルドプロセスは停止し、その問題が開発者に報告され、修復される。代表的な問題には、機能エラー(ゼロ除算の計算エラーなど)やコンポーネントの欠落(必要なライブラリやモジュールがビルドマニフェストに存在しないなど)がある。

 多くのIDEには、選択したプログラミング言語に合わせて調整されたビルドツールが含まれている。スタンドアロンのビルドツールには、オープンソースの「Apache Ant」「Gradle」「Maven」「Phing」「Rake」、Makeの「Make」、OpenMakeの「Meister」などがある。オープンソースの「Jenkins」は広く使われているCIエンジンだが、それに代わるツールとして、Atlassianの「Bamboo」、Amazon Web Services(AWS)の「AWS CodePipeline」、CircleCIの「CircleCI」、GitHubの「GitHub Actions」、JetBrainsの「TeamCity」なども使われている。

 ビルドフェーズでは、ソフトウェア構成分析(SCA)や静的アプリケーションセキュリティテスト(SAST)などの脆弱性に関する基本的なテストを実施することもある。SASTツールの例には、Arctic Wolfの「Vulnerability Assessment」、Micro Focusの「Fortify Static Code Analyzer」、Invictiの「Netsparker」などがある。SCAツールは、Checkmarx、Kiuwan、Snyk、Synopsys、Veracodeなどのベンダーから提供されている。

 ビルドが正常に完了し、初期テストスキャンに合格すると、CI/CDのテストフェーズに移行する。

テスト

 幾つかのテスト(構文やコードの品質など)はその性質上ビルドフェーズで実施するが、大半のテストはビルドが正常に完了した後に実施する。テストフェーズには、次のような多くのステップと目標がある。

  • 単体テスト:新機能やビルドに追加された機能をテストする
  • 動的アプリケーションセキュリティテスト(DAST):セキュリティの欠陥(脆弱なパスワードや資格情報の不足など)を探すためにビルドを検証する
  • インタラクティブアプリケーションセキュリティテスト(IAST):セキュリティの問題(サードパーティーコンポーネントやオープンソースコンポーネントのセキュリティの欠陥など)を見つけるためにトラフィックと実行フローを分析する
  • 回帰テスト:変更や追加によってそれまで動作していた機能に悪影響が及んでいないことをテストする
  • 統合テスト:ビルドが他のアプリケーションやサービスと連携して動作することを確認する
  • ユーザー受け入れテスト:新しい機能や各種機能を意図通りにユーザーが使用できるかどうかを評価する
  • パフォーマンステスト:負荷をかけた状態でビルドが想定通りに動作することを確認する

 開発者とソフトウェアテスト担当者は、ビルドに入力を提供するテスト条件を作成し、実際の応答または出力を想定する応答や出力と比較する。想定通りであれば、テストは成功と見なしビルドを次のテストに送る。想定と異なる場合は、その違いを記録し、調査と修正を目的に、エラーの情報を開発チームに送り返す。

 こうしたテスト全体で利用できるツールは多数ある。いずれのツールもある程度自動化されており、複数種類のテストを実行できるツールもある。よく使われるテストツールには、Appianの「Appian」、Katalonの「Katalon」、Kobitonの「Kobiton」、Kualiteeの「Kualitee」、OpenTextの「OpenText UFT One」、オープンソースの「Qaprosoft」「Selenium」、Sauce Labsの「Sauce Labs」、Telerikの「Telerik Test Studio」、LogiGearの「TestArchitect」などがある。

 テストフェーズが正常に完了したビルドが、全てデプロイメントフェーズに送られるわけではない。中には、まだ検証が必要で中間ステップにあるビルドもある。例えば、開発者は機能を完備していないサブセットのテストを実施し、次のビルドで残りの機能サブセットを追加し、全ての機能がそろってからデプロイするといった可能性もある。

デプロイ

 テストに合格したビルドは、まずステージングサーバまたはテストサーバにデプロイする。これは「テストデプロイ」「運用前デプロイ」などと呼ばれることもある。デプロイプロセスはスクリプトを使って自動化されることが多い。スクリプトでは、ビルドの成果物(ビルドアーティファクト)をリポジトリから目的のテストサーバにコピーし、依存関係とパスを設定する。

 テストサーバにデプロイしたら、運用環境のシミュレーションをするようにビルドを構成する。例えば、テストデータベースやその他のアプリケーションへのアクセスを有効にして、「実際の」機能とパフォーマンスの評価ができる。その過程の多くで自動化を利用できるが、ビルドの微妙な違いを精査するために人間によるテストが必要になる場合もある。これは「αリリース」や「開発リリース」と呼ばれ、十分な知識を持つ少数のテスト担当者やユーザーだけが関与する。ユーザー受け入れテストは、この段階で実施されることが多い。

 運用前デプロイメントは、通常、継続的デリバリーパイプラインの最終段階となる。ビルドの完全な検証が済み、関係者がビルドの安定性と整合性に自信が持てるようになったら、運用環境にデプロイする。継続的デプロイメントパイプラインでは、ビルドが運用前デプロイメントのテストに合格すると、自動的に運用環境にデプロイされる。

 安全性を高め、予期しない結果を防ぐため、新しいビルドをA/B構成で現在のビルドと並行してデプロイすることもある。これは「βテスト」とも呼ばれる。このテストでは、徐々に大規模なユーザーグループへと広げていき、いずれ全てのユーザーが新しいビルドを使用できるようにする。全てのユーザーにビルドが行き渡った時点で、以前のビルドが廃止され、そのコンピューティングリソースは他のアプリケーションに解放される。

 専用のデプロイメントツールも多数ある。Red Hatの「Ansible Tower」、Chef Softwareの「Chef」、CloudBeesの「Codeship」「ElectricFlow」、オープンソースの「Jenkins」「Spinnaker」、Octopusの「Octopus Deploy」、JetBrainsの「TeamCity」などがその例だ。デプロイメントフェーズでは、アプリケーションパフォーマンス監視ツールやその他の種類の計測機器を使ってアプリケーションの健全性をチェックしてレポートすることもある。

画像
一般的なCI/CDパイプラインの各フェーズには、複数のタスクがあり、それらを達成するためにさまざまな種類のツールが使用される

» トップへ戻る

一般的なCI/CDパイプライン構築の流れ

 CI/CDパイプラインを設定する方法は1つではない。「正しい手順」は、ツールと実装するプロセスによって異なる。しかし、どのCI/CDプロセスにも共通する主要なステップと決まりが存在する。以下に一般的なパイプライン構築の流れを示す。

1.コードリポジトリを管理するバージョン管理システムを選択する。ホスティング型のシステムが必要かどうかを判断する。Microsoftの「Azure DevOps」など、大手クラウドプロバイダーもリポジトリサービスを提供している。

2.アプリケーションのソースコード、アーティファクト、ブランチ、ビルドを収容するリポジトリを作成する。

3.使用するビルドサーバ(またはCIサーバ)を決める。これには、セルフホスト型サーバ(Jenkinsなど)か、サードパーティーのサービス(GitHub Actions、CircleCI、Microsoftの「Azure Pipelines」など)を利用できる。

4.アプリケーションのソースコードをビルドにコンパイルするタスクをパイプラインに実装する。DockerイメージやVMを生成する設定もある。

5.コードの品質と自社のガイドラインとの一貫性を確保するため、コードの基本的なテスト(静的分析やスタイルチェックなど)のテストを実行する。

6.ビルドによって、ストアまたはレジストリに公開するアーティファクト(コンテナイメージ)を生成する。

7.ビルドに対してさらなるテスト(機能テスト、セキュリティテスト、ユーザー受け入れテストなど)を実施する。事前に決めたしきい値を満たさない場合、ビルドフェーズを不合格とする。テストの結果とコードのカバレッジを公開し、容易に利用可能にすることが重要だ。

8.ソフトウェアビルドがテストに合格したら、運用環境へのデプロイメントに向けた最終準備が整う。これには、「ブルー/グリーンデプロイメント」や「カナリアデプロイメント」など、複数のステージング環境が含まれる場合がある。

9.デプロイメントのパラメーター(リソースのプロビジョニング、サービスの接続、成功したリリース候補の運用環境への移行など)を検討する。ソフトウェアのパフォーマンス、エラー、その他の要因に関するデータを収集するために、計測機器を接続するのが一般的だ。また、ロールバックプランも用意する必要がある。

 クラウドベースのCI/CDも同じように機能するが、クラウドプロバイダーのプラットフォームにネイティブなツールとサービスに大きく依存するため、特定のステップが必要になる場合があることに注意する。CI/CDの実装には、幾つか特定の課題も生じる。以下に注意すべき大きな課題を挙げる。

テストの限界

 CI/CDパイプラインに共通する課題は、テスト環境を構成し、テストケースを作成するのに必要なリソースと知的投資の確保と調整だ。継続的開発には、複数回のコードコミットと並列テストが必要で、構成の競合やテストケースの限界や見落としが頻繁に発生する。その結果、テスト段階をすり抜けるエラーが生じ、パイプラインの効率が低下する可能性がある。知識豊富な熟練のソフトウェアテスト担当者を確保し、要件と目標をしっかりと文書化することが最優先となる。

バグの修正

 パイプラインは、新しいビルドでバグを修正できるよう開発者にフィードバックループを提供するように設計されている。バグを見つけるのは簡単だが、そのバグを修正すべき開発者を特定することは困難だ。特定の開発者や領域でバグが頻発している場合、追加のトレーニングが必要だが、誰が(もしくはどこが)問題なのかが分からなければ、どのようなトレーニングが必要かも分からない。バグの場所を特定し、その修正を担当する開発者を特定するには、ログ記録、チーム内でのコミュニケーション、豊富なドキュメントが役に立つ。

セキュリティの確保

 ソフトウェアプロジェクトは、ビジネスにとって大きな投資であり、その投資には包括的なセキュリティが組み込まれている必要がある。外部の視点で言えば、パイプラインとそのデータ(ソースコード、テストデータから完成したビルドまで)は、IDとアクセスの管理などの機能に注意しながら安全な方法で保存し、承認を受けた開発者だけがその知的財産にアクセスできるようにする必要がある。内部の観点からは、認証機能付きAPIなどの包括的なセキュリティ技法を使用してソフトウェアを設計、実装し、適切なユーザーだけが開発中のソフトウェアを利用できるようにする必要がある。

» トップへ戻る

CI/CDパイプラインのベストプラクティス

 CI/CDパイプラインを最大限に活用するため、企業や開発チームはさまざまな方法を採用できる。以下のベストプラクティスを実践することで、CI/CDパイプラインからより多くの価値を引き出すことが可能となる。

小さく始める

 CI/CDは迅速性と柔軟性をもたらす。そのため、CI/CDプロセスが進化する時間を確保し、開発者がさまざまなツールやステップを試せるようにする。CIパイプラインから着手し、その後CDを追加することもできる。補填型の小さなプロジェクトは、より広範なパイプラインへと強化できる新しいツールや技法を試す絶好の場所となる。

少しずつ機能させる

 CI/CDは、コードの変更を限定して徐々に変更するように設計する。これによって「ある開発者が変更のためにコードを取り込んでいるので、他の開発者はそのコードにアクセスできない」といった状態が長期間続くのを防げる。また、変更が小さければテストや検証が迅速になり、対処すべきバグの可能性も少なくなる。小さく段階的に機能させていくことで、パイプラインを常に稼働状態にしておくことができる。

成功の基準を定める

 期待するメリット(コードビルドの高速化、エラーの低減、やり直し率の低下など)を理解し、そのメリットを実現する基準を測定する指標を設定する。パイプライン設定前と設定後で指標を比較する。これによって、パイプラインの成果を確認し、時間の経過とともに生じる問題を特定してCI/CDパイプラインの構築と強化の方法に容易に取り組めるようになる。

プロセスをドキュメントにする

 ドキュメントは見落とされたり過小評価されたりすることが多いが、パイプラインには不可欠な要素だ。ドキュメントによって、全ての開発者と業務部門のユーザーにプロセスとツールが示され、全ての要素の関連性や構成が表現される。問題のトラブルシューティング、意図しない設定の変更、構成のずれの軽減にもドキュメントが役立つ。ドキュメントは企業のコンプライアンスやセキュリティ体制にも役立ち、チームの活動を管理者が監査可能になる。

運用について考える

 DevOpsや継続的デプロイメントなど、アジャイル開発は、運用と開発の双方の役割を取り入れている。開発者は、デプロイメントと運用の両面を理解し、ソフトウェアの信頼性、セキュリティ、パフォーマンスに対して責任を負う必要がある。業務部門の責任者やプロジェクトリーダーは、この姿勢の変化を後押しし、強化する必要がある。

フィードバックを重視する

 CI/CDパイプライン内でのフィードバックは、時間を節約して作業効率を高めるために、全てのステップで全ての関係者が積極的に問題を見つけて対処することで最も効果が高まる。フィードバックは、ソースコードのエラーを見つけるところから始まり、テストとデプロイメントまで続く。例えば、テスト段階での時間と労力が無駄にならないように、ビルドフェースでソースコードの構文エラーを見つけて修正する。エラーを分類して分析することは、開発スキルとプロセスを向上させるのにも役立つ。

プロセス全体にセキュリティを浸透させる

 コードレベルでセキュリティスキャンツール(SASTツールやSCAツール)を使うと、脆弱性やエラーを早期に診断できるが、誤検知が多発する可能性がある。テストレベルのセキュリティスキャンツール(DASTツールやIASTツール)を使うと、パイプラインの後半でエラーが見つかり、ソフトウェアのビルドと実行をやり直す必要があるため、バグ修正に時間とコストがかかる。セキュリティスキャンツールは手元のタスクに最適なツールを選択して使用し、バグ追跡システムを自動的に更新し、迅速な調査と修復のためチケットを自動的に生成することが重要だ。

 パイプライン自体のセキュリティについても検討が必要だ。承認や認証が不適切であれば、ツールとリポジトリに対して悪意のある操作が実行されるリスクがある。ツールとリポジトリを保護し、ログを使用してユーザーアクセスを追跡し、異常なアクティビティー(自社LAN外部IPアドレスへのダウンロードなど)にフラグを立てる。

継続的テストを取り入れる

 ソースとビルドのフェーズでは、SCA、SASTなどでコードをスキャンして、スタイルとセキュリティ標準に準じているかどうか確認する。ビルドが完成したら、テストツールを使って、確立済みの一連のテスト条件を適用する。シンプルな機能検証から始め、より複雑で包括的な統合テスト、詳細なセキュリティテスト(DASTなど)、パフォーマンステストへと体系的にテストを拡張する。ビルド、プロジェクト、プロジェクトの要件が進化するにつれ、各新しいビルドの機能を検証するために、テストとテストケースを慎重に構築していく必要がある。頻繁に追加される新機能には、頻繁なテストとテストケースが必要になる。

コミュニケーションを高める

 統合とデリバリーは連携して機能するが、多くの場合はそれぞれ個別に実装され、コーディングチームやテストチームなどの異なるチームが担当する。CI/CDパイプラインが円滑に機能するためには、パイプライン全体でタイムリーで明確なチーム間のコミュニケーションとコラボレーションが必要になる。コミュニケーションが不足すると、不要な遅延が発生して容易に機能不全に陥る可能性がある。

無駄をなくす

 CI/CDパイプラインの作成と保守には、ツール、インフラ、リソースにさまざまなコストがかかる。これらのいずれかの使用効率が低い場合、例えば「十分活用されていないツールや未使用のツールがある」「テストやデプロイメントにITインフラを過剰に割り当てている」「調整が不十分」「プロセスやツールの評価が不十分」といったことがあると、開発が遅れ、開発者の生産性が低下する可能性がある。CI/CDパイプラインを効率的かつ確実に動作させるには、頻繁な改良と定期的な開発者トレーニングが必要だ。

 無駄を避けるというのは、あまり目立たない非効率な部分を避けることでもある。1日に10個のビルドをテストしてデプロイする実用的な方法がなければ、1日に10個の異なるビルドは作成しないようにする。チームとプロジェクトの取り組みは、パイプラインを最も生かせるように調整する必要がある。

エコシステムを強化する

 CI/CDパイプラインは、プロセスと自動化に結び付けられるツールで構成されるエコシステムであり、さまざまな製品に対してそれぞれ異なる手法やステップがある。チームは常に新しいツールを評価し、プロセスを改善して、パイプライン全体を可能な限り円滑かつ効率的に保つ必要がある。

リソースを回復する

 余裕のないCI/CD環境では、ビルド、テスト、デプロイメントにコンピューティングリソースやストレージリソースが大量に使用される可能性がある。業務部門の責任者やプロジェクトリーダーは、プロジェクトの進化に合わせて未使用のリソースを追跡し、再利用のためにリソースを回復する方法を検討することが重要になる。例えば、以前のビルドを置き換えるために新しいビルドをデプロイする場合、古いビルドで利用されていたリソースは再利用できるように“回復”しておく必要がある。

» トップへ戻る

Copyright © ITmedia, Inc. All Rights Reserved.

ページトップに戻る