ひとことで言うと#
本番環境で発生する定型的な運用作業やインシデント対応の手順をステップバイステップで文書化したもの。誰がオンコールを担当しても同じ品質で対応できることを目指し、属人化を排除して対応時間を短縮する。
押さえておきたい用語#
- ランブック(Runbook)
- 特定の運用タスクやインシデントに対する具体的な手順書。「いつ」「何を」「どの順番で」実行するかを誰でも再現可能な形で記述する。
- プレイブック(Playbook)
- ランブックより広い概念で、判断基準やエスカレーションルールを含む対応方針書。ランブックが「手順」ならプレイブックは「戦略」に近い。
- トイル(Toil)
- 手動で繰り返される運用作業のうち、自動化すべきもの。ランブックの中で頻繁に実行される手順はトイルの候補。
- エスカレーション(Escalation)
- ランブックの手順で解決できない場合に、より上位の判断者やチームに対応を引き継ぐプロセス。
- MTTR(Mean Time To Resolve)
- インシデント発生から解決までの平均時間。ランブックの品質が高いほどMTTRは短くなる。
ランブックの全体像#
こんな悩みに効く#
- 特定のエンジニアがいないとインシデント対応ができない
- オンコール当番が変わるたびに引き継ぎに時間がかかる
- 同じインシデントが再発するたびに「前回どう対応したっけ」と調べ直している
- 深夜のアラートに対応できる人が限られている
基本の使い方#
過去3〜6か月のインシデント履歴とオンコール対応ログから、ランブック化すべき作業を特定する。
- 発生頻度が月1回以上のインシデント
- 対応手順が毎回ほぼ同じもの
- 現在は特定の個人しか対応できないもの
- まず上位10件に絞ってランブック化を開始する
各ランブックは以下の構成で書く。
- 概要: このランブックが何のためのものか(1〜2行)
- 前提条件: 必要な権限、接続先情報、ツール
- 手順: 番号付きで、各ステップに「実行するコマンド」「期待される結果」「次に進む条件」を記載
- 確認方法: 作業後に復旧を検証する手順
- エスカレーション: 手順で解決しない場合の連絡先と判断基準
- コマンドはコピー&ペーストで実行できるようにリテラルで記載する
ランブックを書いた本人以外に実行してもらい、再現性を検証する。
- 手順が曖昧で迷う箇所はないか
- 前提知識なしでもステップを追えるか
- コマンドの出力例が実際と一致するか
- テスト実行で見つかった不明点はすぐにランブックに反映する
実際のインシデント対応でランブックを使うたびに改善する。
- 手順の抜け漏れがあれば追加する
- 判断に迷った箇所は基準を明確化する
- 3回以上同じランブックを実行したら自動化を検討する
- 自動化した手順はランブックに「自動化済み」と記載し、手動フォールバック手順を残す
具体例#
月間アクティブユーザー20万人のWebアプリ。DB接続プールの枯渇アラートが月3〜4回発生していたが、対応できるのはインフラリードの1名だけだった。深夜の発生時は翌朝まで放置されることもあり、MTTRは平均4.2時間。
作成したランブック:
# DB接続枯渇対応ランブック
## 概要
PostgreSQLのコネクションプール使用率が90%を超えた場合の対応手順。
## 前提条件
- AWSコンソールへのアクセス権限
- psqlコマンドが使える踏み台サーバーへのSSHアクセス
## 手順
1. 現在の接続数を確認
$ psql -c "SELECT count(*) FROM pg_stat_activity;"
→ 期待値: 90以上なら次へ
2. アイドル接続を特定
$ psql -c "SELECT pid, state, query_start FROM pg_stat_activity WHERE state = 'idle' AND query_start < now() - interval '10 min';"
3. アイドル接続を切断
$ psql -c "SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE state = 'idle' AND query_start < now() - interval '10 min';"
4. 接続数が回復したことを確認
$ psql -c "SELECT count(*) FROM pg_stat_activity;"
→ 期待値: 60以下
## エスカレーション
手順3の後も接続数が80以上の場合 → インフラリード(@田中)に連絡このランブックを導入した結果、オンコール担当の全員(5名)が対応可能に。MTTRは4.2時間→48分に短縮。さらに3か月間で7回実行されたため自動化を決定し、PgBouncerの自動スケーリングスクリプトを作成。以降、手動対応はゼロになった。
リリース頻度が週5回のSaaS。デプロイ後の不具合でロールバックが必要になるケースが月2〜3回あったが、ロールバック手順が明文化されておらず、対応するエンジニアによって手順がバラバラだった。ある回では中途半端なロールバックでDB migrationの不整合が発生し、6時間のダウンタイムを引き起こした。
作成したランブック(要約):
- 判断基準: エラーレート5%超、またはレスポンスタイム95%ile 3秒超が5分間継続したらロールバック開始
- アプリケーションのロールバック: ArgoCD UIで前バージョンにSync(コマンド記載)
- DBマイグレーションの確認: 今回のデプロイでマイグレーションが含まれるか確認(確認コマンド記載)
- マイグレーションありの場合: ロールバックマイグレーション実行(コマンド記載)→ テーブル状態確認
- ロールバック後の確認: エラーレートとレスポンスタイムの回復確認(Grafanaダッシュボードリンク記載)
- ポストモーテム起票: テンプレートリンクから起票
導入後8か月でロールバックは11回発生したが、全件が15分以内に完了。以前のような中途半端なロールバックはゼロに。新入社員でも手順通りに実行でき、「ロールバックが怖くなくなったので、リリース判断が早くなった」というフィードバックがチームから出た。
日次で動く12本のバッチジョブがあるデータ分析基盤。月に2〜3回いずれかのジョブが失敗していたが、リカバリー方法がジョブごとに異なり、特定のデータエンジニア1名しか対応できなかった。そのエンジニアが2週間の休暇を取った際、失敗したジョブが5日間放置され、経営会議用のレポートが出せない事態になった。
対応: 12本のジョブそれぞれにランブックを作成し、共通フォーマットで統一した。
各ランブックの共通構成:
- ジョブ名・実行スケジュール・所要時間の目安
- 失敗時のログ確認方法(CloudWatch Logsのフィルタークエリ付き)
- よくある失敗パターンと対応(パターンごとに分岐)
- パターンA: 上流データ未着 → 上流チームに連絡、到着後に再実行コマンド
- パターンB: メモリ不足 → インスタンスタイプ変更コマンド → 再実行
- パターンC: データ不整合 → 特定テーブルのリカバリーSQL
- 再実行後の整合性確認クエリ
結果:
- リカバリー対応可能なメンバーが1名→4名に拡大
- ジョブ失敗からリカバリー完了までの平均時間が8時間→1.5時間に短縮
- 12本中4本について「失敗パターンAは自動リトライで十分」と判明し、自動化を実施。手動対応の頻度が月2〜3回→月0〜1回に減少
やりがちな失敗パターン#
- 抽象的な手順で書く — 「DBを確認する」ではなく、実行するコマンド・見るべき指標・判断する閾値を具体的に書く。コピー&ペーストで実行できるレベルが理想
- 書いた後メンテナンスしない — インフラ構成やツールが変わればランブックも古くなる。インシデント対応のたびに「手順に修正が必要か」をチェックする習慣をつける
- 書いた本人しかテストしない — 作成者は暗黙知で補完してしまうため、手順の抜けに気づかない。必ず別の担当者にテスト実行してもらう
- 全手順をランブック化しようとする — 年1回しか発生しない作業まで書く必要はない。頻度と影響度でスコアリングし、上位から着手する
まとめ#
ランブックは、定型的な運用作業とインシデント対応を「誰でも再現可能な手順書」にする仕組み。ポイントはコマンドレベルの具体性、別担当者によるテスト実行、そしてインシデント後の継続的改善。3回以上同じ手順を実行したら自動化を検討するのがランブックの出口戦略であり、最終的には「手動ランブックをゼロに近づけること」が理想の姿である。