While it was really cool when AWS Lambda scheduled functions were announced, it was a bit of a let-down to find out they could only be done via the web console. The benefit of having scheduled custom jobs without having to run and maintain a cron server was undone by having to do it via the AWS console.

Thankfully that's changed this week with the announcement of CloudWatch Events. It turns out that Lambda's scheduled tasks we done by CloudWatch under the hood. With this update, we can now schedule Lambda functions from the CLI and APIs!

At the moment CloudWatch alerts are only available in the following regions: US East (Northern Virginia), US West (Oregon), Europe (Ireland), and Asia Pacific (Tokyo).

These steps assume you've installed and configured the AWS CLI, and are using one of the above supported AWS regions.

Moving Pieces

This diagram shows the relationship between CloudWatch alerts and Lambda functions:

CloudWatch scheduling Lambda

Breaking it down it becomes 4 steps:

  1. Setup your CloudWatch event
  2. Setup your Lambda function
  3. Give the alert permissions to Lambda
  4. Make the rule target the function

Create a CloudWatch Event Rule

To start with create a new CloudWatch Event.
In this example I'm going to have an event that is triggered daily, without caring at what time it runs:

aws events put-rule --name 'DailyRule' --schedule-expression 'rate(1 day)'  

Take note of the ARN you get back from the command, as you'll need it in the following steps.

You can now see the rule under the new Events section in the CloudWatch console:

DailyRule in CloudWatch Events

You can see the full schedule expression documentation if you want a different schedule to mine, or want to use the cron syntax for more fine-grained control.

Note: that 5 minutes is the smallest schedule interval that is supported, and that all times specified (when using the cron syntax) are in UTC.

Create a Lambda Function

I'm going to assume you already have a Lambda function you wanted to run. If not you can quickly use one of the ready-made blueprints to get going quickly.

Give Permissions

Once you've got your Lambda function details, you'll need to grant permission to the Rule to allow it to trigger the function. Using the Event ARN you got earlier (for the --source-arn parameter) and your function name from the previous step run the following command:

aws lambda add-permission --function-name MyFunctionName --statement-id SomethingUnique --action 'lambda:InvokeFunction' --principal events.amazonaws.com --source-arn arn:aws:events:us-east-1:MYACCOUNTNUM:rule/DailyRule  

The --statement-id parameter just needs to be unique (it's used for internal IAM labelling).

After this is done, you should see the permission in the "Event sources" tab for the function:

MyFunctionName Event Sources

Create Event Source / Target

Now that the permissions are in place you need to link the rule and the function (i.e. "target" the function with the rule).

aws events put-targets --rule DailyRule --targets '{"Id" : "1", "Arn": "arn:aws:lambda:us-east-1:MYACCOUNTNUM:function:MyFunctionName"}'  

All you'll get back from this command is a FailedEntryCount value - If it's 0 then you're all good.

Once this is done, you can see the Target on the CloudWatch Console > Rules > DailyRule page.

DailyRule Target

Monitoring

You can see when/how often your rules have been triggered via the new TriggeredRules metric in CloudWatch.

Automate ALL THE THINGS!

Now the scheduled functions are able to be set up programatically I can see them being used a lot more - it will really open up Lambda to being a fully automatable solution to running you're own schedule task server or messing around with Simple Workflow Service.

Get in touch if you've got any questions about Lambda!