185 lines
8.2 KiB
Markdown
185 lines
8.2 KiB
Markdown
# EventBridge Scheduler
|
|
|
|
**Protocol:** REST JSON
|
|
**Endpoint:** `http://localhost:4566/`
|
|
|
|
## Supported Actions
|
|
|
|
| Action | Method | Path | Description |
|
|
|---|---|---|---|
|
|
| `CreateScheduleGroup` | `POST` | `/schedule-groups/{Name}` | Create a schedule group |
|
|
| `GetScheduleGroup` | `GET` | `/schedule-groups/{Name}` | Get schedule group details |
|
|
| `DeleteScheduleGroup` | `DELETE` | `/schedule-groups/{Name}` | Delete a schedule group and its schedules |
|
|
| `ListScheduleGroups` | `GET` | `/schedule-groups` | List schedule groups |
|
|
| `CreateSchedule` | `POST` | `/schedules/{Name}` | Create a schedule |
|
|
| `GetSchedule` | `GET` | `/schedules/{Name}` | Get schedule details |
|
|
| `UpdateSchedule` | `PUT` | `/schedules/{Name}` | Update a schedule |
|
|
| `DeleteSchedule` | `DELETE` | `/schedules/{Name}` | Delete a schedule |
|
|
| `ListSchedules` | `GET` | `/schedules` | List schedules |
|
|
| `TagResource` | `POST` | `/tags/{ResourceArn}` | Add tags to a schedule group |
|
|
| `UntagResource` | `DELETE` | `/tags/{ResourceArn}?TagKeys=...` | Remove tags from a schedule group |
|
|
| `ListTagsForResource` | `GET` | `/tags/{ResourceArn}` | List tags on a schedule group |
|
|
|
|
## Schedule Invocation
|
|
|
|
When `floci.services.scheduler.invocation-enabled` is `true` (the default), a
|
|
background dispatcher fires schedule targets on time. Supported expressions:
|
|
|
|
- `at(YYYY-MM-DDTHH:mm:ss)` — one-time fire; honors `ScheduleExpressionTimezone`
|
|
(default UTC) and `ActionAfterCompletion=DELETE`.
|
|
- `rate(N unit)` — repeating fire (`minutes`, `hours`, `days`, `weeks`).
|
|
- `cron(minute hour day-of-month month day-of-week year)` — AWS 6-field cron;
|
|
honors `ScheduleExpressionTimezone`. Day-of-week is `1-7` or `SUN-SAT`, so
|
|
`2` is Monday and `cron(30 2 ? * 2#1 *)` is the first Monday of the month.
|
|
|
|
`State=DISABLED` schedules and schedules outside their `StartDate`/`EndDate`
|
|
window are skipped. The dispatcher ticks every
|
|
`floci.services.scheduler.tick-interval-seconds` (default `10`).
|
|
|
|
Supported target types: SQS, Lambda, SNS, ECS `RunTask`, EventBridge
|
|
`PutEvents`, and unqualified Step Functions state machine ARNs. Templated
|
|
targets receive the schedule target's `Input`. When `Input` is absent, Floci
|
|
delivers the default notification AWS sends: an EventBridge-style event with
|
|
`detail-type` `Scheduled Event`, `source` `aws.scheduler`, the schedule's
|
|
account, region, and ARN (in `resources`), the occurrence time, and `detail`
|
|
set to the string `"{}"`. The event `id` is stable per occurrence, so retries
|
|
and the dead-letter body carry the same event. A Step Functions target starts
|
|
an asynchronous execution with that payload as its input. Scheduler delivery
|
|
succeeds when `StartExecution` is accepted; a later workflow failure does not
|
|
trigger Scheduler retries.
|
|
|
|
`CreateSchedule` and `UpdateSchedule` reject a non-JSON `Input` for Lambda,
|
|
Step Functions, and EventBridge targets with a `ValidationException`, as AWS
|
|
does. A blank `Input`, or one with text after the JSON value such as
|
|
`{} garbage`, is rejected the same way. SQS and SNS targets accept any text,
|
|
and the `Input` of a universal (`aws-sdk`) target is only checked when the
|
|
schedule is invoked.
|
|
|
|
### Retries and dead-letter queues
|
|
|
|
A failed invocation is retried after a deterministic capped exponential delay
|
|
until the target's `RetryPolicy` is exhausted. The delay starts at 60 seconds
|
|
and is capped at 86400 seconds. Missing fields use the AWS defaults:
|
|
`MaximumEventAgeInSeconds=86400` and `MaximumRetryAttempts=185`. Retries run
|
|
when due, without undocumented AWS jitter. Each occurrence retries
|
|
independently, so a failing occurrence does not delay later `rate` or `cron`
|
|
fires. Pending retries are in memory and are dropped when the process restarts,
|
|
or when a schedule is disabled, updated, or deleted. Targets Floci cannot
|
|
deliver to count as failed invocations. Lambda targets are invoked
|
|
asynchronously, so function errors are not retried by the scheduler.
|
|
|
|
When an occurrence is exhausted and `DeadLetterConfig.Arn` names a standard SQS
|
|
queue, Floci sends the fully materialized target request as a JSON body to that
|
|
queue with the message attributes
|
|
`ERROR_CODE`, `ERROR_MESSAGE`, `EXECUTION_ID`, `EXHAUSTED_RETRY_CONDITION`,
|
|
`IS_PAYLOAD_TRUNCATED`, `RETRY_ATTEMPTS`, `SCHEDULED_TIME`, `SCHEDULE_ARN`, and
|
|
`TARGET_ARN`. FIFO queues and non-SQS ARNs are logged and skipped. An `at`
|
|
schedule with `ActionAfterCompletion=DELETE` is deleted once its occurrence is
|
|
delivered or exhausted. The body uses the request fields of the target
|
|
service's API: SQS `MessageBody` and `QueueUrl` (plus `MessageGroupId` for FIFO
|
|
queues), Lambda `FunctionName`, `InvocationType`, and `Payload`, SNS `TopicArn`
|
|
and `Message`, Step Functions `stateMachineArn` and `input`, EventBridge
|
|
`Entries`, and ECS `cluster`, `taskDefinition`, and `count` with the configured
|
|
launch type, group, and network configuration. Non-JSON input of a universal
|
|
target is encoded as a JSON string field.
|
|
|
|
## Configuration
|
|
|
|
| Variable | Default | Description |
|
|
|---|---|---|
|
|
| `FLOCI_SERVICES_SCHEDULER_ENABLED` | `true` | Enable or disable the service |
|
|
| `FLOCI_SERVICES_SCHEDULER_INVOCATION_ENABLED` | `true` | Run the background dispatcher that fires scheduled targets (`false` = CRUD-only) |
|
|
| `FLOCI_SERVICES_SCHEDULER_TICK_INTERVAL_SECONDS` | `10` | How often the dispatcher scans for due schedules (seconds) |
|
|
|
|
## Not Yet Supported
|
|
|
|
- `FlexibleTimeWindow` jitter (fires deterministically at the scheduled time)
|
|
- `NextToken`-based pagination for List operations
|
|
|
|
## Examples
|
|
|
|
```bash
|
|
export AWS_ENDPOINT_URL=http://localhost:4566
|
|
|
|
# Create a schedule group
|
|
aws scheduler create-schedule-group \
|
|
--name my-group \
|
|
--endpoint-url $AWS_ENDPOINT_URL
|
|
|
|
# List schedule groups
|
|
aws scheduler list-schedule-groups \
|
|
--endpoint-url $AWS_ENDPOINT_URL
|
|
|
|
# Create a schedule in the default group
|
|
aws scheduler create-schedule \
|
|
--name my-schedule \
|
|
--schedule-expression "rate(1 hour)" \
|
|
--flexible-time-window '{"Mode":"OFF"}' \
|
|
--target '{
|
|
"Arn": "arn:aws:lambda:us-east-1:000000000000:function:my-func",
|
|
"RoleArn": "arn:aws:iam::000000000000:role/scheduler-role"
|
|
}' \
|
|
--endpoint-url $AWS_ENDPOINT_URL
|
|
|
|
# Create a schedule with retry policy and dead-letter queue
|
|
aws scheduler create-schedule \
|
|
--name my-resilient-schedule \
|
|
--schedule-expression "rate(5 minutes)" \
|
|
--flexible-time-window '{"Mode":"FLEXIBLE","MaximumWindowInMinutes":10}' \
|
|
--target '{
|
|
"Arn": "arn:aws:sqs:us-east-1:000000000000:my-queue",
|
|
"RoleArn": "arn:aws:iam::000000000000:role/scheduler-role",
|
|
"RetryPolicy": {"MaximumEventAgeInSeconds":3600,"MaximumRetryAttempts":5},
|
|
"DeadLetterConfig": {"Arn":"arn:aws:sqs:us-east-1:000000000000:my-dlq"}
|
|
}' \
|
|
--endpoint-url $AWS_ENDPOINT_URL
|
|
|
|
# Get a schedule
|
|
aws scheduler get-schedule \
|
|
--name my-schedule \
|
|
--endpoint-url $AWS_ENDPOINT_URL
|
|
|
|
# Update a schedule
|
|
aws scheduler update-schedule \
|
|
--name my-schedule \
|
|
--schedule-expression "rate(30 minutes)" \
|
|
--flexible-time-window '{"Mode":"OFF"}' \
|
|
--target '{
|
|
"Arn": "arn:aws:lambda:us-east-1:000000000000:function:my-func",
|
|
"RoleArn": "arn:aws:iam::000000000000:role/scheduler-role"
|
|
}' \
|
|
--state DISABLED \
|
|
--endpoint-url $AWS_ENDPOINT_URL
|
|
|
|
# Delete a schedule
|
|
aws scheduler delete-schedule \
|
|
--name my-schedule \
|
|
--endpoint-url $AWS_ENDPOINT_URL
|
|
|
|
# Delete a schedule group (cascades to all schedules in the group)
|
|
aws scheduler delete-schedule-group \
|
|
--name my-group \
|
|
--endpoint-url $AWS_ENDPOINT_URL
|
|
|
|
# Add tags to a schedule group (tags apply to schedule groups only)
|
|
aws scheduler tag-resource \
|
|
--resource-arn arn:aws:scheduler:us-east-1:000000000000:schedule-group/my-group \
|
|
--tags Key=env,Value=prod Key=owner,Value=Alice \
|
|
--endpoint-url $AWS_ENDPOINT_URL
|
|
|
|
# List tags on a schedule group
|
|
aws scheduler list-tags-for-resource \
|
|
--resource-arn arn:aws:scheduler:us-east-1:000000000000:schedule-group/my-group \
|
|
--endpoint-url $AWS_ENDPOINT_URL
|
|
|
|
# Remove tags from a schedule group
|
|
aws scheduler untag-resource \
|
|
--resource-arn arn:aws:scheduler:us-east-1:000000000000:schedule-group/my-group \
|
|
--tag-keys env owner \
|
|
--endpoint-url $AWS_ENDPOINT_URL
|
|
```
|
|
|
|
## Default Schedule Group
|
|
|
|
A `default` schedule group is automatically created on first access. Schedules created without specifying a group are placed in the default group. The default group cannot be deleted.
|