待って!そのデプロイ本当に大丈夫?✋

全国100万人のエンジニアの皆さんこんにちは、デプロイしてますか?
この記事は、本番環境でやらかしちゃった人 Advent Calendar 2019の5日目の記事です

予想以上にこのアドベントカレンダーが注目されてて、書きながら「これ炎上しないよね…」「なんかマズイこと書いてないよな…」と胃が痛くなってます
自分みたいなザコメンタルにはつらい…めっちゃやむ…

この記事はただの不注意が原因のやらかし話です
過度な期待はしないで下さい

追記

さすが3000人以上に購読されてるアドベントカレンダー、アクセス数がすごいことになってますね…怖い…

いくつかコメントや言及を頂いたので、追記というのをしておきます

  • テスト環境ないの?
    • あります
    • タスクAに関してはテスト環境での動作チェックが不十分だった
    • タスクCに関しては焦ってて動作確認せずに出しちゃった(「まぁこれくらいの変更なら大丈夫でしょ」というやつ)
    • あと、アクセスの数%だけが来る本番とは別の本番環境なんかもあるんですが、タスクAのエラーはここでは引っかからなかった
  • CI環境ないの?
    • あります
    • タスクAに関してはテストは通ってたので、テストが十分でなかったということになりますね
    • タスクCに関しては焦ってて(ry
  • レビューした人がマージすれば/デプロイ担当の人を用意すれば
    • これに関しては「うーん…」って感じですね
    • 1日に数十回のマージ/デプロイが走ってるので、それをやろうとすると担当の人の負荷がすごいことになりそうです
  • レビュー通ってないpull reqはマージできないようにしないの?
    • これが本質な気がしてきた
    • 説明するのが面倒&本質じゃないので省いたんですが、実は使ってるのはGitLabなのでpull reqestじゃなくてmerge request
    • GitLab、調べたらapproveもらわないとmergeできない機能は有料版しかないみたいですね
    • うちはどうやら無料版(GitLab Core?)を使ってるみたいです
      • とはいえ、再発防止という面では「システムを改善する」という方向のほうが大事ですよねー
      • お金が絡むのですぐには無理ですけど、ここは改善すべき点ですね

背景

  • いわゆるWeb系のサービスをやっている会社
    • PHPとかRubyとか (この記事ではPHP)
    • 落ちたりするとTwitterで騒がれるくらいには大きいサービス
  • 自分はフルリモートでアルバイト中
    • 自宅と会社が400kmくらい離れてる
  • デプロイは1日に数十回走っている
    • 基本的にpull req出した人がマージ&デプロイ
    • masterへのマージと本番へのデプロイは基本的にセット

アルバイトでもドンドン挑戦させてもらえる素晴らしい環境だと思います

事案発生

  • その日、2つのタスク(タスクA, タスクB)を進めていた
  • タスクAの実装が完了して、pull reqを出してレビュー依頼
    • これは罠で、稀に特定のパターンでエラーとなることが後で分かった
    • PHPUnit通ってるし大丈夫でしょ」←大丈夫ではない
    • 単純に動作確認が足りてなかった
  • その後タスクBの実装も完了したので、こちらもpull reqを出してレビュー依頼
    • こっちはちゃんと動作するコード
  • レビュー待ちの間に、以前やっていた別のタスクCの後処理をポチポチ
    • かなり大きいコード削除をやって、その後変なところでログが上がってないか確認するという感じ
    • タスクAは、その以前やっていたタスクCの続きだった ←これが後の<やらかし>の遠因に
  • タスクC絡みの変なnoticeが少し上がっていたので、直してpull reqを出した
    • これも罠で、プログラムとしてそもそも動かないコードだった
    • 「ちょっとnotice解消するぐらいだし、大丈夫やろ」←はい慢心
  • レビュアーがタスクBのpull reqのレビューOKとのことで、そのままマージすることに
  • ここでタスクBのははずが、間違えてレビュー通っていないタスクAのpull reqをマージ→デプロイしてしまう
    • この時、エディタ3つとブラウザ2つのウィンドウが開いていてごっちゃになっていた
    • そう、タスクAのpull reqは特定のパターンでエラーとなるコードです
    • 直前に関連するタスクCをやっていたのも混乱の原因に
  • 大量に上がるエラー、急いでrevert&rollback
    • この時点では、マージするpull reqを間違えたと気がついていない
    • ここで気がつけばまだ「間違えました、すいません」で済んだ(と思う)
  • 焦って「次こそは大丈夫」とぶっ壊れているタスクCのpull reqをマージ→デプロイ
    • ここでもマージするpull reqを間違えていると気がついていない
  • さっきより酷い状態に
    • 荒れ狂うエラーログとアラート
    • 数分間、関連サービスがすべて500エラーで真っ白になる
    • ここで自分の頭も真っ白になる
      • 半泣きになりながら、とりあえずrevertしてrollbackはした
    • 普通ならここで周りの人に助けを求めるのが正解だと思うが、フルリモートなので周りには誰もいない

全部revert&rollbackして、落ち着いてゆっくり振り返りながらエラーを修正して後日改めてやり直しました

なぜ起こったか/二度と繰り返さないために

  • 自分のキャパシティを超える量の並行作業
    • 複数のタスクを受け持つのは良いけど、順に一つづつやろう
    • ただでさえ自分は凡ミスが多いのに、そんなことをしたらダメになるのは当たり前
  • 作業する際は、関係ないウィンドウを閉じよう
    • 単に作業領域の整理整頓をちゃんとしようという話
    • 「後で見るから…」はだいたい見ない、今見てないなら一旦消す
    • ブラウザのタブは後で履歴から開けばいいし、最近のエディタは開いたら以前のタブを復元してくれる
  • 待って!そのデプロイ本当に大丈夫?✋
    • マージするブランチ間違えてない?
    • デプロイ先間違えてない?
    • それ本当に意図した操作?
  • やらかした後は、落ち着いてちゃんと確認を行う
    • 焦ったらアウト、とりあえずrollbackして深呼吸
    • これ以降、デプロイ前後に小休止を入れるようにした

今回は1つ1つは些細な要因だけど、組み合わさって大変な事になりました

  • 操作ミス
  • 確認忘れ
  • 焦り
  • 慢心

あと、フルリモートなので周りにヘルプを出せないのもつらいですね

これを機に、いかにミスなく効率よく仕事をこなすかというのを少し意識するようになりました
プログラミングとは違うと思うんですがこれも立派なエンジニアリングですし、こういう「仕事をちゃんとこなす」というのは面倒だけど大事ですよね

最後に

事故は誰にでも起こりえます
皆さんお互いに気をつけましょう

明日はsoh1945さんのやらかしのお話です
「おとぎの国のデスマ中に起こった事を少し」とのことですが、人間は焦るとやらかしがちになるので気をつけたいですね
どんなお話か楽しみです