Part 1 - AWS Lambda and how to schedule its execution
Part 1 - AWS Lambda and how to schedule its execution
In the first part, we will concentrate on creating AWS Lambda and scheduling its daily execution by using AWS CloudWatch template.
Let’s start by having a quick glance at the complete CloudFormation part 1 template and then we’ll break it down piece by piece in order to explain how it works.
If you look closely, you will notice there are three main parts - lambda definition, event rule and lambda invoking permission. We will cover each one of them by taking corresponding template excerpt and telling you about its properties. Naturally, we would like to start by telling you what AWS Lambda is.
AWS Lambda super simple introduction
In essence, AWS Lambda is a service which lets you run your code without thinking too much about where it is hosted or how it is actually run. Since you obviously don’t care about anything other than the business function you want to execute, it is also being referred to as Serverless Computing. You could use your Lambda code to process incoming Http request (when configured with AWS API Gateway) or to be a background running job. We’ll stick to the latter scenario so we can schedule our background job execution on a daily basis.
Our first business function packed as Lambda - the Notifier
So, what is our first business function? Well, it is a simple notifier which will use SNS service in order to notify second AWS Lambda for execution. In this blog post we will cover lambda creation and code input; in the following blog post, we will expand this lambda to utilize SNS to send notifications.
The question that arises is - how do we place any code which will be run within this magical AWS Lambda container? Well, it depends! If a Notifier is a simple code it might as well be written directly from within AWS Console - so you would have something like this input into your AWS Lambda:
When we input this code into AWS Lambda and execute it (make sure you replace default code and hit Save button), we get the following output:
Here we can see that there’s a function receiving three parameters and it serves as the entry point for our lambda execution. Other than that, there is not much in here- just a simple response message. If this is your first experience with AWS Lambda you should go and create one yourself and try to input similar code yourself just so that you get some feeling for it.
What you do inside of your function is your thing, however, bear in mind there are certain limitations to the serverless approach - to be more precise, a time limitation of 5 minutes execution within AWS. Therefore, if you plan to have a long-running job you might be better off with something like a Docker container running within EC2 instance. That is, however, a topic for another blog post.
Notifier AWS Lambda excerpt
Now that we have some understanding of AWS Lambda, it is time to describe Notifier Lambda portion of the template. Creating AWS Lambda through CloudFormation is unbelievably simple! In essence, you need to specify lambda name, handler, code URI and a runtime definition to let it know what programming language and framework you are using. These are not the only properties that exist though - you can delve deeper into the documentation to see what other parameters you can configure.
Here is the excerpt representing our Notifier Lambda:
Often, we need to provide our lambda with some context. We use environment variables to do so. When you set environment variable it is accessible inside AWS Lambda code. Here we set just one variable SOME_VARIABLE with a dummy value of ‘some_value’ just to show off how it is done. In real life, you would pass much more relevant input than this - e.g. API endpoint URI a lambda needs to consume.
Our Notifier implementation (packaged in the notifier-partial.zip file) evolved slightly just to give you the sense of how packaging works.
Package contains an entry point index.js as well as package.json files in the root level. If you are familiar with NodeJS this will be very obvious. Index.js references messageCreator.js and snsPublisher.js files which, at this point, serve merely as placeholders for actual SNS notification sending mechanism. Remember, SNS will be the focus of our next blog post and the reason why we suffix the zip package with “partial” is the fact that we still don’t have any SNS specific code in there.
Scheduling AWS Lambda execution
We created our first lambda, so we can start thinking of scheduling its execution.
Unless you want to trigger AWS Lambda execution every time you need it to do the work yourself, which is really not recommended, you can configure it so it is done automatically for you. In our case, the requirement was to trigger execution once per day as the input data we needed to process was not refreshed more often anyway. This is not to mention there are no other ways to trigger AWS Lambda execution since in fact there are; we will be covering triggering using SNS and S3 events within this blog series as well.
Now that we have this off the table, the question remains - how do we schedule AWS Lambda execution in a predetermined time of day? And to provide you with an answer - enter AWS CloudWatch.
I can schedule your AWS Lambda execution - my name is CloudWatch
CloudWatch is actually much more than a simple scheduler. Still, we’ll focus on scheduling functionality only - otherwise, we might end up writing a really long blog post.
The piece of CloudWatch we are interested in is called CloudWatch Events. To be more specific, we are interested in a portion of CloudWatch Events which is concerned with defining rules. To schedule Lambda execution every day at 7 AM GMT we will want to take a look at the NotifierLambdaScheduledRule part of the template:
Notice how we use a cron expression to specify the execution schedule. If you would like to learn more about cron expressions, you can use the following link. Feel free to change this expression to whatever suits you best.
After we have defined common properties like name and description, we need to specify the target of the scheduling rule - our Notifier lambda. A target is identified by the “Arn” or Amazon Resource Name which is used to uniquely identify AWS resource. You’ll see Arn referenced very often so make sure you get familiar with it.
May I invoke the Notifier, please?
Lastly, we need to give a permission to our LambdaScheduledRule to invoke the Notifier lambda:
What matters here the most is that the source is Arn of our NotifierLambdaScheduledRule, and the function to be invoked is NotifierLambda.
We had it broken down, piece by piece. The last remaining aspect of the template (besides the self-explanatory description section) is the Transform section.
Transform enables specifying macros that AWS CloudFormation uses to process the template. It is actually part of a SAM (Serverless Application Model) idea to dramatically simplify resource creation. In concrete, with “AWS::Serverless-2016-10-31” macro we are able to use “AWS::Serverless:Function” which enables us to create lambda with minimum complexity. It will, in turn, create a fully configured “AWS::Lambda::Function” and all required permissions.
Creating CloudFormation stack from the template
Are you pumped with adrenaline yet? I know I am! And you know why? For we are about to create our stack of resources using CloudFormation.
If you haven’t already done so, please download Schedule.yml file here. You are free to do any modifications, but please make sure you don’t break it :).
Now that you have a template file at your disposal, head over to the AWS Console and navigate to CloudFormation service. You can do it either by clicking the link in the Management Tools section or by typing the service name in the finder text area.
Once you are on the CloudFormation service UI, you will notice a big blue Create Stack button. Click it and you will be presented with the options to either design a new template or choose existing template. Here we want to select our YAML template file. Next, we specify a friendly and meaningful name for our new stack (I’ll name it simply schedule-stack) and proceed to the Review screen where we acknowledge that our transforms might create IAM resources. Indeed it will create one additional IAM role. Lastly, we create a changeset and click on the Execute button.
Shortly, we should see on the CloudFormation screen that our stack has been created.
How about that - we have our infrastructure for scheduling lambda execution once per day in place! Let’s go and try to find our Notifier lambda in the AWS Lambda service section. Well, it is there and it is fully configured:
Similarly, AWS CloudWatch event rules section now contains our new scheduled execution rule:
Going back to AWS Lambda section and reviewing monitoring of Notifier lambda or checking CloudWatch logs section will tell you when the lambda was executed and what the result output was. So make sure you do some snooping around to investigate the effects of a newly created stack.
Once you are done playing with your stack, you can go and delete it from the CloudFormation screen to keep your AWS account free of resources you don’t require any longer. You can do it by clicking on the Actions button and choosing an option for stack deletion.
And, that is pretty much it for this blog post. Hope you enjoyed reading it and playing with AWS!
In the second part of this blog post series, we will upgrade our Notifier lambda with actual SNS service connection in order to parallelize our HardWorker lambda execution. Sounds interesting? If so, stay tuned, the second part is coming soon!