Skip to content

Scheduled Tasks

Jeff Bachtel edited this page Sep 15, 2018 · 4 revisions

Scheduled Tasks

Each service can have multiple scheduled tasks defined in mu.yml. Some of the concepts are similar to Unix's cron facility, but the timing is governed by AWS CloudWatch Events.

Configuration

---
service:
  name: my-service
  provider: ecs
  schedules:
  - name: minutely
    expression: cron(* * * * ? *)
    command: ['curl','http://webhook.example.com/minute-cron']
  - name: hourly
    expression: cron(0 * * * ? *)
    command: ['curl','http://webhook.example.com/hour-cron']

Usage of Scheduled Tasks

There are no additional mu commands associated with scheduled tasks. Each scheduled task becomes a new CloudFormation stack incorporating the name you give it. Each scheduled task is created during mu's service deployment. This includes when the mu pipeline reaches the deploy stage, and also when you run mu svc deploy <environment> manually.

ECS Mode required

mu supports both ec2 (default) and ecs (non-default) service deployments. However, the scheduled-tasks feature described in this page is not yet implemented for EC2 instances. Therefore, if you require scheduled tasks functionality, you MUST add provider: ecs to your service definition, as in the example above.

Dockerfile caveat

When these scheduled tasks fire, they launch new, short-lived Docker containers within ECS, using the same Docker image as your long-running services. However, the command array is passed as a containerOverride, which means your scheduled command gets run in these short-lived containers instead of what is specified in the CMD line in the container's Dockerfile.

Because of the way the Dockerfile's ENTRYPOINT command works, you cannot use it in a service that will have scheduled tasks executed against it. If you try this, your command will not run, because ECS will be append your command to whatever value is in ENTRYPOINT, and this is almost certainly not what you want. (ENTRYPOINT vs. CMD)

Also, because the scheduled tasks run inside their own short-lived container, any changes it makes to the files in a docker image will be lost upon termination. For example: running rake update with the intent to update a live Ruby application will work (technically), but will not be useful, since the entire container will be destroyed immediately. These tasks are NOT run against your long-running containers.

Disabling Scheduled Tasks

Scheduled Tasks are enabled by default. However, you can disable and re-enable them through the AWS Console, and the awscli tool.

Two Types of Schedules

Cron Expressions

Users already familiar with cron may notice there is a sixth field within the cron() function, whereas traditional cron only has five schedule fields. The sixth field is merely the year. Amazon has a number of other extensions to this schedule specification that you may which to explore.

Rate Expressions

Instead of using cron(m h d m d) expressions, you may also want to try "Fixed Rate" scheduling. Fixed Rate patterns are fully described here, but the TL;DR version is this:

...
  schedules:
  - name: daily
    expression: `rate(24 hours)`
    command: ['curl','http://webhook.example.com/daily-cron']

The rate(interval) form of scheduling has not undergone separate testing under mu, but it should work, because the value of expression is simply passed to the CloudFormation template as-is.

Timing of CloudWatch Events

Also, be aware that CloudWatch events do not fire as precisely as a local cron daemon does, due to AWS's distributed nature..