メール送信を含む改修を本番に反映する直前、送信ボタンを押す前に手を止めて確認項目を見直している一人運用の保守担当者

メール誤送信を防ぐリリース手順|本番で顧客に飛ばさない確認項目

「このメール文面の修正、大した改修じゃないんですけどね」 「……でも、間違って全会員に飛んだらと思うと、手が止まる」

メールが絡むリリースは、他の改修と少しだけ違います。画面の不具合なら、気づいてから直せばいい。でもメールは、送った瞬間に自分の手を離れて外へ出ていきます。あとから「なかったこと」にはできません。宛先を間違えれば謝罪が要り、二重送信すれば問い合わせが増え、内容によっては社内報告の手続きまで発生します。

だから緊張するのは当然です。その緊張は、危機感が正しく働いているということでもあります。ただ、緊張だけで守り続けるのはしんどいですよね。深夜に一人で反映して、「送信されていないよな」と何度も確認しに戻る。そういう夜を減らしたいところです。

この記事では、注意力ではなく段取りで誤送信を防ぐ形を一緒に整理します。環境や構成で細部は変わりますが、順番はそのまま使えます。

結論:メール送信を含む改修は、「止める → 試す → 開ける」の3段で本番に通します。具体的には、①送信機能を止めた(送らない)状態でコードだけ本番に出す → ②自分や社内の宛先1件だけに実際に送って、宛先・差出人・文面・リンクを実物で確かめる → ③少量から順に開けて、送信ログと件数を見ながら全体に広げる。あわせて、検証環境からは物理的に外へメールが出ない仕組み(送信先を開発用の受け皿に固定する)と、1回の実行で一定件数を超えたら止まる上限を先に入れておきます。「気をつける」を仕組みに置き換えるのが、いちばん効きます。

一度に全部そろえなくて大丈夫です。この記事の中では、③の「少量から開ける」検証環境の出口をふさぐことの2つだけでも、効果がはっきり出ます。

何が起きているか:誤送信は「うっかり」より「段取りの穴」から起きる

メールの事故は、注意力が足りない人のところで起きるわけではありません。送信という処理が、他の処理と性質が違うのに、同じ手順で扱われているところで起きます。

普通の改修は「実行 → 確認 → おかしければ戻す」が成り立ちます。ところが送信は、戻すという操作が存在しません。だから、他の改修と同じ手順で通すと、確認のタイミングが1つ足りないまま本番に出ることになります。

現場で実際に起きやすいのは、だいたい次の5つの型です。心当たりがあっても、落ち込まなくて大丈夫です。どれも構造の問題です。

こうして並べてみると、どれも「気をつける」で防ぐのが難しいものばかりです。フラグの巻き戻りは目視では見えませんし、条件文の変更は正しく動いているように見えます。だから、手順の側で受け止めます。

本番への通し方:止める → 試す → 開ける

メール送信を含む改修を本番に反映するとき、送信を止める・自分宛の1通で試す・少しずつ開ける、の3段階を左から順に進めることを示した手順図
送信は戻せない。だから「止めた状態で出す→1通で試す→少しずつ開ける」の3段に分ける

急がなくて大丈夫です。この3段を、それぞれ確認を挟みながら進めます。

① 止める:送信を止めた状態で本番に出す

コードの反映と、メールが飛ぶことを同じ瞬間に起こさないのがこの段の目的です。反映した直後にバッチが動いて、確認する前に出ていってしまうのを避けます。

止め方は、環境にあるものでかまいません。

# 送信バッチを一時的に止める(該当行の先頭に # を付ける)
crontab -l > ~/crontab.$(date +%Y%m%d).bak   # 先に退避を取る
crontab -e

# 作業後、退避したものと見比べて戻せているか確かめる
diff <(crontab -l) ~/crontab.$(date +%Y%m%d).bak

止めた状態で反映したら、まず「本当に止まっているか」を確かめます。ここを飛ばすと、止めたつもりで流れます。送信ログが増えていないこと、キューが処理されずに積まれていることを、実際に見て確認します。

なお「止める」の対象には、リリースの前からキューに残っていた分も入ります。古いテンプレートで積まれたものが、新しいコードで一斉に流れることがあるためです。積まれている件数を先に数えておくと安心です。

② 試す:自分宛の1通で確かめる

止まっている状態のまま、送信先を自分(または社内の確認用アドレス)だけに絞って、実際に1通送ります。ここが要です。検証環境でどれだけ確認していても、本番でしか分からないことが残ります。

1通の実物で見る項目はこれだけです。

差し込み項目は、空になりやすいデータを選んで試すのがコツです。氏名が未登録の会員、住所が途中までしか入っていない注文。正常なデータだけで試すと、本番で初めて「様」だけが並んだメールが出ます。

送信先を絞る方法は、コードを書き換えるのではなく設定で切り替えられる形にしておくのが安全です。書き換えて戻し忘れるのが、そのまま事故になるためです。

③ 開ける:少しずつ、ログを見ながら

1通で問題がなければ、いよいよ開けます。ただし一気に全開にしません

  1. 上限を決めて開ける:まず10件、次に100件、というように段階を踏みます。送信件数の上限を設定値で持っておくと、この刻みが楽になります。
  2. 1段ごとに送信ログを見る:件数は想定どおりか。同じ宛先に2回出ていないか。エラーで失敗しているものはないか。
  3. バウンス(宛先不明で戻ってくるもの)を見る:急に増えていれば、宛先データの取り違えを疑います。
  4. 問い合わせ窓口に一声かけておく:「◯時からメール送信の反映をします」と伝えておくだけで、万一のとき最初の反応が早く届きます。
  5. 全開にしたら、しばらく手を離さない:最初の数分は画面を閉じないでおきます。

途中で少しでもおかしければ、すぐ止めて構いません。止めるのは失敗ではなく、この手順が正しく働いた証拠です。止めたあとに考える時間があるほうが、走り切ってから謝るよりずっと楽です。戻し方の考え方はロールバック手順の作り方と同じで、開ける前に「どう止めるか」を決めておくのがポイントになります。

事前の仕込み:検証環境から外へ出さない

ここまでの3段は当日の話でした。あわせて、普段の環境の側にも守りを1つ置いておくと、ぐっと楽になります。ねらいはひとつ、検証環境からは、間違っても外へメールが出ないようにすることです。

やり方はいくつかあります。どれか1つでかまいません。

ここで大事なのは、判定を1か所にまとめることです。送信処理があちこちに散らばっていると、どこか1つが守りをすり抜けます。まずは、送信処理の呼び出し口がいくつあるかを数えるところからです。

# メール送信の呼び出し口が何か所あるか、まず数える(関数名は環境に合わせて読み替え)
grep -rn -e "mail(" -e "sendmail" -e "smtp" /var/www/html --include="*.php" | wc -l

# どのファイルに散らばっているかを見る
grep -rln -e "mail(" -e "sendmail" /var/www/html --include="*.php"

数えてみると、思ったより多いことがあります。全部をすぐ1本にまとめる必要はありません。「新しく足すものは必ずこの1本を通す」と決めるだけでも、散らばりは止まります。設定を環境ごとに切り替える考え方は環境差の設定管理が参考になります。

もう1つ、送信件数の上限(それを超えたら止まる仕組み)も入れておくと効きます。「1回の実行で500件を超えたら送信せず中断して通知」といった形です。フラグ巻き戻りによる大量再送は、これがあるだけで被害の桁が変わります。バッチの異常に気づく仕掛けはcronバッチの失敗を見逃さない仕組みと組み合わせると、より確実になります。

具体例:会員向けお知らせメールの文面改修

よくある形を、順番にたどってみます。文面を少し直すだけの、小さな改修です。

この例で救われたのは②です。検証環境では正しく動いていたのに、本番の実物を1通見て初めて分かりました。もしこれを飛ばして全開にしていたら、8,000人に検証環境へのリンクを案内していたことになります。1通の確認が、そのまま8,000通分の安心になった形です。

そして、ベタ書きのURLが残っていたことは誰かの不注意ではありません。改修のたびに毎回見つかる種類の見落としです。だからこそ、毎回見る手順にしておく価値があります。

影響:3段の手順を持つと、何が変わるか

送信を含むリリースに手順を1つ持っておくと、事故の確率が下がるだけでなく、進め方そのものが軽くなります

なお、もし誤送信が起きてしまった場合は、まず止める → 送信ログで範囲を確定する → 関係者に一報の順です。内容によっては社内の報告手続きや、個人情報保護法にもとづく報告・通知の対象になることがあります。判断基準は自社の規程と個人情報保護委員会の公表資料で確認してください。第一報の伝え方は障害第一報のテンプレートが、証拠を消さない初動は不正アクセスが疑われるときの初動がそのまま使えます。

慌てないための備えとして、この順番だけ手元に置いておけば十分です。

明日やること:まず「出口」を1つ確かめる

全部そろえるのは大仕事です。明日できる、いちばん小さな一歩はこれです。

  1. 検証環境のメール送信設定を1行見る。SMTPの向き先が、外部の実サーバーになっていないかを確認します。外を向いていたら、それが今いちばん優先度の高い1件です。
  2. 送信処理の呼び出し口を数えるgrep -rn "mail(" ... を1回打つだけ。数が分かれば、守りをどこに置くかが決まります。
  3. 送信ログの残り方を確認する。「いつ・誰に・何を送ったか」が後から引けるか。引けないなら、まずログを1行足すのが先です。
  4. 次のリリース用に、止め方を1行メモする。「送信を止めるには、どのファイルの・どの設定を・どう変えるか」。この1行があるだけで、当日の判断が速くなります。
  5. 上限の値を決める。「1回の実行で何件を超えたら、いったん止まってほしいか」。数字を決めるところまでで、実装は後日でかまいません。

全部やらなくて大丈夫です。1番だけでも確かめておけば、いちばん起きやすい型は今日から遠ざかります。

メール送信を含むリリースのチェックリスト

反映の前後で確認する項目です。全部を毎回そろえる必要はありません。

まず外せない最低ラインはこの3つです。急いでいても、ここだけは押さえます。

次の項目は、余裕があるときや、対象件数が大きいときに追加で確認します。

全部に○が付かなくても大丈夫です。最低ラインの3つ、とくに「本番で1通試してから、少しずつ開ける」さえ守れれば、この作業はもう賭けではなくなります。

よければ、こちらも

メールに限らず、「出したら戻せない」種類の作業は、同じ考え方で軽くできます。あわせて少しずつ整えていくと効きます。

メール送信を含むリリースを段階的に進めて無事に完了し、送信ログを見ながら安心した表情を見せる一人運用の保守担当者

メールのリリースで手が止まるのは、慎重すぎるからではありません。取り消せないことを、ちゃんと分かっているからです。その感覚は、送信を扱う人として何より大事なものだと思います。

だから、必要だったのは覚悟ではなく順番でした。止めた状態で出して、1通で試して、少しずつ開ける。それだけで、押す瞬間の重さがずいぶん軽くなります。途中で止めていいと決めておけば、なおさらです。

まずは、検証環境の送信設定が外を向いていないか、1行だけ見てみるところから。今日その1行を確かめておけば、次にメールの改修が来たとき、いちばん起きやすい事故はもう手前で止まっています。

ほかの実務ヒントは記事一覧からどうぞ。保守運用の小さな備えを、メールでも少しずつお届けしています。

関連用語