CI/CDとは ― DevOpsとの関係とパイプライン
CI/CDは、
CI/CDとは、変更を本番に届けるまでを自動で流す仕組み
コードを直すたびに、手でビルドしてテストし、サーバに置く作業を繰り返すと、手間も誤りも増えます。CI/CDは、この流れを、ビルドとテストから本番への反映まで自動で進める仕組みです。CIは、変更の統合とテストを自動にする部分です。CDは、その先のリリースに向けた段階を自動にする部分です。
CIは、継続的インテグレーション(Continuous Integration)の略です。CDは、継続的デリバリー(Continuous Delivery)の略です。継続的デプロイ(Continuous Deployment)を指すこともあります。2つのCDの違いは、本番に出す直前で人が承認するかどうかです。
継続的インテグレーション(CI)は、小さく頻繁に統合するやり方
チームのコードは、リポジトリという共有の置き場に集めます。変更をリポジトリに登録することを、以下ではコミットと呼びます。複数の人の変更を1つにまとめることを、統合と呼びます。
CIでは、開発者が自分の変更を、少なくとも毎日リポジトリに統合します。統合するたびに、自動でビルドとテストが走ります。Martin Fowlerは、この流れで統合の誤りをできるだけ早く見つけることを、CIの目的に挙げています。
ビルドとは、ソースコードを、動かす環境で実行できる形に変換する工程です。テストは、変換したものが期待どおりに動くかを、プログラムで確かめる工程です。
小さく頻繁に統合するのは、統合の間隔が長いほど、まとめるコードが増えるからです。Fowlerは、何週間も気づかれなかった変更の衝突は、解消するのが非常に難しいと書いています。毎日統合すれば、衝突は1日分の変更の中で見つかります。
継続的デリバリーと継続的デプロイの違いは、本番に出す直前の承認
継続的デリバリーとは、CIのあとの変更を、いつでも本番に出せる状態まで自動で進める方式です。本番に出す操作は手作業で、人が承認してから出します。NISTはこれを、ボタンを押せばいつでも配置できる状態と説明しています。
継続的デプロイとは、テストに通った変更を、本番まで自動で出す方式です。人の承認を待たないので、変更はすぐに利用者に届きます。Fowlerは、継続的デプロイをするには継続的デリバリーができている必要があると書いています。
Fowlerは、継続的デリバリーでも頻繁に本番に出せる一方、出さないことも選べると説明しています。出さない理由の多くは、ビジネス側がゆっくりした頻度を好むことです。
| 方式 | 自動で | 本番に |
|---|---|---|
| 継続的 | ビルドと | 担当者が |
| 継続的 | ステージングまで | 人が |
| 継続的 | 本番まで | テストに |
次の図で、方式を切り替えて、各段が自動か人の手かを比べます。「テストが失敗した場合」を押すと、テストの段で止まったときの様子に変わります。
- コミット開発者が
送る - ビルド自動
- テスト自動
- ステージング手作業
- 本番手作業
- コミット開発者が
送る - ビルド自動
- テスト自動
- ステージング自動
- 本番人が
承認して 反映
- コミット開発者が
送る - ビルド自動
- テスト自動
- ステージング自動
- 本番自動
- コミット開発者が
送る - ビルド自動
- テスト失敗して
止まる - ステージング進まない
- 本番進まない
- コミット開発者が
送る - ビルド自動
- テスト失敗して
止まる - ステージング進まない
- 本番進まない
- コミット開発者が
送る - ビルド自動
- テスト失敗して
止まる - ステージング進まない
- 本番進まない
パイプラインの段階と、失敗したら止まる仕組み
パイプラインとは、コミットから本番までの段を、順に自動で起動する1本の流れです。NISTは、段ごとに作業を個別に始める代わりに、最初の段から次の段を自動で起動する流れと説明しています。コミットを受けて起動するときは、リポジトリのサービスが送るWebhookの通知をきっかけにする方法があります。
- コミット:開発者が変更をリポジトリに登録し、パイプラインが起動する
- ビルド:ソースコードを、実行できる形に変換する
- テスト:変換したものを、自動のテストで確かめる
- ステージング:本番に近い環境に置き、動作を確かめる
- 本番:利用者が使う環境に反映する
テストで失敗したときに止める設定にしておくと、問題のある変更は先の段へ進みません。開発者は結果を受け取り、直してからもう一度コミットします。Fowlerは、統合のビルドが失敗したらすぐ直すよう書いています。また、多くの場合は原因の変更を取り消すのが早いと書いています。
NISTによると、失敗しても記録だけして続ける設定も選べます。どちらにするかは、組織がどこまでの危険を受け入れるかで決めます。前の節の図は、止める設定の場合を示しています。
最後の本番の段では、新しい版への切り替え方も決めておきます。サービスを止めずに切り替える方法は、ブルーグリーンデプロイとカナリアリリースの記事で比べています。
パイプラインを動かすツールには、GitHub Actions、GitLab CI/CD、Jenkinsなどがあります。これらのツールでは、段の並びと各段の作業を、コードとしてファイルに書いて定義できます。AWSでインフラの構成をテンプレートに書いて作る方法は、CloudFormationの記事で説明しています。パイプラインで作ったイメージを決めた数だけ動かし続ける仕組みは、Kubernetesの記事にあります。
DevOpsとの関係は、考え方とそれを支える仕組み
DevOpsとは、開発チームと運用チームが連携し、迅速かつ柔軟にソフトウェアを開発する考え方です。名前は、開発のDevelopmentと運用のOperationsを合わせたものです。CI/CDは、この考え方を支える代表的な自動化の仕組みの一つです。
NISTは、DevOpsの流れを2つの向きで説明しています。前向きは、ビルドからリリースまでを運ぶパイプラインです。逆向きは、本番を監視して次の計画に生かす流れです。
SREは、運用チームの仕事を、ソフトウェアエンジニアの手法で設計する考え方です。Googleは、SREをDevOpsの具体的な実装の一つと見ることもできると説明しています。SREが目標に使うSLOは、可用性とSLAの記事で説明しています。SLOから求めるエラーバジェットで、リリースを止めるかを判断する方法は、SLA・SLO・SLIの記事にあります。
DevSecOpsは、DevOpsの流れにセキュリティの検査を組み込み、自動化する考え方です。NISTは、開発・セキュリティ・運用の3つを合わせたものと説明しています。
アジャイル・テスト駆動開発との関係
アジャイルは、迅速かつ適応的にソフトウェアを開発する、軽量な開発手法です。CIは、アジャイルの手法の一つであるXPの一部として生まれました。XPは、エクストリームプログラミングの略です。
テスト駆動開発は、先にテストを書き、そのテストが通るようにコードを書く進め方です。略してTDDと呼びます。TDDも、CIと同じくXPで使われる手法です。
CI/CDのメリットと注意点
メリット
- 変更を小さく頻繁に出せるので、1回の変更で壊れる範囲が小さくなる
- 統合とテストが毎回自動で走るので、不具合を早く見つけられる
- 本番に出す手順が毎回同じになり、手作業の誤りが減る
注意点
- パイプラインを作り、保守する手間がかかる
- テストが足りないと、問題のある変更もそのまま先の段へ進む
- パイプラインが本番環境を変更できるため、パイプライン自体の権限の管理が要る
NISTは、本番までの時間の目標を立てる一方で、内部の不正のような危険も抑えるよう求めています。その手段として、変更を取り込む前に複数の人が承認する仕組みを挙げています。
参考にした資料
- Martin Fowler「Continuous Integration」(2024年1月改訂)
- Martin Fowler「ContinuousDelivery」・「TestDrivenDevelopment」
- NIST Special Publication 800-204C「Implementation of DevSecOps for a Microservices-based Application with Service Mesh」(3.3.1 Concept of Pipelines and the CI/CD Pipeline、3.3.4 Strategies for Automation)
- Google「Site Reliability Engineering」Introduction
- Principles of Chaos Engineering
練習問題(全6問)
正解:開発者の
CIは、
正解:継続的デリバリーは
継続的デリバリーは、
正解:継続的デリバリーが
継続的デプロイでは、
正解:テストの
止める
正解:開発チームと
DevOpsは、
正解:DevSecOps
DevSecOpsは、
選んでから「採点する」を押すと、解説つきで答え合わせができます。