アプリケーションは実際にどこで動作するのか
ラップトップでアプリケーションを書き終えたとしよう。すべての機能が動き、エラーもない。満足している。しかし、使えるのはあなただけだ。そのマシンの上だけだ。他の誰かに試してもらおうと思った瞬間、シンプルな疑問が浮かぶ。このアプリケーションは、実際にどこで動作するのか?
この疑問こそが、環境を理解するための出発点だ。環境とは、アプリケーションが動作する場所のことである。その場所は、あなたのラップトップかもしれないし、同僚のコンピュータ、オフィスのサーバー、あるいはデータセンターにあって何千人もの人がアクセスするマシンかもしれない。それぞれの場所には異なる特性があり、その違いは重要だ。
ローカル環境:安全なサンドボックス
アプリケーションがまだラップトップ上にあるとき、それはローカル環境にあると呼ばれる。ここでは、実験するための完全な自由がある。コードを変更し、アプリケーションを再起動し、すぐに結果を確認できる。アプリケーションがクラッシュしても、他の誰にも影響はない。ローカル環境は、新しいことを試すのに最も安全な場所だ。
しかし、アプリケーションが永遠にラップトップに留まることはない。いつかは、自分の作業をチームに見せたり、新しい機能が既存の機能と一緒に正しく動くかテストしたりする必要が出てくる。
次のフローチャートは、アプリケーションが各環境を通過する典型的な流れを示しており、それぞれに明確な目的がある。
開発環境:コードが出会う場所
チームでのコラボレーションのために、ほとんどのチームは開発環境を用意する。これは、複数の開発者が自分のコードを統合する共有サーバーだ。アプリケーションは実際のサーバーに近いマシン上で動作するが、まだ実際のユーザーが使っているわけではない。
開発環境は、異なる人々の異なるコードが初めて一緒に共存しようとする場所だと考えてほしい。ここで、自分の変更が誰かの変更と競合することや、自分が使ったライブラリのバージョンが共有サーバーに存在しないことを発見する。これらの発見は貴重だ。なぜなら、他の誰かがアプリケーションに依存する前に、早期に発見できるからだ。
ステージング環境:本番リハーサル
アプリケーションがユーザーに近づくほど、より慎重に保護する必要がある。ユーザーに届く前に、通常はステージング環境がある。ステージングは、アプリケーションが実際にユーザーにサービスを提供する場所に可能な限り近づけて構築される。
チームはステージングを使って、新しいバージョンが正常に動作するか、既存のデータとの競合がないか、パフォーマンスが許容範囲かどうかを確認する。問題があれば、ユーザーの前ではなく、ステージングで見つけたい。ステージングは、デプロイプロセス全体を実行し、データベースマイグレーションをテストし、監視ツールが期待通りに動作するかを検証する場所だ。
本番環境:ユーザーがいる場所
最後に、本番環境がある。ここで実際のユーザーがアプリケーションとやり取りする。ここで何かがうまくいかないと、ユーザーが影響を感じる。本番環境は最も注意深く守られた環境だ。誰もがそこで何かを変更できるわけではなく、すべての変更は明確なプロセスを経る必要がある。
本番環境には、厳格なアクセス制御、詳細なログ、包括的な監視が設定されていることが多い。本番環境への変更には、通常、承認、変更チケット、ロールバック計画が必要だ。失敗のコストには、不満を抱えたユーザー、失われた収益、損なわれた評判が含まれるため、リスクは高い。
環境の違いが重要な理由
ここに、多くのチームを不意を突く重要なポイントがある。すべての環境は異なる場所なのだ。あなたのラップトップで動作するアプリケーションは、ステージングで動作するアプリケーションと必ずしも同じではない。ましてや本番環境とはなおさらだ。
違いは多くの原因から生じる。
- コードバージョン:どのブランチがデプロイされているか?どのコミットか?コミットされていない変更はあるか?
- 設定:データベース接続文字列、APIキー、フィーチャーフラグ、環境変数は、環境によって異なることが多い。
- データ:開発データベースにはテストデータがあるかもしれないが、本番環境には異なるボリュームとパターンを持つ実際のユーザーデータがある。
- システム依存関係:オペレーティングシステムのバージョン、インストールされているライブラリ、カーネルパラメータ、さらにはタイムゾーンの設定も異なる可能性がある。
- ネットワークトポロジ:ロードバランサー、ファイアウォール、DNS設定、証明書の構成が異なる。
これらの違いが蓄積すればするほど、他の環境では決して現れなかった問題が本番環境で発生する可能性が高くなる。ラップトップでは完璧に動作する機能が、本番データベースの文字エンコーディングが異なるために本番環境で失敗する。ステージングでは問題なく実行されるマイグレーションが、本番テーブルに数百万行ものレコードがあるためにタイムアウトする。
DevOpsの目標:環境間の一貫性
これが、DevOpsチームがすべての環境を可能な限り類似させるために努力する理由だ。目標はシンプルだ。アプリケーションがステージングでうまく動作すれば、本番環境でもほぼ間違いなくうまく動作する。一貫性は驚きを減らす。
この一貫性を達成するには、環境をコードとして扱う必要がある。サーバー設定、インストール済みパッケージ、システム設定は、各マシンで手動で構成するのではなく、バージョン管理されたファイルで定義する必要がある。Dockerのようなコンテナ化ツールは、アプリケーションを実行時環境と一緒にパッケージ化することで、アプリケーションが動作する場所の違いを減らすのに役立つ。
しかし、一貫性だけでは十分ではない。各環境に何を送っているのかを正確に理解する必要もある。それは生のソースコードではない。それは処理され、実行可能な状態になったものだ。その処理された出力はアーティファクトと呼ばれ、実際にデプロイされるものだ。
環境管理のための実践的チェックリスト
先に進む前に、現在の環境設定を評価するためのクイックチェックリストを紹介する。
- ローカルから本番まで、アプリケーションが通過するすべての環境をリストアップできるか?
- 各環境について、その目的、アクセス方法、設定が文書化されているか?
- 環境固有の設定はコードから分離して保存されているか?
- 自動化されたスクリプトや設定ファイルを使って、どの環境でもゼロから再現できるか?
- 本番環境の前にステージング環境でデプロイをテストしているか?
- 各環境に誰がデプロイできるかについて、明確なプロセスがあるか?
具体的なポイント
あなたのアプリケーションは「サーバー」上で動作するわけではない。それは、独自の設定、データ、依存関係を持つ特定の環境で動作する。各環境の目的と制限を理解することで、より良いデプロイプロセスを設計し、問題を早期に発見し、あなたのマシンでコードが動く場所とユーザーのためにコードが動く必要がある場所とのギャップを減らすことができる。まずは、現在の環境を文書化し、それらの間の違いを特定することから始めよう。それだけで、あなたが知らなかったリスクが明らかになるだろう。