LESSON 30分

トイル削減の実践

ストーリー

「毎朝やっている作業、リストアップしてみろ」

松本先輩に言われ、日常業務を書き出してみた。

・ログの確認と異常がないかチェック(15分) ・ステージング環境のデータリセット(10分) ・SSL証明書の有効期限チェック(5分) ・デプロイ後のヘルスチェック(10分)

「その作業、全部自動化できる。 手動で繰り返す作業を『トイル』と呼ぶ。 SREの仕事の半分は、このトイルを減らすことだ」


トイルとは

トイル(Toil)とは、サービスの運用に関連する手動で反復的な作業で、自動化が可能なものを指します。

トイルの定義(5つの特徴)

特徴説明
手動(Manual)人間が手を動かす必要がある手動デプロイ、手動データ修正
反復的(Repetitive)同じ作業を何度も行う毎日のログチェック
自動化可能(Automatable)機械に任せられるスクリプト化できる作業
戦術的(Tactical)長期的な価値を生まないその場しのぎの対応
サービス成長に比例(Scales with service)サービスが大きくなるほど増えるユーザー数増加で問い合わせ対応増

トイルと非トイルの区別

トイル(自動化すべき):
├── 手動デプロイ
├── 手動のヘルスチェック
├── 定期的なログローテーション
├── ユーザーアカウントの手動作成
├── SSL証明書の手動更新
└── 手動のスケーリング

非トイル(人間が行うべき):
├── アーキテクチャの設計
├── コードレビュー
├── ポストモーテムの議論
├── SLO の見直し
├── 新技術の調査
└── チームメンバーのメンタリング

トイルの計測

トイル率の計算

トイル率 = トイルに費やした時間 / 総労働時間

Google SRE の推奨:
  トイル率 < 50% を維持

理想:
  トイル率 < 30% を目指す

例:
  週40時間勤務
  トイルに12時間費やしている場合
  トイル率 = 12/40 = 30%

トイルの棚卸し

トイル棚卸しテンプレート:

作業名: ステージング環境のデータリセット
頻度: 毎日
所要時間: 10分/回
月間合計: 10分 × 20日 = 200分 ≈ 3.3時間
自動化の難易度: 低(スクリプト化可能)
自動化の効果: 3.3時間/月の削減
優先度: 高(簡単で効果が大きい)

作業名: SSL証明書の更新
頻度: 3ヶ月に1回
所要時間: 30分/回
月間合計: 10分(平均)
自動化の難易度: 低(Let's Encrypt + certbot)
自動化の効果: 10分/月 + 更新忘れリスクの解消
優先度: 高(リスク軽減効果が大きい)

トイル削減の実践例

1. 手動デプロイの自動化

yaml
# Before: 手動でサーバーにSSHして実行
# 1. git pull
# 2. npm install
# 3. npm run build
# 4. pm2 restart app
# → 毎回15分、手順ミスのリスクあり

# After: GitHub Actionsで自動化
name: Deploy
on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: '20'
      - run: npm ci
      - run: npm run build
      - run: npm test
      - name: Deploy to production
        run: |
          aws ecs update-service \
            --cluster production \
            --service app \
            --force-new-deployment

2. ヘルスチェックの自動化

typescript
// Before: 手動でURLにアクセスして確認

// After: 自動ヘルスチェック + アラート
// monitoring/healthcheck.ts
interface HealthCheckResult {
  service: string;
  status: 'healthy' | 'unhealthy';
  responseTime: number;
  timestamp: Date;
}

async function checkHealth(url: string): Promise<HealthCheckResult> {
  const start = Date.now();
  try {
    const response = await fetch(url, { signal: AbortSignal.timeout(5000) });
    return {
      service: url,
      status: response.ok ? 'healthy' : 'unhealthy',
      responseTime: Date.now() - start,
      timestamp: new Date(),
    };
  } catch {
    return {
      service: url,
      status: 'unhealthy',
      responseTime: Date.now() - start,
      timestamp: new Date(),
    };
  }
}

// 定期実行 + アラート
const endpoints = [
  'https://api.example.com/health',
  'https://www.example.com',
  'https://admin.example.com/health',
];

setInterval(async () => {
  const results = await Promise.all(endpoints.map(checkHealth));
  const unhealthy = results.filter(r => r.status === 'unhealthy');
  if (unhealthy.length > 0) {
    await sendAlert(unhealthy);
  }
}, 60000); // 1分間隔

3. SSL証明書の自動更新

bash
# Before: 手動で certbot を実行して更新

# After: cron + certbot auto-renew
# /etc/cron.d/certbot
0 0 1 * * root certbot renew --quiet --post-hook "systemctl reload nginx"

# さらに良い: AWS Certificate Manager で完全自動管理
# → 証明書の発行、更新、適用が全て自動

トイル削減の優先順位付け

基準高優先度低優先度
頻度毎日年1回
所要時間長い(30分以上)短い(5分未満)
リスクミスが障害につながるミスの影響が小さい
自動化の難易度簡単非常に困難
人数チーム全員が行う1人が行う

優先度マトリクス

          簡単 ←── 自動化の難易度 ──→ 困難
     ┌──────────────┬──────────────┐
高   │  最優先       │  計画的に対応  │
い   │  (すぐやる) │  (次Qに計画)│
効   │              │              │
果   ├──────────────┼──────────────┤
     │  やる価値あり │  後回し       │
低   │  (余裕時に) │  (保留)     │
い   │              │              │
     └──────────────┴──────────────┘

まとめ

項目ポイント
トイルの定義手動・反復的・自動化可能な運用作業
目標トイル率 50% 未満を維持(理想は30%未満)
計測トイルの棚卸しで現状を把握
優先順位頻度×所要時間×リスク で判断
実践例自動デプロイ、自動ヘルスチェック、証明書自動更新

チェックリスト

  • トイルの5つの特徴を説明できる
  • トイルと非トイルを区別できる
  • トイルの棚卸しを実施できる
  • 優先度マトリクスでトイル削減の優先順位を決められる
  • 具体的なトイル削減の自動化方法を提案できる

次のステップへ

トイル削減を学んだら、次は演習でSRE運用計画を実際に作成します。SLI/SLO設計、エラーバジェットポリシー、トイル削減計画を総合的に策定しましょう。


推定読了時間: 30分