コードが実際に実行される場所:環境を理解する
アプリケーションのビルドが完了し、テストが通り、成果物がレジストリに安全に格納されました。次に、すべてのチームが直面する疑問があります。「これを実際にユーザーが使えるようにするには、どこに配置すればよいのか?」
単純な答えは「サーバー上」です。しかし、その一言では隠れた重要な現実が見えません。アプリケーションは実際のユーザーに届くまでに、複数の異なる場所で動作する必要があります。それぞれの場所には異なる目的があり、それらをすべて同じように扱うと、リリースの失敗やユーザーの不満につながります。
最初の場所:開発環境
コードを書いているときは、自由に実験できるスペースが必要です。これが開発環境です。多くの開発者にとって、これは自分のラップトップから始まります。アプリケーションをローカルで実行し、変更を加え、壊し、修正し、繰り返します。他の誰もそのインスタンスを使用していないため、影響を受ける人はいません。
チームによっては、共有の開発サーバーを使用することもあります。複数の開発者がコードを共通のマシンにプッシュし、本番環境に出す前に統合をテストします。どちらの場合もルールは同じです。データはダミーでよく、クラッシュは許容され、安定性は目標ではありません。目的は探索と反復です。
開発環境はリスクが低いと感じられるべきです。1時間に10回アプリケーションを再起動する必要があっても問題ありません。誤ってデータベースを削除しても、ダミーデータのバックアップから復元して続行できます。この自由度は、開発中の迅速な動作に不可欠です。
成果物がこれらの環境を経由する経路は次のようになります。
ほぼ本番の場所:ステージング環境
ある時点で、コードは実際の世界に近い条件で生き残れることを証明する必要があります。ここでステージング環境が登場します。
ステージング環境は、本番環境を可能な限り忠実に再現するように設計されています。サーバー設定は一致し、データベースのバージョンも同じである必要があります。アプリケーションの起動方法、サービスへの接続方法、リクエストの処理方法はすべて、本番環境と同じでなければなりません。唯一欠けているのは、実際のユーザーと実際のデータです。
この環境が存在する理由はただ一つ、問題がユーザーに届く前に発見することです。マイグレーションが失敗すれば、ステージングで気づきます。設定が間違っていれば、ここで発見します。新しい機能が現実的な負荷の下で壊れるなら、誰かが苦情を言う前に確認できます。
チームはしばしば、ステージング環境を本番環境から乖離させてしまうミスを犯します。ステージングサーバーのメモリが少なかったり、異なるデータベースエンジンを使用していたり、古いバージョンのOSを実行していたりします。これらの違いは目的を無効にします。ステージングが忠実なレプリカでなければ、そこで実行するテストは本番環境で何が起こるかをほとんど教えてくれません。
実際の場所:本番環境
本番環境は、アプリケーションが本来の目的を果たす場所です。実際のユーザーが実際のリクエストを送信します。実際のデータが処理、保存、返却されます。すべての変更には実際の結果が伴います。
リスクが高いため、本番環境は異なる方法で管理されます。アクセスは制限され、変更はより多くのレビューを受け、デプロイメントはより厳格な手順に従います。本番環境で実験してはいけません。未テストのコードをプッシュしてはいけません。影響を理解せずにアドホックな設定変更を行ってはいけません。
開発速度と本番安定性の間の緊張は、すべてのエンジニアリングチームにおける絶え間ない力です。迅速に動きたい一方で、サービスを稼働し続ける必要もあります。環境は、異なるリスクレベルに対して異なるスペースを提供することで、この緊張を管理するのに役立ちます。
同じ成果物、異なる場所
スムーズなデプロイメントと混沌としたデプロイメントを分ける原則があります。それは、同じ成果物がステージング環境と本番環境で実行されるべきだということです。
これは明白に聞こえますが、多くのチームが気づかずにこれに違反しています。ステージング用にアプリケーションをビルドし、テストを実行し、その後本番用に再度ビルドします。本番ビルドでは異なるフラグが使用されるかもしれません。依存関係が微妙に異なる解決方法を取るかもしれません。誰かがステージングで何かを手動でパッチしたが、本番ビルドに同じ修正を適用するのを忘れるかもしれません。
成果物が環境間で変わると、ステージングテストは無意味になります。バージョンAをテストしたのに、バージョンBをデプロイしたことになります。ステージング実行から得た自信は、誤った自信でした。
修正方法は簡単です。一度ビルドし、同じ成果物を環境間で昇格させます。ステージングでテストに合格したバイナリまたはコンテナイメージは、本番環境に送られるものとまったく同じものです。再コンパイルは不要。異なるフラグも不要。手動パッチも不要。同じ成果物を異なる場所にデプロイするだけです。
環境ごとのデプロイ方法の違い
すべての環境を同じ方法でデプロイすべきではありません。注意と儀式のレベルはリスクに一致させる必要があります。
開発環境では、コミットごとに自動的にデプロイできます。障害のコストが低いため、プロセスは迅速かつルーズで構いません。チームによっては、正式なデプロイメントを完全にスキップし、最新のコードでアプリケーションを再起動するだけの場合もあります。
ステージング環境では、通常、基本テストが合格した後にデプロイします。プロセスは自動化されるべきですが、いくつかの検証手順を含めることもあります。成果物がステージングサーバーに到達する前に有効であることを確認したいところです。
本番環境では、デプロイメントには多くの手順が含まれることがよくあります。承認が必要だったり、トラフィックの少ない時間帯にデプロイをスケジュールしたり、新しいバージョンに徐々にトラフィックを移行する段階的なロールアウトを使用したりする場合があります。正確なプロセスはアプリケーションのリスクプロファイルによって異なりますが、パターンは一貫しています。実際のユーザーに影響を与える環境には、より多くの注意を払います。
環境の一貫した管理
各環境は、再現可能な方法で管理する必要があります。ステージングサーバーのセットアップに本番環境とは異なるプロセスが必要な場合、問題を引き起こす可能性のある変数が導入されます。
目標は一貫性です。成果物の配置方法、アプリケーションの起動方法、実行確認方法は、環境間で同じであるべきです。唯一の違いは、データベースURL、APIキー、フィーチャーフラグなどの設定値だけです。
環境が一貫して管理されていないと、奇妙なバグが発生します。「ステージングでは動いたのに」という言葉がよく聞かれるようになり、同じ成果物が本番環境で失敗すると混乱が生じます。十中八九、違いはコード自体ではなく、環境の設定方法にあります。
環境管理の実践的チェックリスト
- 各環境には明確な目的があり、チームによって文書化され理解されている
- ステージング環境は、設定、依存関係、インフラストラクチャにおいて本番環境をミラーリングしている
- 同じ成果物バイナリがステージングから本番環境に昇格される
- デプロイメントプロセスは自動化され、環境間で再現可能である
- 環境固有の設定はアプリケーションコードから分離されている
- 本番環境へのアクセスは制限され、ログに記録される
- ステージング環境は、本番環境のパターンに似たサニタイズデータまたは合成データを使用する
次に来ること
成果物は適切な環境に配置されました。ステージングでテストされ、本番環境に昇格されました。しかし、サーバー上に存在するだけでは、ユーザーがまだそれを見ているとは限りません。次のステップは、新しいバージョンが実際にトラフィックを処理し始めるタイミングを決定することです。デプロイメントとリリースの間のこの瞬間が、多くのチームにとって次の一連の課題となる場所です。