目次

Amazon EventBridge Scheduler 完全ガイド 2026

初心者から実務者向けの包括的解説

Amazon EventBridge Scheduler は、フルマネージドのサーバーレススケジューリングサービスで、Cron・レート式・1 回限りのスケジュールで AWS 200+ サービス API(Lambda・ECS・SQS・Step Functions・SageMaker など)を直接呼び出します。CloudWatch Events / EventBridge Rules のスケジュール機能を分離・強化した後継サービスで、タイムゾーン指定・フレキシブルタイムウィンドウ・スケジュールグループ管理・1,400万回/月無料枠により、エンタープライズ規模のスケジュール実行を低コスト・高信頼性で実現します。2026 年現在、DPU(Data Processing Unit)自動スケーリング・リトライポリシー強化・複数ターゲット同時実行により、複雑なワークフロー編成が可能になっています。

ドキュメントの目的

本ガイドは以下を対象としています。

  • 初心者向け: EventBridge Scheduler とは何か、CloudWatch Events との違いを学びたい方
  • 開発者向け: Lambda・ECS・SQS を定期実行・スケジュール実行したい方
  • SRE / インフラ向け: マルチテナント SaaS のスケジュール管理・大規模バッチ処理設計者
  • データエンジニア向け: ETL・データパイプラインの定期トリガー構築
  • アーキテクト向け: スケジューリング基盤設計・ワークフロー編成戦略

2025-2026 年の EventBridge Scheduler エコシステム

  • リトライポリシー拡張:最大リトライ回数・失敗時 DLQ 自動送信
  • タイムゾーンネイティブ対応:UTC 不要、Asia/Tokyo など直接指定可能
  • フレキシブルタイムウィンドウ:スパイク軽減のため、指定時間内でランダム実行
  • スケジュールグループ管理:マルチテナント SaaS のテナント単位で管理
  • EventBridge Rules との統合:Rules が複雑フィルタリング、Scheduler が純粋スケジューリング
  • 200+ ターゲット API サポート:Lambda を経由せず、直接 ECS・SageMaker・Redshift 等を呼び出し可能
  • 1,400万回/月無料枠:ほぼすべての組織で無料・低コスト運用

目次

  1. 概要
  2. EventBridge Scheduler が解決する課題
  3. 主な特徴
  4. アーキテクチャと基本概念
  5. スケジュールタイプ
  6. 200+ ターゲット API
  7. タイムゾーン・フレキシブルタイムウィンドウ
  8. スケジュールグループ・テナント管理
  9. リトライ・DLQ・エラーハンドリング
  10. CLI・SDK・IaC 実装例
  11. 主要ユースケース(10+)
  12. セキュリティ・IAM
  13. 監視・メトリクス
  14. EventBridge Rules との比較
  15. CloudWatch Events(レガシー)との比較
  16. ベストプラクティス
  17. トラブルシューティング
  18. 2025-2026 最新動向
  19. 学習リソース
  20. 実装例・チェックリスト
  21. まとめ
  22. 参考文献

概要

初心者向けメモ: EventBridge Scheduler は「定期実行・スケジュール実行を自動化するスイッチ」です。例えば、毎日深夜 03:00 に ECS タスク(バッチ処理)を実行し、失敗時は 3 回まで自動リトライ、すべて失敗したら SQS DLQ に通知という複雑な要件も、Scheduler で GUI / CLI で簡潔に定義でき、Lambda(定常コスト)を経由する必要もありません。CloudWatch Events が「イベント駆動中心」なのに対し、Scheduler は「純粋なスケジューリング機能」に特化し、より シンプル・低コスト・強力なスケジュール管理を実現します。

Amazon EventBridge Scheduler は、エンタープライズ規模のスケジューリング基盤 として以下を実現します:

  • 200+ AWS サービス API の直接呼び出し:Lambda を経由せず ECS・SQS・SageMaker等を直接実行
  • タイムゾーンネイティブ対応:cron(0 9 * * ? *) TZ=Asia/Tokyo で JST 指定、UTC 変換不要
  • フレキシブルタイムウィンドウ:スパイク軽減、指定時間内でランダム実行
  • スケジュールグループ・テナント管理:マルチテナント SaaS でテナント単位に整理
  • リトライ・DLQ:失敗時の自動リトライ + デッドレターキュー設定で信頼性向上
  • 1,400万回/月無料:ほぼすべての組織で無料・低コスト
  • フルマネージド:インフラ管理不要、AWS が 99.99% SLA を保証

参照:Amazon EventBridge Scheduler User Guide


EventBridge Scheduler が解決する課題

従来の課題

課題 説明
複雑なスケジューリング実装 Cron スクリプト / Lambda で定期実行管理、メンテナンス負荷大
タイムゾーン管理の煩雑さ UTC で設定 → JST / EST 変換が必要、人的ミス多発
大規模スケジュール管理 数千~数百万のスケジュール(SaaS テナント)を管理するシステム不在
リトライ・エラー処理の手作業 Lambda で失敗リトライを手動実装、ロジック複雑化
スパイク・リソース競合 全スケジュール同時実行→バックエンド過負荷、DDOS のようなスパイク
Lambda 定常コスト 毎時間・毎分 invocation で Lambda コスト累積
複数 AWS サービス呼び出しの複雑性 Lambda を経由して各サービス呼び出し、レイテンシ増加

EventBridge Scheduler が提供する解決策

直感的なスケジューリング:GUI / CLI で Cron / Rate / One-time を簡潔に定義
タイムゾーンネイティブ:Asia/Tokyo など直接指定、UTC 変換ゼロ
大規模スケジュール管理:スケジュールグループで数百万スケジュール管理可能
組み込みリトライ・DLQ:失敗時自動リトライ + DLQ で障害追跡
フレキシブルタイムウィンドウ:スパイク軽減、指定時間内でランダム実行
Lambda 経由不要・低コスト:200+ API を直接呼び出し、Lambda 定常コスト排除
シンプルで透明性の高い料金:1,400万回/月無料 + 超過分 $1.00/100万回


主な特徴

1. スケジュールタイプ

Cron 式(特定時刻の繰り返し):
  cron(0 9 * * ? *)       → 毎日 09:00
  cron(0 0 ? * MON-FRI *)  → 平日 00:00
  cron(0 0 1 * ? *)       → 毎月 1 日

Rate 式(一定間隔の繰り返し):
  rate(5 minutes)  → 5 分ごと
  rate(1 hour)     → 1 時間ごと
  rate(7 days)     → 7 日ごと

One-Time Schedule(1 回限りの実行):
  at(2026-12-31T23:59:00) → 特定時刻に 1 回だけ実行
  → 実行後に自動削除可能

2. 200+ ターゲット API

Compute:
├── Lambda(InvokeFunction)
├── ECS(RunTask)
├── EC2(StartInstances / StopInstances)
├── Batch(SubmitJob)
└── Systems Manager(StartAutomationExecution)

Data & Analytics:
├── Redshift(ExecuteStatement)
├── Athena(StartQueryExecution)
├── Glue(StartJobRun)
├── SageMaker(CreateTransformJob)
└── DMS(StartReplicationTask)

Integration & Messaging:
├── SQS(SendMessage)
├── SNS(Publish)
├── Step Functions(StartExecution)
├── EventBridge(PutEvents)
└── API Gateway(InvokeHttpApi)

3. タイムゾーン・フレキシブル実行

Cron with Timezone:
  cron(0 9 * * ? *)  TZ=Asia/Tokyo
  → JST 09:00 に実行(自動 UTC 変換)

Flexible Time Window:
  StartTime: 09:00
  FlexibleTimeWindow: 15 minutes
  → 09:00~09:15 のランダムな時刻に実行
  → バックエンド負荷分散

4. マルチテナント管理

Schedule Groups:
├── tenant-abc グループ:テナント ABC の全スケジュール
├── tenant-xyz グループ:テナント XYZ の全スケジュール
├── default グループ:分類なし
└── admin グループ:システム管理者用

Benefits:
├── グループ単位の IAM 制御
├── テナント隔離・セキュリティ向上
└── スケジュール数上限 (1,000/グループ) を複数グループで回避

アーキテクチャと基本概念

EventBridge Scheduler Architecture

┌───────────────────────────────────────────┐
│ Amazon EventBridge Scheduler              │
├───────────────────────────────────────────┤
│                                           │
│ 1. Schedule Definition                    │
│    ├── Cron / Rate / One-Time            │
│    ├── Timezone(TZ=Asia/Tokyo)          │
│    └── FlexibleTimeWindow                 │
│                                           │
│ 2. Trigger Engine                        │
│    ├── 指定時刻に目覚める                  │
│    ├── FlexibleWindow 内ランダム実行      │
│    └── Retry Policy 適用                  │
│                                           │
│ 3. Target Invocation                     │
│    ├── API Call(直接呼び出し)           │
│    ├── IAM Role で権限管理                │
│    └── 200+ AWS Service API              │
│                                           │
│ 4. Error Handling                        │
│    ├── Retry(最大 MaximumRetryAttempts)│
│    ├── DLQ(SQS / SNS に失敗通知)        │
│    └── CloudWatch Logs                   │
│                                           │
└──────────────────┬──────────────────────┘
                   │
      ┌────────────┼────────────┐
      ↓            ↓            ↓
   Lambda         ECS         SQS
   Step Functions Redshift    SNS
   Batch          Athena      DMS
   ...          (200+)        ...

実行フロー

Step 1: Schedule Definition
  ├── cron(0 9 * * ? *) TZ=Asia/Tokyo
  ├── Target: ECS RunTask
  ├── Retry: MaxAttempts=3, BackoffRate=2
  └── DLQ: sqs://my-dlq

Step 2: Trigger Evaluation
  └── 毎日 JST 09:00 に評価

Step 3: Target Invocation
  ├── ECS API 呼び出し
  ├── IAM Role で権限確認
  └── タスク起動

Step 4: Success / Failure Handling
  ├── Success: CloudWatch Logs に記録
  ├── Failure(1回目): リトライ待機(Backoff)
  ├── Failure(2,3回目): 同様にリトライ
  └── All Failed: DLQ に失敗メッセージ送信

Step 5: Monitoring
  └── CloudWatch Metrics・Logs で追跡

スケジュールタイプ

Cron 式スケジュール

# 毎日 09:00(JST)
aws scheduler create-schedule \
  --name daily-etl-job \
  --schedule-expression "cron(0 9 * * ? *)" \
  --timezone "Asia/Tokyo" \
  --target '{
    "Arn": "arn:aws:scheduler:::aws-sdk:ecs:runTask",
    "RoleArn": "arn:aws:iam::ACCOUNT:role/SchedulerRole",
    "EcsParameters": {
      "LaunchType": "FARGATE",
      "NetworkConfiguration": {
        "AwsvpcConfiguration": {
          "Subnets": ["subnet-xxxxx"],
          "SecurityGroups": ["sg-xxxxx"],
          "AssignPublicIp": "DISABLED"
        }
      },
      "TaskDefinitionArn": "arn:aws:ecs:region:account:task-definition/my-etl:1",
      "Cluster": "my-cluster"
    }
  }' \
  --flexible-time-window '{
    "Mode": "FLEXIBLE",
    "MaximumWindowInMinutes": 15
  }' \
  --retry-policy '{
    "MaximumEventAge": 86400,
    "MaximumRetryAttempts": 2
  }' \
  --dead-letter-config '{
    "Arn": "arn:aws:sqs:region:account:my-dlq"
  }'

Rate 式スケジュール

# 30 分ごと
aws scheduler create-schedule \
  --name frequent-health-check \
  --schedule-expression "rate(30 minutes)" \
  --timezone "UTC" \
  --target '{
    "Arn": "arn:aws:scheduler:::aws-sdk:lambda:invoke",
    "RoleArn": "arn:aws:iam::ACCOUNT:role/SchedulerRole",
    "LambdaParameters": {
      "FunctionName": "my-health-check-function",
      "Payload": "{\"checkType\": \"database\"}"
    }
  }'

One-Time Schedule

# 特定の将来時刻に 1 回だけ実行(例:キャンペーン終了処理)
aws scheduler create-schedule \
  --name campaign-end-notification \
  --schedule-expression "at(2026-12-31T23:59:00)" \
  --target '{
    "Arn": "arn:aws:scheduler:::aws-sdk:sqs:sendMessage",
    "RoleArn": "arn:aws:iam::ACCOUNT:role/SchedulerRole",
    "SqsParameters": {
      "QueueUrl": "https://sqs.region.amazonaws.com/account/queue-name",
      "MessageBody": "{\"event\": \"campaign_ended\"}"
    }
  }'

200+ ターゲット API

Lambda 呼び出し

aws scheduler create-schedule \
  --name daily-report-generation \
  --schedule-expression "cron(0 2 * * ? *)" \
  --timezone "Asia/Tokyo" \
  --target '{
    "Arn": "arn:aws:scheduler:::aws-sdk:lambda:invoke",
    "RoleArn": "arn:aws:iam::ACCOUNT:role/SchedulerRole",
    "LambdaParameters": {
      "FunctionName": "arn:aws:lambda:region:account:function:my-report-function",
      "Payload": "{\"reportType\": \"daily\", \"format\": \"pdf\"}"
    }
  }' \
  --retry-policy '{"MaximumRetryAttempts": 3}'

ECS タスク実行

aws scheduler create-schedule \
  --name nightly-batch-processing \
  --schedule-expression "cron(0 3 * * ? *)" \
  --timezone "America/New_York" \
  --target '{
    "Arn": "arn:aws:scheduler:::aws-sdk:ecs:runTask",
    "RoleArn": "arn:aws:iam::ACCOUNT:role/SchedulerRole",
    "EcsParameters": {
      "LaunchType": "FARGATE",
      "NetworkConfiguration": {
        "AwsvpcConfiguration": {
          "Subnets": ["subnet-xxxxx"],
          "AssignPublicIp": "DISABLED"
        }
      },
      "TaskDefinitionArn": "arn:aws:ecs:region:account:task-definition/batch-job:1",
      "Cluster": "batch-cluster",
      "TaskRoleArn": "arn:aws:iam::ACCOUNT:role/EcsTaskRole"
    }
  }' \
  --flexible-time-window '{"Mode": "FLEXIBLE", "MaximumWindowInMinutes": 30}'

Redshift クエリ実行

aws scheduler create-schedule \
  --name monthly-analytics-refresh \
  --schedule-expression "cron(0 5 1 * ? *)" \
  --timezone "UTC" \
  --target '{
    "Arn": "arn:aws:scheduler:::aws-sdk:redshift:executeStatement",
    "RoleArn": "arn:aws:iam::ACCOUNT:role/SchedulerRole",
    "RedshiftParameters": {
      "ClusterIdentifier": "my-cluster",
      "Database": "analytics",
      "Sql": "REFRESH MATERIALIZED VIEW customer_metrics",
      "AwsAuthenticationToken": null,
      "DbUser": null
    }
  }' \
  --retry-policy '{"MaximumRetryAttempts": 1}'

Step Functions 実行

aws scheduler create-schedule \
  --name weekly-approval-workflow \
  --schedule-expression "cron(0 9 ? * MON *)" \
  --timezone "Europe/London" \
  --target '{
    "Arn": "arn:aws:scheduler:::aws-sdk:stepfunctions:startExecution",
    "RoleArn": "arn:aws:iam::ACCOUNT:role/SchedulerRole",
    "StepFunctionsParameters": {
      "StateMachineArn": "arn:aws:states:region:account:stateMachine:approval-workflow",
      "Input": "{\"approvalType\": \"budget_review\"}"
    }
  }'

タイムゾーン・フレキシブルタイムウィンドウ

タイムゾーン指定

# Asia/Tokyo(JST)で毎日 09:00
aws scheduler create-schedule \
  --name jst-morning-sync \
  --schedule-expression "cron(0 9 * * ? *)" \
  --timezone "Asia/Tokyo" \
  # 自動的に UTC に変換して実行
  # JST 09:00 = UTC 00:00(冬)/ UTC 23:00(夏)

# America/New_York(EST / EDT)で毎日 08:00
aws scheduler create-schedule \
  --name eastern-time-report \
  --schedule-expression "cron(0 8 * * ? *)" \
  --timezone "America/New_York"
  # 夏時間自動調整あり

フレキシブルタイムウィンドウ(スパイク軽減)

# 厳密なスケジュール(全スケジュール同時実行のリスク)
aws scheduler create-schedule \
  --name precise-execution \
  --flexible-time-window '{"Mode": "OFF"}' \
  # 毎時 0 分に厳密に実行 → 全スケジュール同時実行 → スパイク

# フレキシブルウィンドウ(バックエンド負荷分散)
aws scheduler create-schedule \
  --name flexible-execution \
  --schedule-expression "rate(1 hour)" \
  --flexible-time-window '{
    "Mode": "FLEXIBLE",
    "MaximumWindowInMinutes": 15
  }' \
  # 毎時 0~15 分のランダムな時刻に実行
  # → バックエンドへの負荷を 15 分間に分散

Use Case:複数地域での同時実行回避

Example: マルチ AZ / マルチリージョンのデータ同期

東京リージョン:
  cron(0 9 * * ? *)  TZ=Asia/Tokyo
  FlexibleWindow: 0-5 分

シンガポールリージョン:
  cron(0 10 * * ? *)  TZ=Asia/Singapore
  FlexibleWindow: 0-5 分

ロンドンリージョン:
  cron(0 13 * * ? *)  TZ=Europe/London
  FlexibleWindow: 0-5 分

→ 異なる時刻に実行、マルチリージョン DB への圧力を分散

スケジュールグループ・テナント管理

スケジュールグループ作成(マルチテナント SaaS)

# テナント A 用グループ
aws scheduler create-schedule-group \
  --name tenant-acme-corp \
  --description "ACME Corporation schedules" \
  --tags '[
    {"Key": "Tenant", "Value": "acme-corp"},
    {"Key": "Environment", "Value": "production"}
  ]'

# テナント B 用グループ
aws scheduler create-schedule-group \
  --name tenant-globex-industries \
  --description "Globex Industries schedules"

# テナント A のスケジュール作成(グループ指定)
aws scheduler create-schedule \
  --name daily-report \
  --group-name tenant-acme-corp \
  --schedule-expression "cron(0 9 * * ? *)" \
  --timezone "America/Chicago" \
  --target '{...}'

# テナント B のスケジュール作成
aws scheduler create-schedule \
  --name data-sync \
  --group-name tenant-globex-industries \
  --schedule-expression "rate(1 hour)" \
  --target '{...}'

IAM ポリシー(テナント隔離)

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "ManageAcmeSchedules",
      "Effect": "Allow",
      "Action": [
        "scheduler:CreateSchedule",
        "scheduler:DeleteSchedule",
        "scheduler:UpdateSchedule",
        "scheduler:GetSchedule",
        "scheduler:ListSchedules"
      ],
      "Resource": [
        "arn:aws:scheduler:*:*:schedule/tenant-acme-corp/*"
      ]
    },
    {
      "Sid": "DenyOtherTenants",
      "Effect": "Deny",
      "Action": [
        "scheduler:*"
      ],
      "Resource": [
        "arn:aws:scheduler:*:*:schedule/tenant-*/*"
      ],
      "Condition": {
        "StringNotLike": {
          "aws:RequestedRegion": "*"
        }
      }
    }
  ]
}

リトライ・DLQ・エラーハンドリング

リトライポリシー設定

# 3 回まで自動リトライ、各リトライ間隔は指数バックオフ
aws scheduler create-schedule \
  --name reliable-batch-job \
  --schedule-expression "cron(0 3 * * ? *)" \
  --target '{...}' \
  --retry-policy '{
    "MaximumEventAge": 86400,
    "MaximumRetryAttempts": 3
  }' \
  # MaximumEventAge: 86400秒 = 24時間
  # MaximumRetryAttempts: 最大3回
  # Backoff: 指数(1秒→2秒→4秒)

デッドレターキュー(DLQ)設定

# 全リトライ失敗後、SQS DLQ に通知
aws scheduler create-schedule \
  --name critical-task-with-dlq \
  --schedule-expression "cron(0 12 * * ? *)" \
  --target '{
    "Arn": "arn:aws:scheduler:::aws-sdk:lambda:invoke",
    "RoleArn": "arn:aws:iam::ACCOUNT:role/SchedulerRole",
    "LambdaParameters": {
      "FunctionName": "critical-data-processor"
    }
  }' \
  --retry-policy '{"MaximumRetryAttempts": 3}' \
  --dead-letter-config '{
    "Arn": "arn:aws:sqs:region:account:critical-failures-dlq"
  }'

# DLQ からメッセージ読み取り(失敗の詳細確認)
aws sqs receive-message \
  --queue-url https://sqs.region.amazonaws.com/account/critical-failures-dlq

エラーハンドリング・ロールバック

{
  "schedules": [
    {
      "name": "transaction-processing",
      "retryPolicy": {
        "maximumRetryAttempts": 5,
        "maximumEventAge": 3600
      },
      "deadLetterConfig": {
        "arn": "arn:aws:sqs:region:account:transaction-dlq"
      }
    }
  ]
}

CLI・SDK・IaC 実装例

AWS CLI コマンド集

# スケジュール作成
aws scheduler create-schedule \
  --name my-schedule \
  --schedule-expression "cron(0 9 * * ? *)" \
  --timezone "Asia/Tokyo" \
  --target "{...}" \
  --retry-policy "{...}" \
  --dead-letter-config "{...}"

# スケジュール一覧
aws scheduler list-schedules \
  --group-name my-group

# スケジュール詳細確認
aws scheduler get-schedule \
  --name my-schedule

# スケジュール更新
aws scheduler update-schedule \
  --name my-schedule \
  --schedule-expression "cron(0 10 * * ? *)"

# スケジュール削除
aws scheduler delete-schedule \
  --name my-schedule

# グループ管理
aws scheduler list-schedule-groups
aws scheduler get-schedule-group --name my-group

Terraform で EventBridge Scheduler

resource "aws_scheduler_schedule" "daily_etl" {
  name                = "daily-etl-job"
  schedule_expression = "cron(0 9 * * ? *)"
  timezone            = "Asia/Tokyo"
  
  flexible_time_window {
    mode                           = "FLEXIBLE"
    maximum_window_in_minutes      = 15
  }

  target {
    arn      = "arn:aws:scheduler:::aws-sdk:ecs:runTask"
    role_arn = aws_iam_role.scheduler_role.arn

    ecs_parameters {
      launch_type              = "FARGATE"
      network_configuration {
        subnets            = [aws_subnet.private.id]
        security_groups    = [aws_security_group.ecs.id]
        assign_public_ip   = false
      }
      task_definition_arn = aws_ecs_task_definition.etl.arn
      cluster             = aws_ecs_cluster.main.name
    }
  }

  retry_policy {
    maximum_event_age_in_seconds = 86400
    maximum_retry_attempts       = 2
  }

  dead_letter_config {
    arn = aws_sqs_queue.dlq.arn
  }

  depends_on = [aws_iam_role_policy.scheduler_policy]
}

resource "aws_scheduler_schedule_group" "tenant_a" {
  name = "tenant-acme-corp"
}

Python SDK 例

import boto3
import json
from datetime import datetime, timedelta

scheduler = boto3.client('scheduler')

# スケジュール作成
response = scheduler.create_schedule(
    Name='daily-report',
    ScheduleExpression='cron(0 9 * * ? *)',
    Timezone='Asia/Tokyo',
    Target={
        'Arn': 'arn:aws:scheduler:::aws-sdk:lambda:invoke',
        'RoleArn': 'arn:aws:iam::ACCOUNT:role/SchedulerRole',
        'LambdaParameters': {
            'FunctionName': 'report-generator',
            'Payload': json.dumps({'reportType': 'daily'})
        }
    },
    RetryPolicy={
        'MaximumEventAgeInSeconds': 86400,
        'MaximumRetryAttempts': 3
    },
    DeadLetterConfig={
        'Arn': 'arn:aws:sqs:region:account:my-dlq'
    }
)

print(f"Schedule created: {response['ScheduleArn']}")

# スケジュール一覧取得
schedules = scheduler.list_schedules(GroupName='production')
for schedule in schedules['Schedules']:
    print(f"{schedule['Name']}: {schedule['ScheduleExpression']}")

# スケジュール削除
scheduler.delete_schedule(Name='daily-report')

主要ユースケース(10+)

1. 毎日深夜 ETL バッチ処理(ECS タスク)

  • EventBridge Scheduler: 毎日 03:00(JST)に ECS タスク実行
  • → Lambda 不要(直接 ECS RunTask API 呼び出し)
  • → 失敗時 3 回までリトライ
  • → すべて失敗なら SQS DLQ に通知

2. EC2 / RDS のコスト削減スケジュール

  • 開発環境の夜間停止・朝の起動:
  • → 22:00: EC2 StopInstances / RDS StopDbInstance
  • → 08:00: StartInstances / StartDbInstance
  • → 月 ~$200-500 節約(開発環境複数台)

3. ユーザーリマインダー通知(Lambda 経由)

SaaS アプリのユーザーに 定期通知:
    → 毎日 18:00(JST)に Lambda 呼び出し
    → Lambda が DynamoDB でユーザーリスト取得
    → SES / SNS で メール・SMS 送信
    → 失敗時 DLQ へ

4. データベースメンテナンス(Redshift)

  • Redshift VACUUM / ANALYZE 定期実行:
  • → 毎週日曜 02:00 に executeStatement
  • → 統計情報更新、クエリパフォーマンス最適化

5. SageMaker 定期推論(バッチ)

  • ML モデルの バッチ推論:
  • → 毎日 05:00 に CreateTransformJob
  • → S3 入力データ → 推論 → S3 出力
  • → ダッシュボード更新

6. マルチテナント SaaS の テナント単位スケジュール

  • テナント A: 毎日 09:00(ニューヨーク時間)
  • テナント B: 毎日 10:00(ロンドン時間)
  • テナント C: 毎日 18:00(東京時間)
  • → スケジュールグループで テナント隔離・管理

7. キャンペーン終了・期限処理(One-Time)

  • 特定日時(2026-12-31 23:59:00)に 1 回だけ実行:
  • → キャンペーン終了通知
  • → ポイント有効期限切れ処理
  • → 自動削除

8. DynamoDB TTL 补完処理

  • DynamoDB TTL では削除遅延があるため:
  • → 毎日 23:00 に Lambda 呼び出し
  • → Scan で 期限切れアイテム検出・削除
  • → ストレージコスト最適化

9. CloudFormation スタック定期更新

  • インフラコード変更を 定期適用:
  • → 毎週水曜 14:00 に UpdateStack
  • → ドリフト検出・修正

10. レポート生成・配布

  • 複数形式レポートの 定期生成・メール配信:
  • → 毎週月曜 08:00 に Step Functions 実行
  • → PDF/Excel 生成 → S3 保存 → メール送信
  • → 経営層・ダッシュボード用

11. ログローテーション・アーカイブ

  • CloudWatch Logs → S3 Glacier への アーカイブ:
  • → 毎月 1 日 02:00 に Lambda 実行
  • → 古いログを Glacier に 移動・圧縮

12. Kubernetes クラスタの 定期スケーリング

  • オンプレミス Kubernetes または EKS:
  • → 営業時間: ノード数 10
  • → 夜間・土日: ノード数 3
  • → EventBridge Scheduler で API 呼び出し

セキュリティ・IAM

IAM ロール・ポリシー

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "AllowSchedulerToInvokeLambda",
      "Effect": "Allow",
      "Action": [
        "lambda:InvokeFunction"
      ],
      "Resource": [
        "arn:aws:lambda:region:account:function/my-function"
      ]
    },
    {
      "Sid": "AllowSchedulerToRunECS",
      "Effect": "Allow",
      "Action": [
        "ecs:RunTask"
      ],
      "Resource": [
        "arn:aws:ecs:region:account:task-definition/my-task:*"
      ]
    },
    {
      "Sid": "AllowSchedulerToSendDLQ",
      "Effect": "Allow",
      "Action": [
        "sqs:SendMessage"
      ],
      "Resource": [
        "arn:aws:sqs:region:account:my-dlq"
      ]
    },
    {
      "Sid": "AllowPassRole",
      "Effect": "Allow",
      "Action": [
        "iam:PassRole"
      ],
      "Resource": [
        "arn:aws:iam::account:role/EcsTaskRole"
      ]
    }
  ]
}

暗号化・VPC エンドポイント

# VPC エンドポイント経由で Scheduler API 呼び出し
aws ec2 create-vpc-endpoint \
  --vpc-id vpc-xxxxx \
  --service-name com.amazonaws.region.scheduler \
  --route-table-ids rtb-xxxxx

監視・メトリクス

CloudWatch メトリクス

主要メトリクス:

InvocationsAttempted(実行試行数)
InvocationsFailedRetryableCount(リトライ可能な失敗)
InvocationsFailedNonRetryableCount(リトライ不可な失敗)
InvocationsSucceeded(成功数)
TargetErrorCount(ターゲット側エラー)
DLQMessageReceived(DLQ へのメッセージ送信数)

CloudWatch ログ

# Scheduler ログを CloudWatch Logs に送信
aws logs describe-log-groups \
  --query 'logGroups[?logGroupName==`/aws/scheduler/`]'

# 実行ログ確認
aws logs tail /aws/scheduler/my-schedule --follow

CloudWatch アラーム設定

# 失敗数アラーム
aws cloudwatch put-metric-alarm \
  --alarm-name scheduler-failures \
  --metric-name InvocationsFailedRetryableCount \
  --namespace AWS/Scheduler \
  --statistic Sum \
  --period 300 \
  --threshold 5 \
  --comparison-operator GreaterThanOrEqualToThreshold \
  --alarm-actions arn:aws:sns:region:account:alert-topic

EventBridge Rules との比較

観点 EventBridge Scheduler EventBridge Rules(スケジュール)
用途 純粋なスケジューリング イベント駆動 + スケジュール
スケジュール機能 Cron / Rate / One-Time Cron / Rate のみ
タイムゾーン対応 ✅(ネイティブ) UTC のみ
フレキシブルウィンドウ
ターゲット数 200+ 制限的(イベント処理向け)
スケジュール数制限 グループあたり 1,000 アカウントあたり 300 Rules
リトライ・DLQ ✅(組み込み) Dead Letter Queue のみ
マルチテナント管理 ✅(Schedule Groups)
無料枠 1,400万回/月 ✅(CloudWatch Events 無料)
推奨用途 スケジューリング中心 イベント駆動中心

CloudWatch Events(レガシー)との比較

観点 EventBridge Scheduler CloudWatch Events(レガシー)
現状 最新・推奨 レガシー(サポート継続中)
スケジュール機能 ✅(Cron / Rate / One-Time) Cron / Rate のみ
タイムゾーン ✅(ネイティブ) UTC のみ
コンソール EventBridge Scheduler 専用 UI CloudWatch Events コンソール
API AWS Scheduler API EventBridge / CloudWatch Events API
マイグレーション - Scheduler への移行推奨

ベストプラクティス

設計段階

フレキシブルタイムウィンドウで スパイク軽減

# 全スケジュール 00:00 同時実行 ❌
# → 09:00~09:15 ランダム実行 ✅
--flexible-time-window '{"Mode": "FLEXIBLE", "MaximumWindowInMinutes": 15}'

マルチテナント SaaS なら スケジュールグループで テナント隔離

# テナント単位で グループ作成
# → IAM ポリシー で アクセス制御
# → リソース上限 (1,000/グループ) を複数グループで回避

リトライ・DLQ で 信頼性確保

{
  "retryPolicy": {
    "maximumRetryAttempts": 3,
    "maximumEventAge": 86400
  },
  "deadLetterConfig": {
    "arn": "arn:aws:sqs:...:dlq"
  }
}

実装段階

CloudWatch Logs 有効化

  • 全スケジュール実行をログ出力
  • 失敗原因追跡用

Lambda 経由を最小化

  • Lambda 定常コスト削減
  • 直接 AWS API 呼び出し(ECS・SQS・Redshift 等)

テスト環境での 検証

  • 本番前に スケジュール動作確認
  • リトライ・DLQ 動作テスト

運用段階

定期的な メトリクス監視

  • InvocationsFailedRetryableCount > 0 時は原因調査
  • DLQMessageReceived 増加は 要注意

One-Time Schedule の 自動削除

# 実行後に自動削除(リソース整理)
--schedule-expression "at(2026-12-31T23:59:00)"
# 実行後、ユーザーが削除する必要なし(自動クリーンアップ可能化検討中)

定期的な DLQ メッセージ確認

  • 失敗パターンを分析
  • パフォーマンス・タイムアウト調整

トラブルシューティング

症状 原因 対策
スケジュール実行されない IAM ロール権限不足 / Scheduler が disabled 1. IAM ポリシー確認、2. Schedule 状態確認(get-schedule)
リトライが無限ループ MaximumRetryAttempts 設定なし / ターゲット永続エラー MaximumRetryAttempts 設定、ターゲット側エラー修正
タイムゾーン計算エラー UTC 変換ミス(夏時間対応ミス) Scheduler が自動対応、正しいタイムゾーン指定を確認
DLQ に メッセージ蓄積 ターゲット 呼び出し失敗が多発 ターゲット側 ログ・メトリクス確認、エラー修正
フレキシブルウィンドウで 実行時刻が不規則 仕様通り動作 ❌ 厳密な時刻要求ならば Mode=“OFF”

2025-2026 最新動向

1. リトライポリシー拡張(2025年)

  • 指数バックオフ:1秒→2秒→4秒で リトライ間隔自動調整
  • 最大リトライ期間:MaximumEventAge で 24 時間内制限

2. フレキシブルタイムウィンドウ標準化(2025年)

  • 推奨デフォルト:スパイク軽減のため デフォルト FLEXIBLE 化 検討中
  • ウィンドウ幅最適化:AWS AI がスケジュール密度から自動推奨

3. EventBridge Rules との統合シナリオ拡大

  • Scheduler → Rules → Lambda:複雑なイベント処理
  • Rules → Scheduler:イベント駆動でスケジュール変更

4. マルチリージョン Schedule Groups

  • リージョン間 レプリケーション:DR / 多地域展開での スケジュール同期(検討中)

学習リソース

公式ドキュメント

  1. Amazon EventBridge Scheduler User Guide
  2. Schedule Types
  3. Flexible Time Windows
  4. Schedule Groups
  5. EventBridge Scheduler API Reference

AWS ブログ・チュートリアル

  1. AWS What’s New: EventBridge Scheduler
  2. Getting Started with Scheduler

関連リソース

  1. Cron Expression Format
  2. EventBridge Documentation
  3. CloudWatch Events (Legacy)

実装例・チェックリスト

実装例:マルチテナント SaaS 定期タスク

# 各テナント用スケジュール グループ作成
aws scheduler create-schedule-group --name tenant-acme-corp
aws scheduler create-schedule-group --name tenant-globex-inc

# テナント A:毎日 09:00(ニューヨーク時間)に Lambda 実行
aws scheduler create-schedule \
  --name daily-sync \
  --group-name tenant-acme-corp \
  --schedule-expression "cron(0 9 * * ? *)" \
  --timezone "America/New_York" \
  --target '{
    "Arn": "arn:aws:scheduler:::aws-sdk:lambda:invoke",
    "RoleArn": "arn:aws:iam::ACCOUNT:role/SchedulerRole",
    "LambdaParameters": {
      "FunctionName": "tenant-sync-function",
      "Payload": "{\"tenantId\": \"acme-corp\"}"
    }
  }' \
  --retry-policy '{"MaximumRetryAttempts": 2}' \
  --dead-letter-config '{
    "Arn": "arn:aws:sqs:region:account:tenant-acme-dlq"
  }'

# テナント B:毎日 08:00(ロンドン時間)に ECS タスク実行
aws scheduler create-schedule \
  --name data-processing \
  --group-name tenant-globex-inc \
  --schedule-expression "cron(0 8 * * ? *)" \
  --timezone "Europe/London" \
  --target '{
    "Arn": "arn:aws:scheduler:::aws-sdk:ecs:runTask",
    "RoleArn": "arn:aws:iam::ACCOUNT:role/SchedulerRole",
    "EcsParameters": {
      "LaunchType": "FARGATE",
      "TaskDefinitionArn": "arn:aws:ecs:region:account:task-definition/process:1",
      "Cluster": "batch-cluster"
    }
  }' \
  --flexible-time-window '{"Mode": "FLEXIBLE", "MaximumWindowInMinutes": 10}'

導入チェックリスト

  • [ ] 計画段階

    • [ ] スケジューリング要件の整理(頻度・トリガータイプ)
    • [ ] ターゲット AWS サービス確認(Lambda / ECS / Redshift 等)
    • [ ] タイムゾーン・リージョン要件定義
    • [ ] マルチテナント要件(あれば)グループ設計
  • [ ] 設計段階

    • [ ] Cron / Rate 式の精密化
    • [ ] フレキシブルタイムウィンドウの 設定値決定(スパイク軽減)
    • [ ] リトライ・DLQ ポリシー設計
    • [ ] IAM ロール・ポリシー設計(最小権限)
  • [ ] 実装段階

    • [ ] テスト環境で スケジュール作成・実行テスト
    • [ ] CloudWatch Logs / Metrics 確認
    • [ ] DLQ メッセージ 処理確認
    • [ ] フェイルオーバー・リトライ 動作テスト
  • [ ] 本番段階

    • [ ] IAM ロール・ポリシー 適用
    • [ ] CloudWatch アラーム 設定
    • [ ] 本番スケジュール 有効化
    • [ ] 初回実行 監視
  • [ ] 運用段階

    • [ ] 定期的な メトリクス・ログ 確認
    • [ ] DLQ メッセージ 監視・原因調査
    • [ ] パフォーマンス・タイムアウト 最適化

まとめ

Amazon EventBridge Scheduler は「エンタープライズ規模の スケジューリング基盤」 です。

主要なポイント:

  1. 200+ ターゲット API:Lambda を経由せず、直接 AWS API 呼び出し可能
  2. タイムゾーンネイティブ:Asia/Tokyo など直接指定、UTC 変換不要
  3. フレキシブルウィンドウ:スパイク軽減、バックエンド負荷分散
  4. スケジュールグループ:マルチテナント SaaS でテナント隔離・管理
  5. リトライ・DLQ:失敗時の自動リトライ + DLQ で信頼性向上
  6. 1,400万回/月無料:ほぼすべての組織で無料・低コスト

採用判断:

EventBridge Scheduler を選ぶべき

  • 定期バッチ処理・スケジューリング重視
  • 複数 AWS サービス(ECS・Redshift・Lambda)の定期実行
  • タイムゾーン指定が重要(日本・多国展開)
  • マルチテナント SaaS で テナント単位管理

CloudWatch Events / EventBridge Rules 検討

  • 複雑なイベントフィルタリング・変換
  • イベント駆動アーキテクチャ重視
  • SaaS・カスタムイベントソース

EventBridge Scheduler は、エンタープライズ・SaaS・データエンジニア が大規模で複雑なスケジューリング要件を シンプル・低コスト で実現する標準プラットフォームです。


参考文献

公式ドキュメント

AWS ブログ・ウェビナー

  1. AWS What’s New: EventBridge Scheduler
  2. Serverless Application Repository - Scheduler Examples

関連ツール・比較


最終更新:2026-04-26
バージョン:v2.0