Learn how to create AWS Lambda functions that execute on a scheduled interval, much like a cron job would. In this lesson we will create a Lambda function that checks for a string of text on a website to verify the website is up and operational. The lambda function logs to CloudWatch Metrics and sends a notification email using an SNS queue if the check fails.
I'm going to create a Lambda function that checks the status of this website every five minutes by looking at the text that's returned. I'll start in the Lambda console and click create a Lambda function. We can skip the blueprint, give it a name and description, and we can just enter our code inline.
We'll start exporting a function named handler that has two parameters, event and context. Inside of that, we'll require the HTTP object. Then, I'm going to create an options object that contains our HTTP client options.
Next, I'll create a callback, and this will be the callback that gets called to make the client request. I need a String object that's going to collect all of the chunk responses from the request. Response.on is an event emitter, so when we get data, we're going to call function that adds the chunk we received from the event emitter onto our existing String object.
When we receive the end event from the event emitter, we want to actually test to see if the string we received back from our HTTP request matches what we are expecting.
Let's jump back up here, and we're going to create a variable called "regex." It's going to be the actual string that we're looking for in our response. Basically, we're going to parse a string, and if we find that string of text, we know that the website was alive and it has the correct content on it.
We'll do a regex.text, pass in our string object, and if that's true, we want to write to the CloudWatch logs. We do that using console.log. Then, we'll call the context.succeed method that signals the end of our Lambda function.
Now, if we don't get that string back, we have to assume that something's wrong with our website, so we'll call console.log to write to the CloudWatch logs, and we'll say, "Website failed." Then, we will call the context.fail function to register that our function completed but with a failure status.
Last, we'll make our HTTP request, passing in our options and the callback that we want to fire. Index is a default page name. Handler is the name of the function we exported.
The role, we can choose a Lambda basic execution role, because we have no special permissions here. Memory is fine, timeout's fine, and we're not in VPC, so we'll click next, review it, and create function.
We can test this. We'll use the scheduled event sample template. Save and test. That failed. If we look at our log output over here, it's because our object hosting static websites has no method text. If we look back at our code, I actually want to regex.test that, not regex.text it. Let's save and test that again. This time, it succeeded.
Let's make one more test to it, just so I can show you that it fails. If we look for the text "Hello world," save in test, we get the error message, because we triggered the context.failure. If we go over to monitoring here, for the invocations, we have two invocations and one of those is a failure.
Now we know we can trigger a failure if the website doesn't respond with the correct data, we need to get it to email us. We're going to go into the SNS console. I'm going to create a new topic. I'll call it "Website Down." Then, I'll create a subscription. It's going to be the type of email with my email address.
Now, it says down here, "Pending confirmation." If I open my email, there is a link to click to confirm my subscription. I can click that, and it says, "Subscription confirmed."
Now let's go into CloudWatch, and I want to create a new alarm. Lambda metrics by function name, and I'm going to choose website check, which is the name of my Lambda function. The errors object. I'm going to change this from average to sum. Click next, give it a name, and I want it to fire whenever the errors count is greater than or equal to one.
When it's in the state of alarm, I want to send it to the Website Down SNS list that we created. Click create alarm.
I'm going to return to Lambda, go back into my function, and I'm going to test it again. Now, we're still testing for "Hello world," which is not the right text, so it's going to fail when I test. You can see that it failed, and it fired the context.fail function. If I go into my email, there's the email telling me that my site is down.
There's one last thing to do, and we want this to run every five minutes. In our Lambda function, we'll go to event sources. We'll add an event source. The type is going to be CloudWatch events schedule, and the rule name is fine. The only thing we're really concerned about here is the rate.
It's got a predefined template there that's rate and then the number of minutes or the time value that you want it to schedule. You can't go any sooner than 5 minutes, but you can put 15 minutes, an hour, a day, or you can also use crontab style expressions if you need something that's a little more customizable.
Five minutes is fine for us. Choose enable now and then submit. That's going to start running. It's going to execute now, and then it's going to execute every five minutes until we come back in here and stop it.