手動デプロイが限界を迎えるとき:CI/CDが存在する理由
小さなバグを修正したとする。あなたは自分のラップトップでアプリケーションをビルドし直す。手動でテストを実行する——同じ画面をクリックして回り、同じ出力を確認する。それからビルドファイルをサーバーにコピーし、実行中のアプリケーションを停止し、古いファイルを置き換え、再起動する。もし手順を一つでも飛ばしたり、順序を間違えたりすると、アプリケーションはエラーを出す。あなたは最初からやり直し、どこで間違えたのか思い出そうとする。
さて、これを1日に5回行うことを想像してみてほしい。あるいは、5人のチームメンバーがそれぞれ自分の変更に対して同じことをしているところを想像してみてほしい。あるいは、データベースマイグレーションやインフラ構成にも依存しているアプリケーションを想像してみてほしい。手動プロセスは単に退屈なだけでなく、信頼性を失う。繰り返す頻度が高ければ高いほど、誰かが手順を忘れたり、コマンドを異なる順序で実行したり、疲れていたり急いでいたりしてミスをする確率が高まる。
これこそが、より良い方法を探し始める瞬間だ。自動化がモダンで印象的に聞こえるからではなく、変更が毎日または1日に複数回発生する場合、手動の繰り返しは機能しなくなるからだ。コードが変更されるたびに、ビルド、テスト、デプロイの各ステップが同じ順序で、同じコマンドを使って、同じ結果を生み出すことを保証する方法が必要になる。
核心の問題:再現性
手動デプロイの本当の問題はスピードではない。一貫性だ。手作業で何かを行うとき、あなたは自分の記憶、注意力、そして規律に依存する。これらはスケールしても信頼できるものではない。疲れた開発者はテストをスキップするかもしれない。急いでいるエンジニアはファイルを間違ったディレクトリにコピーするかもしれない。先週入社したばかりのチームメンバーは、他の全員が何ヶ月も前に覚えた正確な手順の順序を知らないかもしれない。
こうした小さな不整合は、デバッグが難しい問題を引き起こす。ある人のマシンでは動くアプリケーションがサーバーでは失敗する。データベースマイグレーションが既に実行済みであることを誰かが忘れて、二重に実行される。設定ファイルにタイポがあり、それが本番環境でだけ顕在化する。これらの問題のそれぞれを見つけて修正するのに時間がかかり、それぞれがデプロイプロセスへの信頼を損なう。
解決策は、プロセスをチェックする人を増やすことではない。解決策は、誰がトリガーしようと、一日のどの時間帯であろうと、毎回同じように実行されるプロセスに、その手順をコード化することだ。
CI/CDが実際に意味するもの
このニーズに対応する概念がCI/CDと呼ばれるものだ。しかし、頭字語の詳細に入る前に、それが解決する2つの異なる問題を理解すると役立つ。
継続的インテグレーション(CI) は次の問いに答える:「コードを変更した後も、それがまだ動作することをどうやって確認するのか?」コードの変更をプッシュするたびに、自動化されたプロセスがコードを取得し、ビルドし、テストを実行する。何かが壊れていれば、すぐにわかる——3日後に他の誰かがあなたのコードを使おうとしたときではない。これにより、フィードバックループが「リリース時にキャッチする」から「変更が行われた時にキャッチする」へとシフトする。
継続的デリバリー(CD) は次の問いに答える:「手作業を必要とせずに、変更を本番環境にリリースできる状態にしておくにはどうすればよいか?」CIチェックを通過したすべての変更は、パッケージ化され、デプロイの準備が整えられる。本番環境に実際にデプロイするかどうかの判断は依然として手動で行うことができる——承認が必要かもしれないし、特定の時間枠を待ちたいかもしれない。しかし、準備作業は自動化されているため、デプロイは意図的な選択であり、手動の苦行ではない。
継続的デプロイメント もある。これはCIを通過したすべての変更が自動的に本番環境にデプロイされる、より厳格なバージョンのCDだ。これは、不良デプロイのコストが低く、ロールバックが迅速なアプリケーションに適している。ほとんどのチームは継続的デリバリーから始め、強力な監視、迅速なロールバック、そしてパイプラインへの高い信頼性を確立した後にのみ継続的デプロイメントに移行する。
パイプライン:自動化された組立ライン
コードのプッシュからデプロイ可能なアーティファクトまで実行される一連の自動化ステップを パイプライン と呼ぶ。典型的なパイプラインは次のようになる:
- コードが共有リポジトリにプッシュされる。
- パイプラインがコードを取得し、ビルドを実行する。
- ビルド出力に対して単体テストが実行される。
- テスト環境に対して統合テストが実行される。
- セキュリティスキャンが既知の脆弱性をチェックする。
- ビルドがパッケージ化され、保存される。
- 最終確認のために、パッケージがステージング環境にデプロイされる。
- (オプション)パッケージが本番環境にデプロイされる。自動的に、または手動承認の後で。
各ステップは毎回同じ方法で実行される。パイプラインは疲れを知らない。誰かが急いでいるからといってステップをスキップすることはない。通常それを担当しているエンジニアが休暇中だからといって、データベースマイグレーションを忘れることはない。
以下の図は、コードコミットからデプロイまでの典型的なフローを示しており、テストが失敗した場合にはコードコミットに戻るループがある。
CI/CDではないもの
CI/CDはツールではない。SaaS製品にサブスクライブしたり、オープンソースのサーバーをインストールしたりすることでCI/CDを「買う」ことはできない。ツールはパイプラインを構築するのに役立つが、価値はどのツールを使うかではなく、どのようにプロセスを設計するかから生まれる。
CI/CDはスピードに関するものではない。デプロイの高速化は副次的な効果であり、目標ではない。本当の目標は信頼性と一貫性だ。自信を持ってデプロイできるようになると、より頻繁にデプロイするようになる。より頻繁にデプロイするようになると、各デプロイに含まれる変更が少なくなり、デバッグが容易になる。スピードはその自信から生まれるのであって、自動化自体から生まれるのではない。
CI/CDは銀の弾丸ではない。悪いプロセスを自動化しても、悪いプロセスがより速く実行されるだけだ。テストが不安定なら、パイプラインも不安定になる。デプロイの手順が十分に理解されていなければ、自動化によってその混乱がコード化される。自動化する前に、プロセスを適切に設計する必要がある。
パイプライン構築前の実用的チェックリスト
CI/CDのセットアップを始める前に、以下の条件を確認してほしい:
- テストが信頼できること。 テストがランダムに失敗するなら、パイプラインは無視されるようになる。
- ビルドプロセスが文書化されていること。 手順を文章で説明できなければ、自動化することもできない。
- デプロイ手順が把握されていること。 デプロイ時に何が起こるか正確に分かっているか?データベースマイグレーション、設定変更、サービス再起動を含めて。
- チームがプロセスに合意していること。 自動化は、全員が同じワークフローに従うときに最も効果を発揮する。ある人は直接mainにマージし、別の人はフィーチャーブランチを使っている場合、パイプラインはチームの習慣と戦うことになる。
まとめ
手動デプロイは、月に一度デプロイし、それを担当する人物がこれまでに50回同じことを行ってきた場合には機能する。しかし、変更が毎日発生し、チームが成長し、アプリケーションが複雑になるにつれて、機能しなくなる。CI/CDは、その手動の繰り返しを、毎回同じように実行される一貫性のある自動化プロセスに置き換えるために存在する。目標はより速くデプロイすることではない。目標は、すべての変更が毎回同じ方法でチェックされたという確信を持って、自信を持ってデプロイすることだ。