DevOpsのサイクルをコードで管理し、プロセスを自動化する「CI/CDパイプライン」

2024年2月9日(金)
水野 源
第12回の今回は、アプリケーションのビルドからテスト、デプロイまでのプロセスを自動化する「CI/CDパイプライン」について解説します。

はじめに

DevOpsのサイクルを回す上で重要なのが、アプリケーションのみならず、インフラ構成、テスト、デプロイ手順、モニタリング、といったあらゆる要素をコードによって管理することと、これらのプロセスを自動化することです。今回はアプリケーションのビルド、テスト、デリバリーなどのプロセスを自動化する「CI/CDパイプライン」について解説します。

CI/CDとは

第4回のおさらいになりますが、CI/CDについて改めて解説しましょう。

CIは「Continuous Integration」の略で、日本語では「継続的インテグレーション」と呼ばれます。インテグレーションという表現が抽象的なためイメージしづらいかもしれませんが、簡単に言えば、コードをリリースブランチにマージ可能な状態に保つことです。そしてリリースブランチにマージ可能な状態とは、コードに問題がないことが確認できた状態です。これは必要なテストをパスした状態と言い換えても良いでしょう。CIはこの確認を自動化し、継続的に行うプロセスです。例えば「コミットやプルリクエストの発行をトリガーとして、自動的にコードの静的解析やテストを行う」などは、典型的なCIの一例です。CIによって自動的にテストが行われることで、追加したコードが意図通りに動いていることや、既存のコードにリグレッションが発生していないことが担保されます。

CDは「Continuous Delivery」の略で、日本語では「継続的デリバリー」と呼ばれます。デリバリーとは、アプリケーションを正しくデプロイできるよう、その準備を整えるプロセスを指します。具体的にはコンテナイメージのビルドや、コンテナレジストリへのプッシュといった作業がデリバリーに含まれます。そしてCDは、このデリバリーに必要な作業を自動化し、継続的に行います。CIによってアプリケーションのコードに問題がないことが確認されると、その後段階としてCDが行われるのが一般的です。

CDはあくまでデプロイの準備である「デリバリー」までを自動化するもので、実際のデプロイは行いません。そのためデリバリーの完了後、担当者による承認などを挟んだ上で、別途デプロイ作業が必要になります。ただしデプロイまでを完全に自動化するケースもあり、その場合のプロセス「Continuous Deployment」(継続的デプロイ)と呼ばれます。どちらも略称が同じ「CD」のため、取り違えないよう注意してください。こちらの継続的デプロイについては、次回で解説する予定です。

その性質上、CIとCDは連続して行われることが多いため、この2つはセットにして「CI/CD」と呼ばれます。また実際のCI/CDにおいて、具体的にどのようなツールが、どのような処理を行うかを定義したものを「CI/CDパイプライン」と呼びます。

従来、アプリケーションへの新規機能の実装とリリースは、バグ混入のリスクや既存機能への影響といった面からコストが大きく、これがリリース頻度の低下の一因となっていました。しかし、これでは激しく変化する市場の要求に対応できません。CI/CDによるテストとデリバリーの自動化は、品質を担保しつつ、同時に開発サイクルを高速化します。アジャイルな開発を実現するためにも、CI/CDは絶対に欠かすことのできない要素だと言って良いでしょう。

CI/CDパイプラインの構成要素

CI/CDパイプラインは、テストやビルドといった連続、あるいは並列に実行される、複数の要素が集まって構成されています。このパイプラインを構成する要素を「ジョブ」と呼ぶこともあります。

ひと口にCI/CDパイプラインと言っても、具体的にどのようなジョブが実行されるかは、対象となるアプリケーションの要求やシステムの仕様によって異なるため、その構成は一様ではありません。とは言え、細かな違いはあれども、一般的なCI/CDパイプラインにおいては、概ね以下のようなジョブが共通して実行されています。

なおツールの内部において、CIのジョブとCDのジョブは必ずしも区別されません。前述の通り、CIはコードをマージ可能にするための確認作業で、CDはデプロイの準備を整えることですが、これは概念上の区別であり、ツールから見ればどちらもコードが変更された際に実行するジョブの1つでしかないためです。そのため単一のパイプライン内でCIとCDの両方を連続して行うことは一般的ですし、場合によってはデプロイまでを一気通貫で実行することも珍しくありません。

コードのチェックアウト

何はなくとも、対象となるコードをリポジトリから入手しないことには始まりません。そのため、CI/CDパイプラインは最初にコードをチェックアウトするジョブを実行するのが一般的です。そしてチェックアウトのような普遍的な処理は、簡単に何度でも実行できるように通常はパッケージ化して提供されています。具体的な例を挙げると、GitHub Actionsでは「アクション」というジョブをパッケージ化して提供する仕組みが用意されており、以下のジョブ設定だけでコードをチェックアウトできます。

・GitHub Actionsのワークフロー(パイプラインから、チェックアウト部分のジョブの抜粋
jobs:
  test:
    steps:
      - uses: actions/checkout@v4

コードの静的解析

どのようなジョブをどのような順に実行するかは、パイプライン実装者の自由ですが、一般論として実行にかかるコストが低く、依存するジョブの少ないものから優先的に行うのが定石となっています。その中でも静的解析はコードのみがあればよく、ビルド等の作業が必要ないため、最初に行うのに適したジョブと言えるでしょう。

静的解析は、主に文法の間違いやコーディング規約違反などをチェックします。コードの複雑さなど、潜在的なバグとなりうる箇所を見つけてくれる解析ツールも存在します。また、この段階でインデントなどを揃える「コード整形」を実行することもあります。

アプリケーションのビルド

使用しているプログラミング言語にもよりますが、テストの前にビルドが必要となる場合があります。そうしたケースでは、テストジョブを実行する前段階で、ビルドジョブを実行します。

テスト環境へのデプロイ

後述するテストのうちのいくつかは、実際にアプリケーションをデプロイしないと確認できないため、この段階でテスト環境にアプリケーションをデプロイする場合があります。「継続的デリバリーでは、デプロイまでは行わない」と述べましたが、これはあくまで本番環境に対しての話です。テスト環境へのデプロイは、インテグレーションとデリバリーの一環として実施されることもあります。

アプリケーションのテスト

テストにも様々な種類がありますが、最も基本的なのが、プログラミング言語ごとに用意されたテストフレームワークなどを利用した「ユニットテスト」です。実際にどのようなテストを行うかはアプリケーションごとに異なってきますが、コードを書く以上は、どのようなアプリケーションであってもユニットテストは絶対に行うべきです。

その他にも、データベース等の外部リソースとの連携を確認する「インテグレーションテスト」や、動作中のアプリケーションに負荷をかける「パフォーマンステスト」などがあります。また専用のツールを用いて、ユーザーの操作を模倣したエンドツーエンドのテストを行う場合もあります。これらのテストはアプリケーションが動作していないと行えないため、実施前にはテスト環境へのデプロイジョブが実行されます。

アプリケーションのデリバリー

ここまでが主にCIに含まれる内容です。これらをパスしたら、本番環境へのデプロイの準備、すなわちデリバリーを行います。

デリバリーの具体的な内容は、アプリケーションのデプロイ方法によって異なるため、一概に「こうする」とは言えませんが、近年ではコンテナを使ってデプロイするケースが多く、その場合はコンテナイメージのビルドとコンテナレジストリへのプッシュを行うことになるでしょう。GitHub Acrionsでは、これらもコードのチェックアウトと同様に、再利用可能なアクションが用意されています。

CI/CDを実現するツール

CI/CDを実現するためには、専用のツールを用いるのが一般的です。

DevOpsの中核を成すのが、ソースコード管理システムです。CI/CDはソースコードへの変更をトリガーとして、ソースコードや、そこから生成される成果物に対して行われます。この性質から、CI/CDツールとソースコード管理システムの間には密接な関係があるため、ソースコード管理システムの一機能として、CI/CDツールが提供されていることも一般的です。

例えば、全世界で1億人以上が利用するソースコードホスティングサービスである「GitHub」には、CI/CDのワークフローを自動化する「GitHub Actions」という機能が用意されています。

また、同様のサービスである「GitLab」にも「GitLab CI/CD」という機能があります。これらは、どちらもCI/CDパイプラインが行うタスクを設定したファイルをリポジトリ内に含めるだけでCI/CDを動かすことができます。ソースコード管理システムが標準で備えている機能のため、既にこれらのサービスを利用しているのであれば、非常に導入しやすいのが特徴です。

ソースコード管理システムとは独立した、単独のCI/CDサービスも存在します。その中でも老舗で有名なのが「CircleCI」や「Travis CI」です。わざわざ独立したサービスを選択するメリットは、対応しているソースコード管理システムであれば、自由な組み合わせを実現できるという点です。ソースコード管理システムが備えているCI/CD機能よりも機能面で優れている点も多いため、要件や好みに応じてこうした外部サービスを選択するのも良い考えです。

社内のセキュリティポリシーや予算といった理由で、こうしたクラウドサービスが利用できないこともあるでしょう。そうした場合は、オンプレミスでホスト可能なCI/CDサービスの利用を検討しましょう。「Jenkins」はCI/CDの自動化を支援するツールとして広く利用されているオープンソースソフトウェアです。またGitHub ActionsやGitLab CI/CDでは、CI/CDパイプライン自体はクラウドサービス上で動かしつつも、実際のジョブは手元のサーバーで動かせる「Self Hosted Runner」をサポートしています。場合によっては、こうしたハイブリッドな構成を検討してみても良いでしょう。

おわりに

DevOpsのサイクルを回し続けていくには、自動化による省力化・高速化と、品質の担保の両立が必要です。そしてCI/CDなしに、これらを実現することは難しいでしょう。

幸いなことに、ソースコード管理システム、特にGitHubやGitLabを利用しているのであれば、CI/CDの導入はそれほど高いハードルではありません。もちろんCDまでを完全に自動化するには、ワークフローの見直しやインフラ側の整備といった作業が必要になることもあるでしょう。しかしソースコードの解析やテストなど、単体で完結するCI部分に関しては今日からでも取り組めるはずです。CI/CDの第一歩として、まずは現在手動で行っているテストを自動化する所から始めてみるのがお勧めです。

日本仮想化技術株式会社
Ubuntu Japanese Teamメンバー。理想のフリーデスクトップ環境を求めて東へ西へ……のはずが,気がついたら北の大地で就職していたインフラ寄りのエンジニア。最近レンズ沼にハマる。日本仮想化技術株式会社所属。

連載バックナンバー

設計/手法/テスト技術解説
第25回

AWSの監視サービス「CloudWatch」でサーバー監視を試してみよう

2024/8/9
本連載も今回で最終回となります。今回は、AWSの監視サービス「CloudWatch」を使って、簡単なサーバー監視を試してみましょう。
設計/手法/テスト技術解説
第24回

CI環境を構築して「ESLint」で静的解析を実行してみよう

2024/7/26
実践編第8回の今回は、「Dev Containers」でCI環境を構築し、静的解析ツール「ESLint」で静的解析を実行するまでの流れを解説します。
設計/手法/テスト技術解説
第23回

テストコードを書いて「GitHub Actions」でCIを実行してみよう

2024/7/12
実践編第7回の今回は、Webフロントエンド開発を例に、テストコードを書いて「GitHub Actions」でCIを実行するまでの流れを解説します。

Think ITメルマガ会員登録受付中

Think ITでは、技術情報が詰まったメールマガジン「Think IT Weekly」の配信サービスを提供しています。メルマガ会員登録を済ませれば、メルマガだけでなく、さまざまな限定特典を入手できるようになります。

Think ITメルマガ会員のサービス内容を見る

他にもこの記事が読まれています