mcpField
D
disaster-recovery-plan

disaster-recovery-plan

github.com/mohitagw15856クラウド・DevOps1.5k39 回インストール5 日前に更新
リポジトリ

disaster-recovery-plan について

エンジニア、SRE、オンコール担当者向けに、サービスやシステムの災害復旧計画を作成するスキルです。入力されたサービス情報を基に、復旧目標、障害シナリオ、段階的な手順書をまとめます。

主な機能

  1. 01サービスとインフラの情報を整理
  2. 02測定可能なRPO・RTOを設定
  3. 03障害シナリオを一覧化
  4. 04コマンド付きの復旧手順を作成
  5. 05復旧確認手順を記載

活用シーン

  1. 01本番サービスの復旧手順を準備
  2. 02リージョン切り替え手順を記録
  3. 03データベース破損時の復旧を計画
  4. 04オンコールチームの障害対応を支援

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/mohitagw15856/pm-claude-skills --skill disaster-recovery-plan

インストール後、Claude Code で/disaster-recovery-planを入力して読み込まれたか確認します。

詳細

災害復旧計画スキル

サービスまたはシステムの完全な災害復旧計画を作成します。エンジニア、SRE、オンコール対応者が、災害シナリオから可能な限り短時間で復旧するために必要な情報をすべて提示します。優れたDR計画は定期的にテストされ、曖昧な指示ではなく正確なコマンドが記載され、RTO/RPOの目標が測定可能であるため、チームは復旧が成功したかどうかを把握できます。

必要な入力情報

まだ提供されていない場合は、以下を尋ねてください。

  • サービス名とその機能(ビジネス上の役割および技術的な役割)
  • 重要度ティア — 長時間のダウンタイムによるビジネスへの影響(例:ティア1=収益に直結、ティア2=運用への影響、ティア3=社内限定)
  • 現在のインフラストラクチャ構成 — クラウドプロバイダー、リージョン/ゾーン、デプロイモデル(Kubernetes、ECS、VM、サーバーレス)
  • RPO/RTO要件 — 目標復旧時点(許容されるデータ損失量)と目標復旧時間(停止が許される時間)
  • バックアップ戦略 — バックアップ対象、頻度、保存場所、保持ポリシー
  • オンコール連絡先 — 対応者の順序に沿った氏名と連絡先情報

出力形式


災害復旧計画:[Service Name]

チーム: [Team name] | テックリード: [Name] 重要度ティア: [Tier 1 / Tier 2 / Tier 3] | 最終テスト日: [Date] 次回のDRテスト: [Date] | ドキュメント所有者: [Name] 最終更新日: [Date] | レビュー周期: 四半期ごと

緊急事態ですか? セクション3 — 障害シナリオ別ランブックに進んでください。 状況に合ったシナリオを見つけ、手順に正確に従ってください。


1. 復旧目標

目標値根拠
RPO(目標復旧時点)[X 分/時間][例:「最後にコミットされたトランザクション — データベースのレプリケーションは同期式です」]
RTO(目標復旧時間)[Y 分/時間][例:「30分で収益への影響が始まるため、15分以内の復旧を目標とします」]
MTTR目標(災害以外)[Z 分][運用上のインシデント。DRイベントは含みません]
データ保持期間(バックアップ)[N 日/週][コンプライアンス要件または運用ポリシー]
バックアップ頻度[X 時間ごと][RPOに基づく — バックアップ間隔はRPO以下である必要があります]

実際の運用での意味:

  • データベースが破損した場合、ビジネスへの影響が許容できなくなるまでに失ってよいトランザクションは最大[X分]分です。
  • DRイベントを宣言してから[Y分/時間]以内に、サービスを再び稼働させる必要があります。
  • いずれかの目標を達成できない場合は、直ちに[Engineering Manager]へエスカレーションしてください。

2. 障害シナリオ一覧

シナリオ発生可能性影響RTO目標RPO目標ランブック
単一アベイラビリティゾーンの障害中[部分的/全面的な停止][15 分][0 — データ損失なし]セクション3.1
リージョン全体の障害低全面停止[60 分][5 分]セクション3.2
データベースの破損/データ損失低全面停止[90 分][RPO値]セクション3.3
重要な依存先の停止高[部分的な性能低下][30 分][該当なし]セクション3.4
セキュリティ侵害/ランサムウェア非常に低全面停止+調査[4 時間][最後の正常なバックアップ]セクション3.5
誤操作による大量データ削除低部分的または全面的なデータ損失[60 分][RPO値]セクション3.6

3. 障害シナリオ別ランブック

3.1 単一アベイラビリティゾーンの障害

トリガー: 1つのAZに到達できなくなり、そのゾーン内のポッド/インスタンスが応答しなくなります。 検知: PagerDutyアラート[AlertName]が発報するか、クラウドプロバイダーのステータスページにAZの性能低下が表示されます。 想定RTO: [15 分] | 想定RPO: ゼロ(マルチAZレプリケーションが機能していればデータ損失なし)

ステップ1 — 障害を確認する

# Check pod/instance health across zones
kubectl get pods -o wide -n [namespace] | grep -v Running

# Check which nodes are affected
kubectl get nodes -o wide | grep -v Ready

# Verify cloud provider AZ status
# AWS: https://health.aws.amazon.com/health/status
# GCP: https://status.cloud.google.com

ステップ2 — 自動復旧が行われたか確認する

# If using auto-scaling, check if replacement instances launched
kubectl get pods -n [namespace] --watch

# Check deployment replica count
kubectl get deployment [service-name] -n [namespace]

# Verify load balancer health checks are passing
[cloud provider CLI command to check target group health]

ステップ3 — 自動復旧が停滞している場合は、強制的に再スケジュールする

# Cordon the affected node so no new pods schedule on it
kubectl cordon [node-name]

# Drain the node — moves all pods to healthy nodes
kubectl drain [node-name] --ignore-daemonsets --delete-emptydir-data

# Verify pods have rescheduled successfully
kubectl get pods -o wide -n [namespace]

ステップ4 — サービスの健全性を確認する

# Smoke test key endpoints
curl -s -o /dev/null -w "%{http_code}" https://[service-url]/health
curl -s -o /dev/null -w "%{http_code}" https://[service-url]/[critical-endpoint]

# Check error rate in monitoring
[dashboard link or query]

復旧の確認条件: すべてのポッドがRunningであり、ヘルスチェックが200を返し、エラー率がベースラインに戻っていること。


3.2 リージョン全体の障害

トリガー: プライマリリージョンが完全に利用できなくなります。 検知: すべてのサービスヘルスチェックが失敗し、クラウドプロバイダーのステータスページでリージョン全体の障害が確認されます。 想定 RTO: [60 minutes] | 想定 RPO: [5 minutes — based on cross-region replication lag]

ステップ 1 — リージョン障害を確認する(5 minutes)

# Confirm the primary region is unreachable
ping [primary-region-endpoint] || echo "Primary region unreachable"

# Check replication lag on standby region database
[command to check replica lag — e.g. for RDS: aws rds describe-db-instances --region [dr-region]]

ステップ 2 — DR イベントを宣言して通知する(2 minutes)

#incidents に投稿します:

🔴 DR EVENT — [Service Name] — Region Failure
Primary region: [region] — UNREACHABLE
Activating failover to: [dr-region]
Incident commander: [Name]
Next update: 15 minutes

PagerDuty 経由で [Engineering Manager] と [CTO/VP Eng] にページを送ります。

ステップ 3 — DR データベースを昇格する(10 minutes)

# AWS RDS — promote read replica to primary
aws rds promote-read-replica \
  --db-instance-identifier [dr-replica-identifier] \
  --region [dr-region]

# Wait for promotion to complete
aws rds wait db-instance-available \
  --db-instance-identifier [dr-replica-identifier] \
  --region [dr-region]

# Record the new database endpoint
aws rds describe-db-instances \
  --db-instance-identifier [dr-replica-identifier] \
  --region [dr-region] \
  --query 'DBInstances[0].Endpoint.Address'

ステップ 4 — DR リージョンにサービスをデプロイする(20 minutes)

# Update service configuration to point at DR database
kubectl set env deployment/[service-name] \
  DATABASE_URL=[new-dr-database-url] \
  -n [namespace] \
  --context [dr-region-context]

# Scale up the DR deployment
kubectl scale deployment/[service-name] --replicas=[N] \
  -n [namespace] \
  --context [dr-region-context]

# Verify all pods are running
kubectl get pods -n [namespace] --context [dr-region-context]

ステップ 5 — DNS/ロードバランサーを切り替える(5 minutes)

# Update DNS to point to DR region load balancer
# AWS Route 53:
aws route53 change-resource-record-sets \
  --hosted-zone-id [zone-id] \
  --change-batch file://dr-failover-dns.json

# Verify DNS propagation (may take up to [TTL] seconds)
dig [service-domain] @8.8.8.8

ステップ 6 — エンドツーエンドで検証する

# Full smoke test against DR endpoint
curl -s https://[service-url]/health
[run automated smoke test suite if available]

復旧の確認条件: DNS が DR リージョンを解決し、スモークテストが成功し、エラー率がベースラインに戻っていること。

フェイルオーバー後の対応(緊急ではありません — サービス安定後に実施):

  • 根本原因が解決したと確認されるまで、プライマリにフェイルバックしないでください
  • データ損失期間を記録します(障害発生時のレプリケーション遅延を確認してください)
  • インシデントの事後レビューを開始します — [incident-postmortem skill] を参照してください

3.3 データベースの破損またはデータ損失

トリガー: ソフトウェアのバグ、オペレーターのエラー、またはハードウェア障害により、データベース内のデータが破損、削除、またはその他の理由で不正確になっています。 検知: データの欠落/無効を示すアプリケーションエラー、クエリエラー率に関する監視アラート、ユーザーからの報告。 想定 RTO: [90 minutes] | 想定 RPO: [Backup interval — e.g. 1 hour]

ステップ 1 — 直ちに被害の拡大を止める

# Put the service into maintenance mode to prevent further writes to corrupted data
[command to enable maintenance mode — e.g. kubectl set env deployment/[name] MAINTENANCE_MODE=true]

# Or: scale down the service to zero to prevent writes
kubectl scale deployment/[service-name] --replicas=0 -n [namespace]

ステップ 2 — 破損の範囲を評価する

# Identify which tables/records are affected
[SQL query to check data integrity — e.g.]
# psql $DATABASE_URL -c "SELECT COUNT(*) FROM [table] WHERE [integrity check condition]"

# Determine when corruption started (cross-reference with deploy times and error logs)
[log query to find earliest error — e.g. in Datadog:]
# service:[service-name] status:error "[corruption error message]" | sort by timestamp asc

ステップ 3 — 適切な復元ポイントを特定する

# List available backups
[command to list backups — e.g. for RDS:]
aws rds describe-db-snapshots \
  --db-instance-identifier [db-identifier] \
  --query 'DBSnapshots[*].[SnapshotCreateTime,DBSnapshotIdentifier]' \
  --output table

# Choose the most recent backup BEFORE corruption started
# Record the chosen snapshot ID: [snapshot-id]

ステップ 4 — バックアップから復元する

# Restore to a NEW database instance (never overwrite production directly)
aws rds restore-db-instance-from-db-snapshot \
  --db-instance-identifier [service-name]-restored-[date] \
  --db-snapshot-identifier [snapshot-id] \
  --region [region]

# Wait for restore to complete
aws rds wait db-instance-available \
  --db-instance-identifier [service-name]-restored-[date]

# Get the restored instance endpoint
aws rds describe-db-instances \
  --db-instance-identifier [service-name]-restored-[date] \
  --query 'DBInstances[0].Endpoint.Address'

ステップ 5 — 復元したデータを検証する

# Connect to restored database and verify integrity
psql [restored-db-endpoint] -U [user] -d [database] -c "[data integrity query]"

# Confirm record counts match expectations
psql [restored-db-endpoint] -U [user] -d [database] -c "SELECT COUNT(*) FROM [critical-table]"

ステップ 6 — 復元したデータベースをサービスに接続する

kubectl set env deployment/[service-name] \
  DATABASE_URL=postgres://[user]:[pass]@[restored-endpoint]/[db] \
  -n [namespace]

kubectl scale deployment/[service-name] --replicas=[N] -n [namespace]

復旧の確認条件: サービスが復元したデータベースに接続して稼働し、データ整合性チェックに合格し、エラー率がベースラインに戻っていること。


3.4 重要な依存関係の停止

トリガー: [service name] が依存するサービスが利用できない、または性能が低下しています。 検知: [dependency] を呼び出すエンドポイントのエラー率またはレイテンシの増加、依存先の担当者からのアラート。 想定 RTO: 依存先によります — [30 minutes for mitigation, resolution depends on dependency owner]

依存関係マップ:

依存関係重要度劣化時の動作緩和策
[Database]Critical — all writes failFull outageActivate DR database (Section 3.3)
[Cache — Redis]High — latency increasesPerformance degradationBypass cache, serve from DB
[Auth service]Critical — auth failsAll authenticated endpoints failReturn cached tokens (if implemented)
[Message queue]Medium — async processing delaysWrites succeed, async jobs queueQueue backlog — see on-call runbook
[External API — name]Low — feature X unavailableGraceful degradationFeature flag to disable feature X

緩和手順:

# Enable circuit breaker / fallback for [dependency] if implemented
kubectl set env deployment/[service-name] [DEPENDENCY]_CIRCUIT_BREAKER=open -n [namespace]

# Enable feature flag to disable [dependency-backed feature]
[feature flag CLI command or dashboard link]

# Check if dependency has a status page
# [Dependency status URL]

エスカレーション: [PagerDuty / Slack #[channel]] 経由で [dependency] のオンコール担当者に連絡します。サービスのエラー率と、依存先でエラーが発生し始めた時刻を共有してください。


3.5 セキュリティ侵害またはランサムウェア

トリガー: 不正アクセス、データの持ち出し、またはサービスデータの暗号化を示す証拠があります。 検知: セキュリティツールのアラート、不審なアクセスパターン、データ漏えいに関するユーザーからの報告。 想定 RTO: [4+ hours — prioritise containment over speed] | 想定 RPO: [Last verified clean backup]

ステップ 1 — 直ちに隔離する

# Take the service offline — do not attempt to recover while breach is active
kubectl scale deployment/[service-name] --replicas=0 -n [namespace]

# Revoke all API keys and service account credentials immediately
[command to rotate secrets — e.g. via Vault or cloud provider]

# Block all external access at network level
[firewall/security group command to deny all inbound traffic]

ステップ 2 — 直ちにセキュリティチームに通知する PagerDuty 経由で [Security lead] にページを送ります。セキュリティチームの関与なしに、修復を試みないでください。

#security-incidents に投稿します(#incidents ではなく、非公開チャンネルです):

🔴 SECURITY INCIDENT — [Service Name]
Time detected: [Time]
Evidence: [One sentence — what was observed]
Actions taken: Service isolated, credentials revoked
Awaiting: Security team guidance

ステップ 3 — 証拠を保全する

# Export current logs before any remediation
[log export command — preserve evidence for forensics]

# Snapshot the current state of all infrastructure
[snapshot/image command]

ステップ 4 以降 — セキュリティチームの指示に従ってください。 セキュリティチームが攻撃経路の封鎖を確認するまで、バックアップから復元しないでください。


3.6 誤操作による大量データ削除

発生条件: オペレーター、スクリプト、またはアプリケーションのバグにより、レコードが大量に削除されました。 検知方法: レコード数の急減、データが見つからないというユーザーからの報告、アプリケーションエラー。 想定 RTO: [60 minutes] | 想定 RPO: [Backup interval]

# Step 1 — Stop further writes immediately
kubectl scale deployment/[service-name] --replicas=0 -n [namespace]

# Step 2 — Determine what was deleted and when
psql $DATABASE_URL -c "
  SELECT schemaname, tablename,
         n_dead_tup, last_autovacuum
  FROM pg_stat_user_tables
  ORDER BY n_dead_tup DESC LIMIT 10;
"

# Step 3 — Check if deletion is recoverable via MVCC (PostgreSQL)
# Records may still be recoverable if VACUUM has not run
psql $DATABASE_URL -c "
  SELECT * FROM [table]
  WHERE xmax != 0  -- recently deleted rows
  LIMIT 100;
"

# Step 4 — If not recoverable via MVCC, restore from backup
# Follow Section 3.3 (Database Corruption runbook) from Step 3 onward

4. バックアップと復元の手順

バックアップの設定
データストアバックアップの種類頻度保持期間場所
[Primary database]自動スナップショット[N] 時間ごと[N] 日[S3 bucket / cloud storage path]
[Primary database]トランザクションログのバックアップ継続的[N] 日[Location]
[Secondary store — e.g. Redis]RDB ダンプ毎日[N] 日[Location]
[Blob/object storage]クロスリージョンレプリケーション継続的[N] 日[DR region bucket]
[Config / secrets]Terraform state + Vault backup変更時無期限[Location]
バックアップの検証(毎週実施)
# Test restore of latest database backup to a throwaway instance
aws rds restore-db-instance-from-db-snapshot \
  --db-instance-identifier [service-name]-backup-test-$(date +%Y%m%d) \
  --db-snapshot-identifier $(aws rds describe-db-snapshots \
    --db-instance-identifier [db-id] \
    --query 'sort_by(DBSnapshots, &SnapshotCreateTime)[-1].DBSnapshotIdentifier' \
    --output text)

# Wait for restore, then run integrity checks
psql [test-instance-endpoint] -c "[integrity check query]"

# Confirm row counts match recent production values (allow ≤ RPO difference)
psql [test-instance-endpoint] -c "SELECT COUNT(*) FROM [critical-table]"

# Destroy the test instance
aws rds delete-db-instance \
  --db-instance-identifier [service-name]-backup-test-$(date +%Y%m%d) \
  --skip-final-snapshot

5. DR テストの実施頻度

定期的なテストは必須です。テストされていない DR 計画は、DR 計画とは言えません。

テストの種類頻度実施担当者合格基準
バックアップ復元の検証毎週(自動)オンコール担当のローテーション復元が完了し、整合性チェックに合格する
ゾーンフェイルオーバー訓練毎月エンジニアリングチームRTO 目標を達成し、データ損失がゼロである
リージョンフェイルオーバー訓練四半期ごとエンジニアリングチーム + SRERTO/RPO 目標を達成する
DR 総合訓練毎年エンジニアリングチーム + ステークホルダーすべてのシナリオを実施し、ギャップを記録する
カオスエンジニアリング(インフラ障害)毎週(自動)カオスエンジニアリングツールサービスが適切に縮退し、自動的に復旧する
総合訓練の手順
  1. 訓練の1週間前: すべてのステークホルダーに通知し、当日の本番環境への変更を凍結して、DR 環境を準備します。
  2. 対象範囲の定義: セクション2から2~3個のシナリオを選びます。テスト前に期待される結果を記録します。
  3. 実施: 1人がインシデントコマンダーを務め、ほかのメンバーがランブックの手順を実行する間、別の1人が観察して所要時間を計測します。
  4. 測定: 各シナリオについて、実際の RTO と RPO を目標値と比較して記録します。
  5. 振り返り(当日中): ギャップ、ランブックの不正確な記述、自動化の機会を記録します。
  6. アクションアイテム: 見つかったすべてのギャップについてチケットを起票します。優先度:P1 項目は次回の総合訓練までに修正する必要があります。

6. コミュニケーション計画

DR イベント発生中の社内コミュニケーション

インシデントコマンダーの責務:

  • DR イベントを宣言し、インシデント用チャンネルを開設する
  • 最低15分ごとに最新情報を投稿する
  • フェイルオーバーを実行する判断を下す(チームの合議に委ねない)
  • 想定される復旧時間をビジネス関係者に通知する

DR イベント開始時に以下の担当者へ通知します:

役割名前連絡先通知のタイミング
エンジニアリングマネージャー[Name][Slack / Phone]直ちに
CTO / VP Engineering[Name][Phone]Tier 1 サービス:直ちに
カスタマーサクセス責任者[Name][Slack]顧客向けサービスに影響がある場合
セキュリティ責任者[Name][Slack / PagerDuty]情報漏えいが疑われる場合
法務 / コンプライアンス[Name][Email / Phone]データ損失に PII が含まれる場合
コミュニケーションテンプレート

DR イベントの宣言:

🔴 DR EVENT — [Service Name]
Time: [HH:MM UTC]
Scenario: [Zone failure / Region failure / Data loss / etc.]
Impact: [Who is affected and how]
RTO target: [X minutes]
Incident commander: [Name]
War room: [Slack channel / call link]
Next update: [Time + 15 min]

状況報告(15分ごと):

🔴 DR UPDATE — [Service Name] — [HH:MM UTC]
Status: [Investigating / Executing recovery / Verifying]
Progress: [One sentence on current step]
Blockers: [Any — or "None"]
Updated RTO estimate: [Time]
Next update: [Time + 15 min]

復旧の確認:

✅ DR RESOLVED — [Service Name] — [HH:MM UTC]
Total downtime: [X minutes]
Data loss: [None / X minutes of transactions]
RTO target: [X min] — Actual: [Y min] — [MET / MISSED]
RPO target: [X min] — Actual: [Y min] — [MET / MISSED]
Root cause: [One sentence]
Post-incident review: [Scheduled for / Link when created]

7. DR 対応準備チェックリスト

このチェックリストを四半期ごと、および大規模なインフラ変更の前に実施してください。

バックアップ:

  • 自動バックアップが実行され、失敗した場合にアラートが通知される
  • 直近のバックアップ復元が過去 7 日以内にテストされている
  • バックアップの保持期間が RPO およびコンプライアンス要件を満たしている
  • バックアップがプライマリとは別のリージョン/アカウントに保存されている

フェイルオーバーインフラ:

  • DR リージョン/環境が存在し、プロビジョニングされている(文書化されているだけではない)
  • DNS フェイルオーバー手順が正確なコマンドとともに文書化されている
  • DR データベースレプリカが最新である(レプリケーション遅延が RPO の範囲内)
  • DR リージョンに単一のコマンドまたは自動化されたパイプラインでサービスをデプロイできる

ランブック:

  • セクション 3 のすべてのランブックが、前四半期中にテストされている
  • ランブックのコマンドが現在のインフラに対して検証されている(古い参照がない)
  • 連絡先リストが最新である(退職者が載っていない)

アクセス:

  • オンコールエンジニアが DR リージョンのコンソール/CLI にアクセスできる
  • DR リージョン用のサービスアカウント認証情報がプロビジョニングされ、テストされている
  • SSO が利用できない場合の緊急アクセス用に、緊急用アカウントが用意されている

モニタリング:

  • DR リージョンにもモニタリングがある(プライマリだけではない)
  • DR 環境に問題が発生したとき、アラートが正しく通知される

品質チェック

  • RPO と RTO の目標が範囲ではなく具体的な数値で設定され、ビジネス部門の合意を得ている
  • すべてのランブックに記載されたすべてのコマンドが、前四半期中に担当者によって実行されている。ドキュメントからコピーしただけで未テストのものではない
  • DR データベースが DR リージョンに存在し、レプリケーション遅延がモニタリングされている
  • バックアップ復元が過去 7 日以内にエンドツーエンドでテストされている
  • ゲームデーのスケジュールがチームのカレンダーに登録されている。ここに文書化されているだけではない
  • 連絡先リストに現在使われている電話番号が記載されている。Slack のハンドル名だけではない(DR 発生時に Slack が停止している可能性がある)
  • セキュリティ侵害のランブック(3.5)にセキュリティチームの連絡先が明記され、自己修復を試みないようにしている
  • すべてのしきい値(RTO/RPO)がモニタリングダッシュボードに表示され、実績と目標をリアルタイムで測定できる

アンチパターン

  • テストせずにランブックのコマンドを記載しないでください。ランブックにある未テストのコマンドは、認知負荷が最も高くなる実際の災害時に、かえって危険です
  • ビジネス部門の承認なしに RTO/RPO の目標を設定しないでください。技術チームは、ダウンタイムに対する実際のビジネス上の許容コストを反映しない、意欲的すぎる目標を設定しがちです
  • 各フェイルオーバーシナリオの「正常系」だけを記載しないでください。ランブックでは、復旧手順そのものが失敗した場合の対応も明示する必要があります
  • エスカレーション先として Slack のハンドル名だけを記載しないでください。リージョン全体の障害時には Slack が利用できない可能性があるため、電話番号は必須です
  • 見つかった問題の修正を事前に確約せずに DR ゲームデーを予定しないでください。誰も担当しないアクションアイテムを生むだけのゲームデーは、備えではなく単なる見せかけです

トリガーとなるフレーズの例

  • 「DR 計画を作成して。」
  • 「フェイルオーバー手順を文書化して。」
  • 「復旧ランブックを作成して。」
  • 「RTO/RPO の目標を定義して。」
  • 「災害復旧のゲームデーに備えて。」

コメント