Schedule a containerized cron job using Amazon ECS and AWS Copilot
Setup a background batch job on a cron schedule. It will be run in AWS Fargate by Amazon ECS. Pattern is setup using AWS Copilot.
About
cron is a command line tool and scheduling system built into Unix-like operating systems, to help you schedule commands to run periodically. You can schedule commands to run on on an interval, or at fixed dates and times.
Amazon EventBridge is a serverless event router and scheduler that can make AWS API calls on a cron schedule.
This pattern will demonstrate how to use Amazon EventBridge to schedule an Amazon ECS RunTask API call to launch a container in AWS Fargate. The configuration will be setup using AWS Copilot, the official command line tool for Amazon ECS.
This example is ideal for implementing:
- An ETL (Extract, Transform, Load) job for syncing production data to an database used for running reporting queries
- Generating business reports on a regular basis
- Running cleanup jobs or other similar workloads on a regular interval
Dependencies
In order to use this pattern you will need the following dependencies:
- Docker or other OCI compatible container builder.
- AWS Copilot CLI - Follow the install instructions for your system.
Architecture
The following diagram shows the architecture that will be deployed:
- An Amazon EventBridge rule is created which has the cron schedule or interval at which you want to run your container.
- The rule invokes an AWS Step Functions workflow that calls Amazon ECS
RunTaskAPI and handles retries and timeouts - Amazon ECS
RunTasklaunches the container of your choice on AWS Fargate capacity.
This architecture is designed to be serverless and not have a single point of failure. Unlike a traditional cron job that is tied to a specific instance in a specific availability zone, all components of this architecture are multi AZ. EventBridge and Step Functions utilize multiple AZ’s for high availability, and AWS Fargate is configured to span multiple AZ’s in a VPC so that it can launch your container with high availability.
Instructions
First we need to create a Dockerfile to define the cron job to run. To simulate a batch job you can use the following basic Dockerfile which does nothing but sleep for one hour:
FROM public.ecr.aws/docker/library/busybox:stable
CMD sh -c "echo 'Sleeping one hour' && sleep 3600"
To begin deploying the cron job using Copilot run the following command:
copilot init
Copilot will ask what you’d like to name your application. Type cron-app.
What would you like to name your application? [? for help] cron-app
Next Copilot will ask what type of workload you are deploying. Choose Scheduled Job:
Which workload type best represents your architecture? [Use arrows to move, type to filter, ? for more help]
Request-Driven Web Service (App Runner)
Load Balanced Web Service (Internet to ECS on Fargate)
Backend Service (ECS on Fargate)
Worker Service (Events to SQS to ECS on Fargate)
> Scheduled Job (Scheduled event to State Machine to Fargate)
As the name of the job type cron-job.
What do you want to name this job? [? for help] cron-job
AWS Copilot will ask what Dockerfile to run. Use the example Dockerfile from above, or supply your own custom Dockerfile.
Which Dockerfile would you like to use for cron-job? [Use arrows to move, type to filter, ? for more help]
> ./Dockerfile
Enter custom path for your Dockerfile
Use an existing image instead
To demonstrate job scheduling choose Rate.
How would you like to schedule this job? [Use arrows to move, type to filter, ? for more help]
> Rate
Fixed Schedule
Copilot will ask what rate you’d like to run the job at. You can type 1h for 1 hour interval between running jobs.
How long would you like to wait between executions? [? for help] (1h30m) 1h
Last but not least type y when Copilot asks if you are ready to deploy a test environment.
Would you like to deploy a test environment? [? for help] (y/N)
Manifest
Take a look at the generated manifest file copilot/cron-job/manifest.yml:
Some extra configuration that you can customize:
retries- If the job fails to start up as expected, how many times would you like to retry.timeout- A maximum lifespan for the task if it is taking too long. You can use this to prevent multiple copies of the job from running parallel with each other if the duration of one job extends past the interval that would trigger the next job.cpuandmemory- How much resources your cron job requires.
Extra commands
If you would like to invoke a job instantly you can do so with:
copilot job run
View the logs for your job with:
copilot job logs
Cleanup
Run the following command to tear down the pattern:
copilot job delete