「防ぐより備えよ」
プロダクション環境へのデプロイ前の入念な準備は、システムの安定稼働を保証するうえで非常に重要です。Mike Tysonの名言「誰もが計画を持っているが、顔面を殴られるまではね」を思い出しますが、だからといって準備が無駄なわけではありません。困難な状況に陥ったとき、準備をしていることで有利に進められます。
1️⃣ 常にクリーンなコードを意識する
クリーンなコードは、あらゆる状況で推奨されるべきものです。プロダクションへのデプロイをより安全に行うために、コードが整理され、分かりやすい状態であることが大切です。これは、他者がコードを引き継いだ場合や、あなた自身が修正する場合にも役立ちます。特にプロダクション環境では、時間が非常に貴重です。1分の遅れが大きな問題を引き起こすこともあります。私は、チームメンバーのコードをデプロイし、プロダクションでエラーに遭遇した経験が何度もあります。その際、本人に電話をしても対応できないことがあり、自分でコードを見て即座に修正しなければならないことも。そんな時、コードが分かりにくいと修正に時間がかかり、クライアントからの問い合わせも増えてしまいます。
2️⃣ 防御的プログラミング(Defensive Programming)を実践する
私は「The Pragmatic Programmer(実践プログラマー)」という本で紹介されている防御的プログラミングの考え方が非常に好きです。この手法を身につけることで、予期せぬエラーや環境の変化にも柔軟に対応できます。インドのエンジニアのコードは冗長で複雑なことが多いですが、エラー処理がしっかりしており、安定して動作している印象があります。
3️⃣ 可能な限りユニットテストを活用する
コードに問題が発生するまで、誰もコードを見てくれないものです。エラー処理能力を自ら身につけ、コードを書く段階からテストを実施することが重要です。ユニットテストを活用することで、一部のバグ修正時にシステム全体を再テストする必要がなくなり、バグの連鎖(デグレード)を防げます。さらに、ユニットテストは思考力や予測力のトレーニングにもなります。テストカバレッジが高いほどバグは減り、プロダクションへのデプロイも安心して行えます。
4️⃣ ログ記録の習慣をつける
ログ記録は、開発中からプロダクション環境まで非常に役立ちます。プロダクション環境でデバッグモードを有効にするのは絶対に避けてください。例外やシステムの動作情報をログに記録しておくことで、問題発生時の調査が非常に楽になります。また、ログがあることで、問題が自分のコードではなく他の箇所にあることを証明する根拠にもなります(ただし、ログ記録自体がエラーを引き起こすこともあります。私はLaravelとDockerでログファイルへの書き込みができず、システムが落ちた経験があります)。
5️⃣ 可能ならCI(継続的インテグレーション)を導入する
CIを導入することで、コードレビューや自動テストなど、普段は面倒でやりがちな作業を自動化できます。CIの活用により開発スピードが向上し、より良いコードを書く時間も増えます。
6️⃣ デプロイ用チェックリストを作成する
デプロイ用のチェックリストを作成することは非常に重要です。デプロイ前・中・後の各ステップをリスト化しておくことで、重要な手順を忘れることがなくなります。また、各ステップにかかる時間も把握できます。私が参加したプロジェクトでは、クライアントからチェックリストの作成を求められることが多く、デプロイの進捗を共有することで信頼を得られました。クライアントが要求していなくても、自発的にチェックリストを提供することで、DevOpsとしての専門性をアピールできます。
7️⃣ プロダクション環境の前にDev/Test/Staging環境を準備する
プロジェクトの要件やリソースによりますが、重要なプロジェクトやDevOpsが十分に活用できる場合は、開発・テスト・ステージング環境を分けて運用することをおすすめします。ステージングサーバーでコードが正常に動作することを確認してから、プロダクション環境へデプロイしてください。
8️⃣ デプロイ用のワークフローとパイプラインを作成する
基本的にワークフローやパイプラインはチェックリストと似ていますが、より技術的な側面が強いです。パイプラインでは、各ステップが完了しないと次のステップに進めないようになっています。たとえば、自動テストが失敗した場合は、テストサーバーへのデプロイができません。パイプラインはステップ・バイ・ステップの流れであり、チェックリストは並列や順不同で実施できるリストであることを理解しておきましょう。