Automating AWS with EventBridge Scheduler
Learn how to replace traditional cron jobs with the more powerful and serverless AWS EventBridge Scheduler to trigger Lambda functions, ECS tasks, and more on a recurring schedule.
For decades, cron
has been the go-to tool for running scheduled tasks. In the cloud, however, a simple cron job on an EC2 instance is often not the most resilient or cost-effective solution. If the instance goes down, your job doesn't run. AWS's answer to this is the Amazon EventBridge Scheduler.
EventBridge Scheduler is a serverless scheduler that allows you to create, run, and manage scheduled tasks at scale. It's more reliable, scalable, and powerful than a traditional cron daemon.
Why Use EventBridge Scheduler over Cron?
- Serverless: No EC2 instance to manage, patch, or pay for when it's idle.
- Reliable: It's a fully managed AWS service with high availability built-in.
- Versatile Targets: It can trigger a huge range of AWS services, including Lambda functions, ECS tasks, Step Functions workflows, and even API endpoints.
- Timezone Aware: Schedules can be configured to run in specific timezones, automatically handling daylight saving changes.
- Flexible Schedules: Supports cron expressions, fixed-rate schedules (e.g., every 5 minutes), and one-time schedules.
Creating a Schedule with the AWS CDK
Let's create a schedule that triggers a Lambda function every day at 10:00 AM UTC. We'll use the AWS CDK in TypeScript.
First, you need a target for the schedule to invoke. Let's use a simple Lambda function:
// lib/my-stack.ts
import * as lambda from 'aws-cdk-lib/aws-lambda';
import * as scheduler from 'aws-cdk-lib/aws-scheduler-alpha';
import { Stack, StackProps } from 'aws-cdk-lib';
import { Construct } from 'constructs';
export class MyScheduledStack extends Stack {
constructor(scope: Construct, id: string, props?: StackProps) {
super(scope, id, props);
// The Lambda function to be triggered
const myFunction = new lambda.Function(this, 'MyDailyFunction', {
runtime: lambda.Runtime.NODEJS_20_X,
handler: 'index.handler',
code: lambda.Code.fromInline('exports.handler = async () => console.log("Hello from the scheduler!");'),
});
Now, let's create the schedule. The EventBridge Scheduler construct is currently in alpha in the CDK, so you'll need to install it separately (npm install @aws-cdk/aws-scheduler-alpha
).
// ... continuing in MyScheduledStack
// The target for the schedule
const target = new targets.LambdaInvoke(myFunction, {
// You can optionally pass a static payload to the function
input: scheduler.ScheduleTargetInput.fromObject({
message: 'Time for the daily report!',
}),
});
// Create the schedule
new scheduler.Schedule(this, 'MyDailySchedule', {
schedule: scheduler.ScheduleExpression.cron({
minute: '0',
hour: '10',
day: '*',
month: '*',
year: '*',
}),
target: target,
description: 'Triggers the daily report Lambda function.',
});
}
}
Key Concepts
- Schedule Expression: This defines when the task runs. You can use
ScheduleExpression.cron(...)
for standard cron syntax orScheduleExpression.rate(...)
for fixed intervals (e.g.,cdk.Duration.minutes(5)
). - Target: This defines what the schedule invokes. The CDK provides target classes for most common AWS services (
LambdaInvoke
,EcsTask
,SfnStateMachine
, etc.). - Input: You can pass a static JSON payload to your target. This is useful for creating a single generic Lambda function that behaves differently based on the input it receives from different schedules.
Advanced Feature: Universal Target
One of the most powerful features is the "universal target," which allows you to call the API of almost any AWS service. For example, you could create a schedule to automatically start or stop an EC2 instance at a certain time.
// Schedule to stop an EC2 instance every day at 7 PM
const ec2StopTarget = {
arn: 'arn:aws:scheduler:::aws-sdk:ec2:stopInstances',
input: scheduler.ScheduleTargetInput.fromObject({
InstanceIds: ['i-1234567890abcdef0'],
}),
role: mySchedulerRole, // A role with ec2:StopInstances permission
};
new scheduler.Schedule(this, 'StopEc2Schedule', {
schedule: scheduler.ScheduleExpression.cron({ minute: '0', hour: '19' }),
target: ec2StopTarget,
});
Monitoring and Error Handling
EventBridge Scheduler also provides robust error handling mechanisms.
- Retry Policies: You can configure a retry policy to automatically re-run a failed invocation with exponential backoff.
- Dead-Letter Queue (DLQ): If a target fails to be invoked after all retries, the event can be sent to an SQS queue (a DLQ) for later analysis. This ensures that you never lose a scheduled invocation.
Conclusion
EventBridge Scheduler is the modern, serverless solution for task scheduling on AWS. It's more reliable, scalable, and feature-rich than a traditional cron job running on a single server. By integrating it into your infrastructure as code with the CDK, you can build powerful, automated, and resilient workflows for everything from daily reports to starting and stopping resources.