CI/CDパイプラインの概要

この講座では、DevOpsの基本であるCI/CDパイプラインについて学びます。

  • CI/CDパイプラインとは何か
  • 静的解析・自動テスト・ビルド・デプロイの各工程
  • CI(継続的インテグレーション)とCD(継続的デリバリー/デプロイ)の違い
  • CI/CDがもたらすメリット
  • CI/CDパイプラインの代表的なツール

1. CI/CDパイプラインとは

CI/CDパイプラインとは、ソフトウェアの開発からリリースに伴う流れの中で、静的解析、テスト、ビルド、デプロイなどの工程を自動化する仕組みです。

1.1 CI/CDパイプラインの流れ

CI/CDパイプラインは、コードのプッシュやPull Requestの作成など、あらかじめ設定したタイミングで、いくつかの工程を自動実行します。ここでは、主な4つの工程について説明します。

静的解析

静的解析は、プログラムのコードを実行せずに解析し、コード品質やセキュリティ上の問題を自動的に検知する仕組みです。実際にアプリケーションを動かす前の段階で問題を発見できるため、後工程での手戻りを防ぐことができます。変数名の付け方やインデントの統一といったコードスタイルのチェックから、型の不整合やバグの原因となりうるコードの検出まで、幅広い観点でコードを検査します。

自動テスト

自動テストは、あらかじめ用意したテストコードに従ってアプリケーションを実際に動かし、期待通りに動作するかどうかを確認する工程です。手動テストでは時間がかかるうえ、テスト漏れや人的ミスのリスクがありますが、自動化することで何度でも同じ条件でテストを繰り返し実行でき、効率よく品質を高めることができます。

自動ビルド

自動ビルドは、ソースコードを実行可能な形式に変換し、アプリケーションとして動かせる状態にまとめる工程です。例えば、コンパイル言語ではバイナリファイルへの変換が行われ、コンテナを利用する場合はコンテナイメージの作成が該当します。ビルドされた成果物は、次のデプロイ工程で使用するためにアーティファクトとして保管されます。

自動デプロイ

自動デプロイは、ビルドで生成された実行ファイルやコンテナイメージを、サーバやクラウドなどの実行環境に自動的に反映させる工程です。この工程が完了すると、コードの変更が実際のシステムに反映され、ユーザが新しい機能や修正を利用できるようになります。

1.2 CIとCD

CI/CDパイプラインは、大きくCICDの2つの領域に分かれます。それぞれの意味と、どの工程が含まれるかを説明します。

CI(継続的インテグレーション)

CI(Continuous Integration)とは、コードを自動でチェックし続け、常に問題のない状態を保つことを指します。日本語では「継続的インテグレーション」と呼ばれます。

具体的には、開発者がコードをリポジトリに統合(マージ)するたびに、静的解析や自動テストが自動で実行されます。これにより、問題のあるコードが早い段階で検知され、品質を維持したまま開発を進めることができます。工程としては、静的解析と自動テストがCIに含まれます。また、自動ビルドも一般的にはCIに含まれますが、組織やツールによってはCD側に分類されることもあります。

📝 Integrationの意味
「Integration(インテグレーション)」は「統合」という意味です。複数の開発者が書いたコードを頻繁に統合(マージ)し、その都度自動テストを行うことで、問題を早期に発見するという考え方から名付けられています。

CD(継続的デリバリー/デプロイメント)

CD(Continuous Delivery / Continuous Deployment)は、完成したアプリケーションをいつでも実行環境に公開できる状態に保つ、あるいは自動で公開する仕組みを指します。日本語では「継続的デリバリー/デプロイメント」と呼ばれます。

工程としては、自動デプロイがCDの中心になります。また先程説明したように、自動ビルドもCDに含まれることがあります。CIでコードの品質が確認された後、CDによってそのコードが実際の環境に届けられるという流れになります。

1.3 メリット

最後に、CI/CDパイプラインを導入するメリットをいくつか紹介します。

品質の向上

CI/CDパイプラインを導入することで、品質が向上し、問題を早い段階で発見できるようになります。静的解析や自動テストがCI/CDパイプラインに組み込まれることで、実際に動作させる前の段階で問題点を検知できるため、品質向上が見込まれます。合わせて、問題のない状態のコードのみが実環境にデプロイされるという仕組みも構築できます。

リリース作業の効率化

各工程を自動で行うことができるため、リリース作業を効率化することができます。手動でリリースする場合は何時間もかかることがありますが、自動化されたビルドやデプロイであれば数分で完了させることも可能です。

作業ミスの軽減

自動化の恩恵として作業ミスの軽減が期待できます。手動の場合は操作やコマンドの入力ミスなど、人的なミスが生じやすいことがありましたが、自動化によってこれらのリスクを大きく軽減できます。

手順の可視化と標準化

手順の可視化や標準化が図れます。手動で行う場合、暗黙のルールや、ベテランでないと把握できていない手順などがあり、リリースの難易度を高めているケースがありました。各ツールの設定ファイルに手順が明文化されるため、暗黙の手順がなくなり、属人化を防止できます。

これらのメリットにより、より安全に、より素早くリリースできる開発体制を作ることができます。

2. CI/CDパイプラインの代表的なツール

ここでは、CI/CDパイプラインでよく使われる代表的なツールを紹介します。

CI/CDツールは大きく「コード連携型」「クラウド統合型」「独立型」の3つに分類できます。これは公式な分類ではありませんが、理解しやすくするためにこの3つの観点で整理して説明します。

2.1 コード連携型ツール

まず「コード連携型ツール」です。

ソースコード管理リポジトリと密接に連携して動作するタイプで、代表的なものにGitHub ActionsやGitLab CI/CDがあります。これらのツールでは、プッシュやプルリクエストなどの変更をトリガーに、自動で静的解析・テスト・ビルド・デプロイを実行できます。コード管理ツールと統合されているため、リポジトリへのアクセスや認証設定が容易で、トラブルが起きにくい点が特徴です。

特にGitHub ActionsはGitHub上で完結するCI/CDツールとして広く利用されており、開発からデプロイまでの流れをスムーズに実現します。

このようにコード連携型ツールは、ソース管理から自動化までを一貫して扱える点が魅力で、個人開発や小規模チームにも適しています。

2.2 クラウド統合型ツール

次に「クラウド統合型ツール」です。

これはクラウドサービスに標準搭載されているタイプで、AWS CodePipeline、Azure DevOps、Google Cloud Buildなどが代表例です。クラウド環境と深く統合されているため、各クラウドサービスへの自動デプロイを容易に行えます。

インフラ構築や運用を行うチームに特に向いており、クラウドに特化した安定したパイプラインを構築できます。一方で、クラウドごとに環境や設定が異なるため、マルチクラウド運用では注意が必要です。

2.3 独立型ツール

最後に「独立型ツール」です。特定のクラウドやリポジトリに依存せず、独立した環境で利用できるタイプで、代表的なものにCircleCIとJenkinsがあります。

CircleCIはクラウド上で手軽に使えるSaaS型ツールで、GitHubやGitLabと連携して自動ビルド・テスト・デプロイを実行できます。セットアップが容易で、特定サービスに縛られない柔軟性があります。

一方、Jenkinsはオープンソースとして広く利用されており、自社サーバや仮想マシン上で構築・運用できます。豊富なプラグインにより、高度なカスタマイズや外部ツール連携も可能です。ただし、動作するためのサーバが必要になるなど、導入のコストはCircleCIなどと比べると多少多くなります。

このように独立型ツールは自由度が高い反面、初期設定やメンテナンスの負担が大きいため、導入時には運用コストとのバランスを考えることが大切です。

3. 静的解析

ここからは、CI/CDパイプラインの各工程について、もう少し詳しく見ていきます。まずは静的解析です。

3.1 静的解析とは

静的解析は、プログラムのコードを実行せずに解析し、問題となる箇所を検知する仕組みです。コードの品質や保守性を高めるための解析手法として利用されます。

イメージとしては、チェックツールをインストールし、そのツールが対象のコードを検査して問題点を指摘する、という流れです。

静的解析ツールは言語やフレームワークごとに標準的なものが用意されており、それを利用するのが一般的です。例えば Python であれば、「Pythonで静的解析をしよう」で学んだ flake8 や mypy が代表的です。その他にも、Java の SpotBugs や Checkstyle、Go の golangci-lint、PHP の PHPStan、Ruby の RuboCop、JavaScript の ESLint などがあります。

静的解析では、例えば以下のような問題を検知できます。

  • インデントや命名規則の不統一など、可読性の低いコード
  • 型の不整合やエラー処理の未実装など、バグの原因となりうるコード
  • 条件分岐のネストが深いなど、保守性の低いコード

このように、コードを実行する前に問題点を検知できる点が、静的解析の大きな特徴です。

具体的にCI/CDパイプラインに静的解析を組み込む方法は、この後のハンズオンで実際に体験します。

4. 自動テスト

次に、自動テストについて詳しく見ていきます。

4.1 自動テストとは

自動テストは、あらかじめ用意したテストコードや設定に従ってテストを自動で実行し、作業の効率化とミスの防止を行う仕組みです。

手動テストの課題

自動テストの前段となる手動のテストでは、開発者が画面操作やコマンド実行を行い、テスト結果を記録して確認します。こうした作業は時間がかかるうえ、テスト漏れや人的ミスのリスクがあり、さらに修正のたびに再テストが必要になります。加えて、人によって判断基準が異なるため、テスト結果にばらつきが出やすいという課題があります。

自動テストの導入効果

一方、自動テストを導入すると、あらかじめ用意されたテストコードや設定に基づいて自動でテストが実行されます。これにより、作業時間を短縮し、人的ミスを防ぐことができます。コードを修正したあともすぐに再テストを実行でき、品質を継続的に確認できます。また、常に同じ条件でテストが行われるため、人による判断基準に左右されず、一定の基準で品質を維持できます。

このように、自動テストは開発の効率を高めるだけでなく、品質を安定させるための重要な仕組みです。

4.2 自動テストの種類

自動テストにはいくつかの種類があります。目的や実行方法によって分類され、それぞれが異なる役割を持っています。

まずユニットテストです。ユニットテストは、プログラムを構成する関数やロジックなど、最小単位の動作を確認するテストです。小さな単位で検証することで、問題の箇所を特定しやすくなります。ユニットテストは、CI/CDパイプラインに組み込みやすいテストのひとつです。

続いてE2Eテスト(End-to-Endテスト)です。E2Eテストは、画面やAPIなどを通して、システム全体を入口から出口まで一連の流れで検証するテストです。実際のユーザ操作に近い形で動作を確認できるため、アプリケーション全体の品質を評価するのに適しています。

続いて「セキュリティテスト」です。セキュリティ上の脆弱性が存在しないかを確認するテストで、不正アクセスや情報漏えいを防ぐために重要です。

最後に「性能テスト」です。性能テストでは、システムが一定の負荷に耐えられるかどうか、応答速度や安定性を含めて検証します。これにより、本番環境で安定したパフォーマンスを維持できるかを確認します。

E2Eテスト、セキュリティテスト、性能テストは、CI/CDパイプラインに組み込むことも可能ですが、独立したプロセスとして実施されることもあります。そのため、「必ずしもすべてをパイプラインに組み込む必要はない」という点を意識しておくと良いでしょう。

このように、自動テストにはさまざまな種類があり、それぞれが異なる角度からシステムの品質を支えています。開発の段階や目的に応じてこれらを組み合わせることで、より信頼性の高いソフトウェアを作ることができます。

4.3 ユニットテストとは

ユニットテストは、あらかじめ用意したテストコードに従ってテストを実行し、主に関数や処理単位で正しく動作しているかを確認するテストです。

まずテストコードを用意します。ここには、テストの流れや期待される結果(期待値)などを定義します。このテストコードに従ってコードを実行し、結果が期待値と一致しているかを確認するのが一般的な流れです。

ユニットテストの代表的なツールは、静的解析と同様に各言語やフレームワークごとに標準的なものが用意されており、それらを利用するのが一般的です。Pythonのpytest、JavaのJUnit、PHPのPHPUnit、Goのtestingパッケージ、RubyのRSpecやMinitest、JavaScriptのJestなどがよく使われます。

ユニットテストでは、例えば以下のような内容を検証できます。

  • 期待値と実行結果が一致するかなど、正常時の挙動
  • エラー発生時に正しくエラー処理が行われるかなど、異常時の挙動
  • コード修正後に既存の動作へ影響がないかを確認する、回帰テスト(デグレード防止)
📝 期待値とは
「期待値」とは「正しい結果はこうなるはず」という値のことです。例えば、足し算の関数で「2 + 3」を計算させるテストを書く場合、期待値は「5」になります。実際の計算結果と期待値を比べて、一致すればテスト成功です。

具体的にCI/CDパイプラインに自動テストを組み込む方法は、この後のハンズオンで実際に体験します。

5. 自動ビルド

続いて、自動ビルドについて詳しく見ていきます。

5.1 自動ビルドとは

自動ビルドは、コードを実行可能な形式に変換し、動作に必要な依存ライブラリや設定を整える工程です。CI/CDパイプラインに組み込んで自動化することができます。

まず、ソースコードを実行可能なファイルに変換します。実行ファイルとは、例えばコンパイルによって作成されるバイナリファイルや、コンテナを使う場合はコンテナのイメージファイルなどが該当します。

作成した実行ファイルは、次のデプロイ工程で使用するために、アーティファクトと呼ばれる保存領域に保管します。アーティファクトはGitHub Actionsのアーティファクト領域やS3などに格納されます。なお、コンテナを格納するDocker Hub や Amazon ECR も同様に扱えますが、厳密には アーティファクトではなくコンテナレジストリ に分類されます。

このように自動ビルドを行うことで、ビルド作業の効率化や人的ミスの軽減が期待できます。

5.2 自動ビルドの代表的なパターン

自動ビルドには、大きく2つのパターンがあります。

1つ目はコンパイルを行うケースです。Go言語やJavaなどのコンパイル言語では、ソースコードをバイナリファイル(実行ファイル)に変換する工程が必要です。

2つ目はコンテナを利用するケースです。Dockerfileをもとにコンテナイメージを作成し、Amazon ECRなどのコンテナレジストリに格納します。Pythonのようにコンパイルが不要な言語でも、アプリケーションと依存ライブラリをまとめてコンテナイメージとしてビルドするのが一般的です。

具体的にCI/CDパイプラインに自動ビルドを組み込む方法は、この後のハンズオンで実際に体験します。

6. 自動デプロイ

このセクションでは、CI/CDパイプラインにおける自動デプロイについて解説します。

6.1 自動デプロイとは

自動デプロイとは、自動ビルドで生成された実行ファイルやコンテナイメージを、サーバやコンテナ環境に自動的に反映させる仕組みです。

一般的な流れとしては、ビルド工程で作成された実行ファイルをアーティファクトからダウンロードし、それをサーバに反映させる処理が行われます。なお、コンテナを利用する場合など、アーティファクトからのダウンロードが不要となるケースもあります。

自動デプロイの代表的な例をいくつか紹介します。

サーバへのデプロイ

オンプレミスのサーバや、Amazon EC2などの仮想環境で動作しているサーバが該当します。CI/CDパイプラインツールからサーバにSSH接続を行い、リソースの転送や再起動などを行って反映させます。

コンテナ環境へのデプロイ

Amazon ECSなどのコンテナ環境が該当します。Amazon ECRのようなコンテナレジストリに格納されたイメージを、コマンドでECSに反映させる仕組みです。

PaaSへのデプロイ

HerokuやAWS Elastic Beanstalkなどが該当します。サービスが提供するデプロイ用コマンドを実行して、変更を反映させます。

具体的にCI/CDパイプラインに自動デプロイを組み込む方法は、この後のハンズオンで実際に体験します。

6.2 継続的デリバリーと継続的デプロイメント

CDには「継続的デリバリー」と「継続的デプロイメント」の二つの意味があると先ほど説明しました。これらは似ていますが、定義が異なります。ここでは、この二つの違いについて説明します。

簡単に説明すると、継続的デリバリーは『ビルドまでを自動化し、デプロイは手動または承認を経て行う』方法であり、継続的デプロイメントは『ビルドからデプロイまでを完全に自動化』する方法です。

それぞれの違いを説明します。

継続的デリバリー

継続的デリバリーとは、CI/CDパイプラインにおいて、ビルドとデプロイの間に手動の承認プロセスを設定し、ビルド後に人の手で内容を確認してからデプロイを行う仕組みです。

この方法のメリットとして、デプロイのタイミングを手動でコントロールできるという点があります。たとえば、リリース時に関係者への周知や調整が必要な場合、マージのタイミングで自動的にリリースされては困ることがあります。そういった場面で、継続的デリバリーの仕組みは有効です。

また、ビルドに時間がかかる構成の場合、先にビルドを済ませておき、システムへの反映は任意のタイミングで行うこともできます。

利用シーンとしては、本番への機能変更を慎重に行う必要があるケースが挙げられます。たとえば、関係者への周知が必要な場合や、法律の改正タイミングなど、リリース時期に制約があるシステムで特に有効です。

また、ビルドやデプロイの失敗リスクが高い場合も、工程を分けておくことで、それぞれに適切な対処を行いながら進めることができます。

継続的デプロイメント

継続的デプロイメントは、ビルドからデプロイまでの工程を完全に自動化する考え方です。ビルドが完了すると、そのまま自動的にデプロイまで実行されます。

この方法のメリットは、プロセスを完全に自動化できる点です。継続的デリバリーの場合、手動承認によって確実なコントロールが可能な一方で、承認待ちによる遅れが発生するリスクがあります。とくにテスト環境においては、承認待ちの状態で作業が一時停止してしまうことがあります。この工程を自動化することで、スピード感を持って開発を進めることができます。

利用シーンとしては、ビルドやデプロイの失敗リスクが低い場合が挙げられます。また、変更に対して他部門や顧客との調整が不要な場合も、一貫して自動化した方が効率的です。

どちらを採用するかは、プロジェクトごとの状況や優先度に応じて判断する必要があります。また、テスト環境は継続的デプロイメント、本番環境は継続的デリバリーといったように、環境ごとに方針を切り分けて運用することもできます。

7. まとめ

この講座では、CI/CDパイプラインの概要について学びました。

  • CI/CDパイプラインは静的解析、テスト、ビルド、デプロイを自動化する仕組み
  • CI(継続的インテグレーション)は静的解析や自動テストでコードの品質を常に保つ
  • CD(継続的デリバリー/デプロイメント)はビルドからデプロイまでを自動化または半自動化する
  • CI/CDツールには「コード連携型」「クラウド統合型」「独立型」がある
  • 静的解析でコードの品質やセキュリティの問題を事前に検知できる
  • 自動テスト(ユニットテスト、E2Eテストなど)で品質を継続的に確認できる
  • 自動ビルドでコードを実行可能な形式に変換し、自動デプロイで環境に反映する
  • 継続的デリバリーはデプロイ前に承認を挟み、継続的デプロイメントは完全自動化する