Serverless Ruby Cron Jobs Tutorial: Route53 Backup
A great use case for AWS Lambda is running Cron Jobs. Instead of setting up a special one-off Cron server to run a simple task, we can just run the task on serverless nowadays. In this blog post, we’ll go over how to build a simple Cron Job with Jets, the Ruby Serverless Framework. As a useful practical example, we’ll create a job that backs up route53 records. This is quite handy when if you ever need it!
Jets New Job Mode
The jets new command has a few different modes: html, api, and job. We’ll use the handy job mode for this tutorial to create a minimal starter project designed to run jobs.
jets new backer --mode job
cd backer
We’ve successfully generated a very minimal Jets project. It is interesting to note that in job mode, there’s is no database configured and prewarming is disabled. Feel that these are good default settings for job mode. We are ready to now add some job code.
Initial Test Job Code
Let’s create a simple stub Job class.
app/jobs/backup_job.rb:
class BackupJob < ApplicationJob
rate "1 minute" # fast rate for initial testing
def route53_records
puts "Backing up route53 records"
end
end
To do a quick test let’s use jets console
:
$ jets console
>> BackupJob.perform_now(:route53_records)
Backing up route53 records
=> nil
The local sanity check looks good. Let’s deploy it now.
$ jets deploy
Deploying to Lambda backer-dev environment...
...
Stack success status: UPDATE_COMPLETE
Time took for stack deployment: 1m 41s.
Prewarming application.
You can check out the deployed function in the Lambda console:
Since we’ve used a rate of 1 minute
we can also see it running pretty quickly in the CloudWatch logs. It looks something like this:
Backup Route53 Code
Okay, now we can add the actual code that backs up the route53 records to s3.
We need to add the aws-sdk-route53
to the project’s Gemfile
. The aws-sdk-s3
dependency is already included as part of Jets, so we don’t need to add that.
Gemfile:
gem "aws-sdk-route53"
For explanatory purposes, I’m going to focus on the code snippets that help to understand how the backup script works. The full source code is also on GitHub: jobs/backup_job.rb
class BackupJob < ApplicationJob
iam_policy "s3"
managed_iam_policy "AmazonRoute53ReadOnlyAccess"
rate "1 day" # changed it so it runs once a day now
def route53_records
puts "Backing up route53 records"
hosted_zones = route53.list_hosted_zones.hosted_zones
hosted_zones.each do |zone|
# ...
save_to_s3("backups/route53/#{domain}-#{page}.json", resp)
end
end
# ...
private
def bucket_name
ENV['S3_BUCKET']
end
end
The code essentially loops through all the hosted zones and takes a backup of all the route53 records for each hosted zone, saving them in JSON format.
We also added an iam_policy declaration. For the sake of this tutorial, we’re using a simple s3 policy to give us write access to s3. There is also a managed_iam_policy declaration to get route53 read-only access. Note that these iam policies apply for the deployed function on AWS Lambda. Locally, you’re using the IAM permissions of your IAM user.
There is also an environment variable S3_BUCKET
to tell the script where to save the backup records. Let’s create a s3 bucket and also add S3_BUCKET
to our .env file.
aws s3 mb s3://jets-demo-backups # use your own unique bucket name
echo "S3_BUCKET=jets-demo-backups" > .env
The backups are saved to an easily identifiable structure:
s3://jets-demo-backups/backups/route53/example.com-1.json
s3://jets-demo-backups/backups/route53/example.com-2.json
The number at the end is a page number in case the number of routes in a zone exceeds a single page of results. The full source code is available here again: tongueroo/jets-backup-route53
It is useful to first to test things locally.
$ bundle
$ jets console
>> BackupJob.perform_now(:route53_records)
Backing up route53 records
Saving to s3://jets-demo-backups/backups/route53/demo.boltops.com-1.json
Saving to s3://jets-demo-backups/backups/route53/demo.rubyonjets.com-1.json
=> {:success=>true}
>>
Once the function completes successfully, let’s check our s3 bucket:
$ aws s3 ls s3://jets-demo-backups/backups/route53/
2019-01-04 06:49:31 968 demo.boltops.com-1.json
2019-01-04 06:49:31 2135 demo.rubyonjets.com-1.json
$
We’re ready to deploy it again:
$ jets deploy
After it deploys, let’s manually trigger the function in the Lambda console this time. You can use anything for the test event payload because the backup function doesn’t care. Click on the Test button to run the function.
We should see something like this after running the function:
That’s it! We have successfully created a Ruby Serverless Cron Job with Jets! To boot, it backs up route53 records, which is pretty darn useful in case we ever need it. Usually, I enable versioning and a lifecycle policy on the s3 bucket also. This allows us to go back in history and get records from the past. This also makes the script simpler.
Hope you’ve enjoyed this article. If you find Ruby on Jets interesting, please give it ⭐️ on GitHub. I’d appreciate it. 👍
More info
- For an Jets Introduction: Introducing Jets: A Ruby Serverless Framework.
- Also more info at: Jets documentation site.
Jets Links and Tutorial Series
- Introducing Jets: A Ruby Serverless Framework
- Toronto Serverless Presentation: Jets Framework
- Jets Afterburner: Serverless Rails in 5 Minutes
- Mega Mode: Rails on AWS Lambda
- An Introductory CRUD App Part 1
- Deploy to AWS Lambda Part 2
- Debugging Logs Part 3
- Background Jobs Part 4
- IAM Policies Part 5
- Function Properties Part 6
- Extra Environments Part 7
- Different Environments Part 8
- Polymorphic Support Part 9
- Jets Delete Tutorial
- Jets Image Uploads Tutorial with CarrierWave
- Cron Job Tutorial: Backup Route53
- Build an API with the Jets Ruby Serverless Framework
Thanks for reading this far. If you found this article useful, I'd really appreciate it if you share this article so others can find it too! Thanks 😁 Also follow me on Twitter.
Got questions? Check out BoltOps.
You might also like
More tools:
-
Kubes
Kubes: Kubernetes Deployment Tool
Kubes is a Kubernetes Deployment Tool. It builds the docker image, creates the Kubernetes YAML, and runs kubectl apply. It automates the deployment process and saves you precious finger-typing energy.
-
Jets
Jets: The Ruby Serverless Framework
Ruby on Jets allows you to create and deploy serverless services with ease, and to seamlessly glue AWS services together with the most beautiful dynamic language: Ruby. It includes everything you need to build an API and deploy it to AWS Lambda. Jets leverages the power of Ruby to make serverless joyful for everyone.
-
Lono
Lono: The CloudFormation Framework
Building infrastructure-as-code is challenging. Lono makes it much easier and fun. It includes everything you need to manage and deploy infrastructure-as-code.