- AWS
EventBridge Schedulerの使い方|cron・rate・1回実行
EventBridge Scheduler は、決めた時刻や間隔で AWS の API(Lambda の呼び出し、SQS への送信、ECS タスクの起動など)を呼ぶサービスです。 スケジュール1つにターゲット1つを持ち、cron・rate・at(1回だけ)の3種類の式と、Asia/Tokyo などのタイムゾーンを指定できます。AWS のドキュメントでは、時刻で何かを動かすときは EventBridge のスケジュールルールより Scheduler を使うよう勧められています。
# 平日の 9:00(日本時間)に Lambda を呼ぶ
aws scheduler create-schedule \
--name daily-report \
--schedule-expression 'cron(0 9 ? * MON-FRI *)' \
--schedule-expression-timezone Asia/Tokyo \
--flexible-time-window '{"Mode":"OFF"}' \
--target '{
"Arn": "arn:aws:lambda:ap-northeast-1:123456789012:function:daily-report",
"RoleArn": "arn:aws:iam::123456789012:role/scheduler-exec",
"Input": "{\"source\":\"scheduler\"}"
}'
| 式 | 書き方 | 例 | タイムゾーン |
|---|---|---|---|
| 1回だけ | at(yyyy-mm-ddThh:mm:ss) |
at(2026-10-20T09:00:00) |
指定できる |
| 一定間隔 | rate(値 単位) |
rate(5 minutes)・rate(1 hour) |
関係なし(開始から一定間隔) |
| 日時の指定 | cron(分 時 日 月 曜日 年) |
cron(0 9 ? * MON-FRI *) |
指定できる |
確認環境:AWS CLI 1.46.1・boto3 1.43.112・Python 3.11(Linux)。AWS には接続せず、moto 5.2.4 のサーバーモードに CLI を向けて、create-schedule(SQS・Lambda・ECS・ユニバーサルターゲット、DLQ・再試行ポリシー付き)、get-schedule・list-schedules・update-schedule・delete-schedule、スケジュールグループ、ActionAfterCompletion、boto3 での1回だけのスケジュール作成を動かしました。moto はターゲットを実際には呼ばないため、呼び出しの時刻・再試行・DLQ への送り方・上限・料金は AWS のドキュメントに基づいています(確認日 2026年10月13日)。
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「EventBridge Schedulerの使い方|cron・rate・1回実行」
EventBridge ルール(スケジュール式)との違い
EventBridge には、前からある「スケジュールルール」(aws events put-rule --schedule-expression)と、2022年に出た「EventBridge Scheduler」(aws scheduler)の2つがあります。ドキュメントでは、スケジュールルールは legacy(従来の機能) とされ、Scheduler が勧められています。
| 項目 | EventBridge Scheduler | EventBridge ルール(スケジュール) |
|---|---|---|
| CLI・リソース | aws scheduler・AWS::Scheduler::Schedule |
aws events・AWS::Events::Rule |
| タイムゾーン | IANA のタイムゾーンを指定できる(夏時間も調整) | UTC だけ |
| 1回だけの実行 | at() 式がある |
無い(cron で年まで指定して代用) |
| ターゲット | テンプレート化ターゲット+ユニバーサルターゲット(270 以上のサービス、6,000 以上の API) | ルールの対応ターゲット。1 ルールに最大 5 個 |
| スケジュールとターゲット | 1 対 1 | 1 対 多(最大 5) |
| 作れる数(既定) | 1 リージョンに 10,000,000 スケジュール | 1 イベントバスに 300 ルール(東京) |
| 再試行・DLQ | スケジュールごとに設定 | ターゲットごとに設定 |
| フレックスタイムウィンドウ | ある | 無い |
| 呼び出しの権限 | 実行ロール(Scheduler が引き受ける) | ターゲット側のリソースポリシー(Lambda の add-permission など)またはロール |
| 実行の精度 | 60 秒(指定した分の 00〜59 秒の間) | 1 分。数秒の遅れがあり得る |
上限の数はドキュメントの値です(ルールは「Custom Event Bus - Classic」の表)。スケジュールルールの cron の書き方と、UTC への換算は、関連記事「EventBridge cron式の書き方|JST変換と例の早見表」で扱っています。Scheduler では --schedule-expression-timezone Asia/Tokyo を付けると、cron を日本時間のまま書けます。
準備:実行ロールを作る
Scheduler は、スケジュールに付けた IAM ロール(実行ロール)を引き受けて、ターゲットの API を呼びます。 信頼ポリシーのプリンシパルは scheduler.amazonaws.com です。
cat > trust.json <<'EOF'
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": { "Service": "scheduler.amazonaws.com" },
"Action": "sts:AssumeRole",
"Condition": { "StringEquals": { "aws:SourceAccount": "123456789012" } }
}]
}
EOF
aws iam create-role --role-name scheduler-exec \
--assume-role-policy-document file://trust.json
Condition の aws:SourceAccount は、自分のアカウントのスケジュールだけがこのロールを使えるようにする条件です。ドキュメントの基本例には無く、本番では「混乱した代理(confused deputy)」を防ぐ条件を足すよう案内されています。信頼ポリシーの読み方は、関連記事「IAMロールとは|ユーザー・ポリシーとの違いとAssumeRole、信頼ポリシー」で扱っています。
ターゲットごとに付ける権限です。
| ターゲット | 実行ロールに必要な権限 |
|---|---|
| Lambda | lambda:InvokeFunction |
| SQS | sqs:SendMessage(KMS で暗号化したキューなら KMS の権限も) |
| SNS | sns:Publish |
| ECS(RunTask) | ecs:RunTask、タスクロール・タスク実行ロールを渡す iam:PassRole |
| Step Functions | states:StartExecution |
| ユニバーサルターゲット | 呼ぶ API の権限(例:ec2:StopInstances) |
| DLQ を付けるとき | DLQ のキューへの sqs:SendMessage |
cat > invoke.json <<'EOF'
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Action": "lambda:InvokeFunction",
"Resource": "arn:aws:lambda:ap-northeast-1:123456789012:function:daily-report*"
}]
}
EOF
aws iam put-role-policy --role-name scheduler-exec \
--policy-name invoke-lambda --policy-document file://invoke.json
ドキュメントの例は "Resource": "*" ですが、呼ぶ関数やキューの ARN に絞ることができます。Lambda 側に add-permission(リソースベースのポリシー)を足す操作は、Scheduler では使いません。 ロールの権限で呼ぶためです。
スケジュール式の書き方
at:1回だけ
at(2026-10-20T09:00:00) ← --schedule-expression-timezone Asia/Tokyo なら日本時間の 9:00
| 決まり(ドキュメント) | 内容 |
|---|---|
| 形式 | at(yyyy-mm-ddThh:mm:ss)。タイムゾーンは --schedule-expression-timezone で指定(省くと UTC) |
| 開始日・終了日 | --start-date・--end-date は無視される |
| 実行後 | スケジュールは残り、上限の数に数えられ続ける。--action-after-completion DELETE で自動で消せる |
rate:一定間隔
rate(5 minutes) rate(1 hour) rate(7 days)
| 決まり(ドキュメント) | 内容 |
|---|---|
| 単位 | minutes・hours・days(値は正の数) |
| 最初の実行 | --start-date があればそこから。無ければ作った直後から |
days と夏時間 |
days は「24 時間」として数える。夏時間で1日が 23・25 時間になっても、前回の 24 時間後 |
rate は「何時何分」を決めません。毎日 9:00 のように時刻をそろえるなら cron を使います。
cron:日時の指定
cron(分 時 日 月 曜日 年) の6つを空白で区切ります。
| フィールド | 値 | 使える記号 |
|---|---|---|
| 分 | 0-59 | , - * / |
| 時 | 0-23 | , - * / |
| 日 | 1-31 | , - * ? / L W |
| 月 | 1-12 または JAN-DEC | , - * / |
| 曜日 | 1-7 または SUN-SAT(1 が日曜) | , - * ? L # |
| 年 | 1970-2199 | , - * / |
「日」と「曜日」の両方に * は書けません。 どちらかに *(または値)を書いたら、もう片方は ? にします。cron(0 9 * * MON-FRI *) は誤りで、cron(0 9 ? * MON-FRI *) が正しい形です。
よく使う例です(--schedule-expression-timezone Asia/Tokyo を付けた場合)。
| やりたいこと | 式 |
|---|---|
| 毎日 2:30 | cron(30 2 * * ? *) |
| 平日 9:00 | cron(0 9 ? * MON-FRI *) |
| 平日 9〜18 時の毎時 0 分 | cron(0 9-18 ? * MON-FRI *) |
| 15 分ごと | cron(0/15 * * * ? *) |
| 毎月 1 日 0:00 | cron(0 0 1 * ? *) |
| 毎月末日 18:00 | cron(0 18 L * ? *) |
| 毎月 15 日に一番近い平日 10:00 | cron(0 10 15W * ? *) |
| 第 2 火曜 10:00 | cron(0 10 ? * 3#2 *) |
| 毎月最後の金曜 10:15 | cron(15 10 ? * 6L *) |
# を使うときは、曜日のフィールドに式を1つしか書けません(3#1,6#3 は不可)。
タイムゾーンと夏時間
| 項目 | 内容(ドキュメント) |
|---|---|
| 指定できる式 | cron と at。値は IANA のタイムゾーン名(Asia/Tokyo・America/New_York など) |
| 省いたとき | UTC |
| 夏時間で時刻が進む日 | その時刻が存在しなければ、その日の実行は飛ばされる |
| 夏時間で時刻が戻る日 | 1回だけ実行され、繰り返さない |
| 精度 | 60 秒。1:00 の指定なら 1:00:00〜1:00:59 の間に呼ぶ(フレックスタイムウィンドウ無しのとき) |
Asia/Tokyo には夏時間が無いので、日本時間で書くかぎり、飛ばされたり重なったりはしません。
create-schedule:ターゲット別の設定
ターゲットは2種類あります。
| 種類 | Arn に入れるもの |
対象 |
|---|---|---|
| テンプレート化ターゲット | 呼ぶリソースの ARN(関数・キュー・クラスターなど) | Lambda Invoke、SQS SendMessage、SNS Publish、Step Functions StartExecution、ECS RunTask、EventBridge PutEvents、Kinesis・Firehose PutRecord、CodeBuild・CodePipeline・SageMaker の開始、Inspector |
| ユニバーサルターゲット | arn:aws:scheduler:::aws-sdk:サービス:API名 |
上記以外の AWS API |
Lambda
aws scheduler create-schedule \
--name cleanup-hourly \
--schedule-expression 'rate(1 hour)' \
--flexible-time-window '{"Mode":"OFF"}' \
--target '{
"Arn": "arn:aws:lambda:ap-northeast-1:123456789012:function:cleanup",
"RoleArn": "arn:aws:iam::123456789012:role/scheduler-exec",
"Input": "{\"source\":\"scheduler\",\"at\":\"<aws.scheduler.scheduled-time>\"}"
}'
Input の文字列が、そのまま Lambda の event になります。関数側では event["at"] に予定の時刻が入ります。Lambda 関数の作り方は、関連記事「AWS CLIでLambdaを作成・更新 環境変数とレイヤー」で扱っています。
SQS(DLQ・再試行つき)
moto で作って get-schedule で読み戻した形です。
aws scheduler create-schedule-group --name batch
aws scheduler create-schedule --name daily-report --group-name batch \
--schedule-expression 'cron(0 9 ? * MON-FRI *)' --schedule-expression-timezone Asia/Tokyo \
--flexible-time-window '{"Mode":"FLEXIBLE","MaximumWindowInMinutes":15}' \
--target file://sqs-target.json
{
"Arn": "arn:aws:sqs:ap-northeast-1:123456789012:jobs",
"RoleArn": "arn:aws:iam::123456789012:role/scheduler-exec",
"Input": "{\"job\":\"report\",\"at\":\"<aws.scheduler.scheduled-time>\"}",
"RetryPolicy": { "MaximumEventAgeInSeconds": 3600, "MaximumRetryAttempts": 3 },
"DeadLetterConfig": { "Arn": "arn:aws:sqs:ap-northeast-1:123456789012:scheduler-dlq" }
}
$ aws scheduler get-schedule --name daily-report --group-name batch
"Arn": "arn:aws:scheduler:ap-northeast-1:123456789012:schedule/batch/daily-report",
"FlexibleTimeWindow": { "MaximumWindowInMinutes": 15, "Mode": "FLEXIBLE" },
"ScheduleExpression": "cron(0 9 ? * MON-FRI *)",
"ScheduleExpressionTimezone": "Asia/Tokyo",
"State": "ENABLED",
--target は file:// で JSON ファイルを渡すと、引用符のエスケープで迷いません。FIFO キューに送るときは "SqsParameters": {"MessageGroupId": "..."} を足し、キュー側でコンテンツに基づく重複排除を有効にしておきます(CLI リファレンス)。SQS の基本は関連記事「Amazon SQSの使い方|送受信・削除と可視性タイムアウト、FIFO」で扱っています。
ECS(Fargate タスクの起動)
Arn にはクラスターの ARN、EcsParameters にタスク定義とネットワークを入れます。
{
"Arn": "arn:aws:ecs:ap-northeast-1:123456789012:cluster/batch",
"RoleArn": "arn:aws:iam::123456789012:role/scheduler-exec",
"EcsParameters": {
"TaskDefinitionArn": "arn:aws:ecs:ap-northeast-1:123456789012:task-definition/nightly-job",
"TaskCount": 1,
"LaunchType": "FARGATE",
"PlatformVersion": "LATEST",
"NetworkConfiguration": {
"awsvpcConfiguration": {
"Subnets": ["subnet-0123456789abcdef0"],
"SecurityGroups": ["sg-0123456789abcdef0"],
"AssignPublicIp": "DISABLED"
}
}
},
"Input": "{\"containerOverrides\":[{\"name\":\"app\",\"command\":[\"python\",\"nightly.py\"]}]}"
}
aws scheduler create-schedule --name nightly-ecs \
--schedule-expression 'cron(30 2 * * ? *)' --schedule-expression-timezone Asia/Tokyo \
--flexible-time-window '{"Mode":"OFF"}' --target file://ecs-target.json
| 項目(CLI リファレンス) | 内容 |
|---|---|
awsvpcConfiguration |
先頭の a が小文字。中の Subnets・SecurityGroups・AssignPublicIp は大文字始まり |
Subnets |
必須。最大 16 |
SecurityGroups |
最大 5。省くと VPC の既定のセキュリティグループ |
AssignPublicIp |
ENABLED は Fargate のときだけ。プライベートサブネットなら DISABLED で、NAT か VPC エンドポイントが要る |
TaskCount |
1〜10(既定 1) |
Input |
RunTask の追加の引数。上の例ではコンテナのコマンドを上書き |
タスク定義の書き方は、関連記事「ECSタスク定義JSONの書き方|Fargate必須項目と環境変数secrets」で扱っています。
ユニバーサルターゲット(例:開発用 EC2 を夜に止める)
テンプレートに無い API は、arn:aws:scheduler:::aws-sdk:サービス:API名 で呼べます。Input には、その API のリクエストの JSON をそのまま書きます。
aws scheduler create-schedule --name stop-dev-ec2 \
--schedule-expression 'cron(0 20 ? * MON-FRI *)' --schedule-expression-timezone Asia/Tokyo \
--flexible-time-window '{"Mode":"OFF"}' \
--target '{
"Arn": "arn:aws:scheduler:::aws-sdk:ec2:stopInstances",
"RoleArn": "arn:aws:iam::123456789012:role/scheduler-exec",
"Input": "{\"InstanceIds\":[\"i-0123456789abcdef0\"]}"
}'
| 決まり(ドキュメント) | 内容 |
|---|---|
| サービス名 | SDK のサービス名(エンドポイントの名前と違うことがある。Cognito ユーザープールは cognitoidentityprovider) |
| API 名 | 先頭小文字(stopInstances・sendMessage) |
| 呼べない API | get・describe・list・poll・receive・search・scan・query・select・read・lookup・discover・validate・batchGet・retrieve・invokeModel などで始まる読み取り系 |
Input で使える置き換え
Input の中に書くと、呼び出しのたびに値に置き換わります。
| キーワード | 値の例 |
|---|---|
<aws.scheduler.schedule-arn> |
スケジュールの ARN |
<aws.scheduler.scheduled-time> |
予定の時刻(2022-03-22T18:59:43Z) |
<aws.scheduler.execution-id> |
呼び出しごとの ID |
<aws.scheduler.attempt-number> |
何回目の試行か(1 から) |
execution-id は再試行でも同じ値ではなく、scheduled-time は予定の時刻です。Scheduler の配信は「少なくとも1回」(AWS のブログ)なので、同じ予定時刻の処理が2回来ても結果が変わらないよう、scheduled-time を処理済みのキーにする作り方があります。
フレックスタイムウィンドウ
FLEXIBLE にすると、予定の時刻から最大 N 分の間のどこかで呼びます。 多数のスケジュールが同じ時刻に集まるときに、呼び出しを散らせます。
| 値(API リファレンス) | 内容 |
|---|---|
{"Mode":"OFF"} |
予定の時刻に呼ぶ |
{"Mode":"FLEXIBLE","MaximumWindowInMinutes":15} |
予定の時刻から 15 分以内に呼ぶ |
MaximumWindowInMinutes |
1〜1,440 |
--flexible-time-window は省けません。 CLI では次のエラーになりました。
aws: error: the following arguments are required: --flexible-time-window
MaximumWindowInMinutes に 0 を入れると、送る前に止まります。
Parameter validation failed:
Invalid value for parameter FlexibleTimeWindow.MaximumWindowInMinutes, value: 0, valid min value: 1
決まった時刻ちょうどに動かしたい処理(締めの集計など)は OFF、多少ずれてよい処理は FLEXIBLE です。
再試行と DLQ
ターゲットの呼び出しに失敗すると、Scheduler は再試行し、それでも届かなければ DLQ(SQS の標準キュー)に送ります。
| 項目 | 内容 |
|---|---|
MaximumRetryAttempts |
0〜185。再試行の回数。0 で再試行しない |
MaximumEventAgeInSeconds |
60〜86,400(24 時間)。この時間を過ぎたら再試行をやめる |
| 指定しないとき | 24 時間・185 回まで再試行(AWS のブログ。moto でも get-schedule に 86400・185 が入った) |
| 再試行の間隔 | 指数バックオフ(だんだん間隔をあける) |
| DLQ が無いとき | 再試行し尽くしたイベントは捨てられる |
| DLQ のキュー | 標準キューだけ。FIFO は使えない |
moto で RetryPolicy を書かずに作ったスケジュールです。
$ aws scheduler get-schedule --name every5 --query Target.RetryPolicy
{
"MaximumEventAgeInSeconds": 86400,
"MaximumRetryAttempts": 185
}
1 時間ごとの処理が 24 時間再試行され続けると、次の回と重なります。 間隔より短い MaximumEventAgeInSeconds、少なめの MaximumRetryAttempts にして、DLQ で失敗に気づく形が扱いやすくなります。
DLQ に入ったメッセージには、失敗の理由がメッセージ属性で付きます。
aws sqs receive-message --queue-url "$DLQ_URL" \
--attribute-names All --message-attribute-names All --max-number-of-messages 1
| 属性(ドキュメント) | 内容 |
|---|---|
ERROR_CODE・ERROR_MESSAGE |
ターゲットの API が返したエラー |
EXHAUSTED_RETRY_CONDITION |
MaximumRetryAttempts(回数を使い切った)か MaximumEventAgeInSeconds(時間切れ) |
TARGET_ARN・SCHEDULE_ARN |
呼び先とスケジュール |
SCHEDULED_TIME・EXECUTION_ID・RETRY_ATTEMPTS |
予定の時刻・実行 ID・試行回数 |
IS_PAYLOAD_TRUNCATED |
本文が切り詰められたか |
EXHAUSTED_RETRY_CONDITION は、再試行できるエラーのときに付きます。権限が無いなど、再試行しても直らないエラーでは付きません。DLQ の監視と再処理は、関連記事「SQSデッドレターキューの設定|maxReceiveCountと再処理」で扱っています。
1回だけ実行して自動で消す(アプリから作る)
「3日後にリマインドを送る」のように、アプリが1件ずつスケジュールを作る使い方です。ActionAfterCompletion="DELETE" にすると、実行後に自動で消えます。
import json, uuid
from datetime import datetime
from zoneinfo import ZoneInfo
import boto3
scheduler = boto3.client("scheduler")
def schedule_reminder(user_id: str, run_at: datetime) -> str:
"""run_at の時刻に1回だけ Lambda を呼ぶ。実行後はスケジュールを自動で消す"""
name = f"reminder-{user_id}-{uuid.uuid4().hex[:8]}" # 64 文字以内・英数と - _ .
scheduler.create_schedule(
Name=name,
GroupName="default",
ScheduleExpression=f"at({run_at.strftime('%Y-%m-%dT%H:%M:%S')})",
ScheduleExpressionTimezone="Asia/Tokyo",
FlexibleTimeWindow={"Mode": "OFF"},
ActionAfterCompletion="DELETE",
Target={
"Arn": "arn:aws:lambda:ap-northeast-1:123456789012:function:send-reminder",
"RoleArn": "arn:aws:iam::123456789012:role/scheduler-exec",
"Input": json.dumps({"userId": user_id,
"scheduledTime": "<aws.scheduler.scheduled-time>"}),
"RetryPolicy": {"MaximumRetryAttempts": 3, "MaximumEventAgeInSeconds": 3600},
},
)
return name
run_at = datetime(2026, 10, 16, 9, 0, tzinfo=ZoneInfo("Asia/Tokyo"))
name = schedule_reminder("u123", run_at)
s = scheduler.get_schedule(Name=name)
print(name)
print(s["ScheduleExpression"], s["ScheduleExpressionTimezone"], s["ActionAfterCompletion"])
print(s["Target"]["Input"])
moto に向けて動かした出力です。
reminder-u123-02ad45ec
at(2026-10-16T09:00:00) Asia/Tokyo DELETE
{"userId": "u123", "scheduledTime": "<aws.scheduler.scheduled-time>"}
ActionAfterCompletion(ドキュメント) |
消えるとき |
|---|---|
DELETE・at 式 |
1回呼んだあと |
DELETE・cron/rate 式 |
--end-date に一番近い最後の呼び出しのあと。EndDate が無いと消えない |
NONE(既定) |
消えない。終わった at のスケジュールも上限の数に残る |
取り消すときは delete_schedule(Name=name) です。 名前を DB に保存しておくと、予約のキャンセルに使えます。
更新の注意:update-schedule は「全部置き換え」
update-schedule は、渡さなかった項目を既定値に戻します。 API リファレンスに「指定しなかった任意の項目は、更新後にシステムの既定値になる」と書かれています。
moto で、タイムゾーン・再試行・DLQ・Input を付けたスケジュールを、式とターゲットの ARN だけ渡して更新した結果です。
$ aws scheduler update-schedule --name report --schedule-expression 'cron(0 10 * * ? *)' \
--flexible-time-window Mode=OFF --target '{"Arn":"arn:...:jobs","RoleArn":"arn:...:scheduler-exec"}'
$ aws scheduler get-schedule --name report --query '{Expr:...,TZ:...,Retry:...,DLQ:...,Input:...}'
{
"Expr": "cron(0 10 * * ? *)",
"TZ": "UTC",
"Retry": { "MaximumEventAgeInSeconds": 86400, "MaximumRetryAttempts": 185 },
"DLQ": null,
"Input": null
}
タイムゾーンが UTC に戻り、10 時(日本時間 19 時)の実行になりました。 DLQ と Input も消えています。CLI でも --flexible-time-window と --target を省くとエラーで止まりますが、それ以外は黙って既定値に戻ります。
get-schedule の結果から必要な項目を取り出し、変えたい所だけ書き換えて渡すと安全です。
aws scheduler get-schedule --name report \
| jq '{Name, GroupName, ScheduleExpression, ScheduleExpressionTimezone, FlexibleTimeWindow,
Target, Description, StartDate, EndDate, KmsKeyArn, ActionAfterCompletion}
| with_entries(select(.value != null))
| .State = "DISABLED"' > update.json
aws scheduler update-schedule --cli-input-json file://update.json
moto で動かすと、State だけが DISABLED に変わり、タイムゾーン(Asia/Tokyo)・再試行(3 回・3600 秒)・DLQ は残りました。止める・再開するだけなら、この方法で State を DISABLED/ENABLED にします。
一覧・削除・グループ
aws scheduler list-schedules --query 'Schedules[].[GroupName,Name,State]' --output text
aws scheduler list-schedules --group-name batch --name-prefix daily
aws scheduler delete-schedule --name cleanup-hourly
aws scheduler delete-schedule --name daily-report --group-name batch
aws scheduler delete-schedule-group --name batch # グループ内のスケジュールも消える
| 項目 | 内容 |
|---|---|
| スケジュールグループ | スケジュールをまとめる入れ物。タグはグループに付ける。default が最初からある |
| グループを消すと | 状態が DELETING になり、中のスケジュールも消える(ドキュメント。moto でも消えた) |
--group-name を省くと |
default グループ |
| 名前 | 1〜64 文字、[0-9a-zA-Z-_.]+。グループの中で一意 |
moto で出たエラーと、実際の AWS での扱い
| 操作 | moto での結果 | AWS での扱い(ドキュメント) |
|---|---|---|
| 同じ名前で作る | ConflictException ... Schedule lambda-hourly already exists. |
同じく ConflictException |
| 消したスケジュールを取得 | ResourceNotFoundException ... does not exist. |
同じく 404 |
--flexible-time-window を省く |
CLI のエラー(必須) | 必須 |
MaximumWindowInMinutes=0 |
送る前にエラー(最小 1) | 1〜1,440 |
MaximumRetryAttempts=200 |
作られた | 0〜185。ValidationException になる範囲 |
cron(0 9 * * MON-FRI *) |
作られた | 日と曜日の両方に値があるため不正な式 |
moto は式や上限の範囲を細かく調べません。 テストで作れても、実際の AWS では断られる設定があります。式の書き方は上の表で確かめてから使います。
上限と料金
| 項目(ドキュメント) | 値 |
|---|---|
| スケジュールの数 | 1 リージョンに 10,000,000(引き上げ可)。終わった at のスケジュールも含む |
| スケジュールグループ | 1 リージョンに 500 |
| 呼び出しの速さ | 東京などで 1,000 TPS(ほかは 500)。超えると遅れて呼ばれる(捨てられない) |
CreateSchedule の速さ |
東京などで 5,000 回/秒 |
Input の大きさ |
256 KB(固定) |
| 1つのスケジュールの読み書き | 10 TPS |
| 料金(AWS の料金ページ) | 値 |
|---|---|
| 無料枠 | 毎月 14,000,000 回の呼び出し(GovCloud 以外の全リージョン合計) |
| 超えた分 | 料金ページの計算例では 100 万回あたり 1.00 USD |
5 分ごとのスケジュールは、1 か月(30 日)で 8,640 回です。数百個の定期実行なら無料枠の中に収まる計算です。料金の確かめ方は、関連記事「AWSの料金を確認する方法|Cost Explorer・CLI・予算アラート」で扱っています。
よくある質問
Q. スケジュールが動いたかどうかは、どこで分かりますか。
A. CloudWatch の AWS/Scheduler 名前空間の指標で見ます。値はアカウント全体と、スケジュールグループ(ScheduleGroup ディメンション)ごとに集計されます。
| 指標(ドキュメント) | 分かること |
|---|---|
InvocationAttemptCount |
呼び出しを試みた回数 |
TargetErrorCount・TargetErrorThrottledCount |
ターゲットがエラー・スロットリングを返した |
InvocationThrottleCount |
Scheduler の呼び出しの上限で遅らせた |
InvocationDroppedCount |
再試行を使い切って捨てた(DLQ 無し) |
InvocationsSentToDeadLetterCount |
DLQ に送った |
InvocationDroppedCount と InvocationsSentToDeadLetterCount が 0 より大きくなったら知らせるアラームを作っておくと、失敗に気づけます。関連記事「CloudWatchアラームをAWS CLIで作成|SNS通知・カスタム指標」で扱っています。
Q. 秒単位で動かせますか。 A. できません。精度は 60 秒で、指定した分の中のどこかで呼ばれます。秒単位の待ち合わせは、Step Functions の Wait 状態などで作ります。関連記事「Step Functions入門|ASLの書き方とLambda連携・Retry」で扱っています。
Q. 既存の EventBridge ルールから移すと、何が変わりますか。
A. cron を UTC から日本時間に書き直せること、Lambda の add-permission の代わりに実行ロールを使うこと、ターゲットが1つになることです。ルールに複数のターゲットがあるなら、スケジュールを複数作ります。
Q. CloudFormation ではどう書きますか。
A. AWS::Scheduler::Schedule で、FlexibleTimeWindow・ScheduleExpression・Target が必須です。CLI の JSON と同じ名前の項目が並びます。
まとめ
aws scheduler create-scheduleに 式・--flexible-time-window・--target(ArnとRoleArn) が必須- 時刻は
cron+--schedule-expression-timezone Asia/Tokyo。日と曜日のどちらかは? - 1回だけは
at()。--action-after-completion DELETEで実行後に消す - 実行ロールの信頼ポリシーは
scheduler.amazonaws.com。Lambda のadd-permissionは使わない - 再試行は既定で 24 時間・185 回。間隔に合わせて短くし、DLQ(標準キュー) を付ける
update-scheduleは全部置き換え。get-schedule→ 書き換え →--cli-input-jsonで更新- 無料枠は毎月 1,400 万回の呼び出し
参考・出典
確認日はいずれも 2026年10月13日です。
- EventBridge Scheduler User Guide「Schedule types in EventBridge Scheduler」:https://docs.aws.amazon.com/scheduler/latest/UserGuide/schedule-types.html
- EventBridge Scheduler User Guide「Getting started with EventBridge Scheduler」:https://docs.aws.amazon.com/scheduler/latest/UserGuide/getting-started.html
- EventBridge Scheduler User Guide「Setting up Amazon EventBridge Scheduler」:https://docs.aws.amazon.com/scheduler/latest/UserGuide/setting-up.html
- EventBridge Scheduler User Guide「Using templated targets」「Using universal targets」:https://docs.aws.amazon.com/scheduler/latest/UserGuide/managing-targets-universal.html
- EventBridge Scheduler User Guide「Adding context attributes」:https://docs.aws.amazon.com/scheduler/latest/UserGuide/managing-schedule-context-attributes.html
- EventBridge Scheduler User Guide「Configuring flexible time windows」:https://docs.aws.amazon.com/scheduler/latest/UserGuide/managing-schedule-flexible-time-windows.html
- EventBridge Scheduler User Guide「Configuring a schedule's dead-letter queue」:https://docs.aws.amazon.com/scheduler/latest/UserGuide/configuring-schedule-dlq.html
- EventBridge Scheduler User Guide「Deleting a schedule」「Managing a schedule group」:https://docs.aws.amazon.com/scheduler/latest/UserGuide/managing-schedule-delete.html
- EventBridge Scheduler User Guide「Quotas for EventBridge Scheduler」:https://docs.aws.amazon.com/scheduler/latest/UserGuide/scheduler-quotas.html
- EventBridge Scheduler API Reference「CreateSchedule」「UpdateSchedule」「RetryPolicy」「FlexibleTimeWindow」:https://docs.aws.amazon.com/scheduler/latest/APIReference/API_UpdateSchedule.html
- AWS CLI Command Reference「scheduler create-schedule」:https://docs.aws.amazon.com/cli/latest/reference/scheduler/create-schedule.html
- Amazon EventBridge User Guide「Creating a rule that runs on a schedule」:https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-create-rule-schedule.html
- Amazon EventBridge User Guide「Amazon EventBridge quotas」:https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-quota.html
- Amazon EventBridge の料金:https://aws.amazon.com/eventbridge/pricing/
- AWS Compute Blog「Introducing Amazon EventBridge Scheduler」:https://aws.amazon.com/blogs/compute/introducing-amazon-eventbridge-scheduler/
- クラスメソッド「[新機能] タイムゾーン指定でスケジュール起動できるAmazon EventBridge Schedulerがリリースされました」:https://dev.classmethod.jp/articles/amazon-eventbridge-scheduler-new-way-to-launch-tasks/
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「EventBridge Schedulerの使い方|cron・rate・1回実行」
株式会社RJC ― SI事業・SES事業・AI駆動開発。RJCは一緒に成長を楽しめる会社です。
WE ARE HIRING
RJCで一緒に開発しながら、
成長を楽しみませんか?
RJCは、Web・モバイル・AIを活用した開発プロジェクトで、テックリードやPM・PMOも活躍するシステム開発会社です。会社を知る、待遇を確かめる、話を聞いてみる。気になるところ見てみてください!
- 127日年間休日
- 12時間平均残業時間
- 毎日ガチャ遊びココロも大切にする福利厚生。アマギフなどの賞品ラインナップ!
ほかにも、チケットレストラン、書籍読み放題、2年ごとの慰労報奨(休暇 or 金一封)、11期連続の黒字決算。