Site Down Detector with AWS (Amazon Web Services)
Tags: aws, lambda, cloudwatch, sns
Published: 2019-10-27 18:53:57

I wanted to make a down detector for a website that was cheap, and reliable that is separate from the hosts down detection. I decided to create this in Lambda.
#Lambda Function
In the AWS console go to Lambda, and click **Create Function**. Click **Author from Scratch** and enter whatever function name you want. Choose the node 10 run-time since at the time of writing that is the LTS (Long Term Support) version of node on lambda. You can leave the rest as the default and it will just add the permissions for you.

AWS will create a CloudWatch logs output by default. For the code paste this in and modify the YOUR_SITE constant

```javascript
const https = require('https');
exports.handler = async (event) => {
    // TODO implement
    'use strict';
  const YOUR_SITE = 'https://yoursite.com';
  const data = await new Promise((resolve, reject) => {
        https.get(YOUR_SITE, (res) => {
          res.on('data', (d) => {
            resolve(res.statusCode);
          });
        
        }).on('error', (e) => {
          reject(e);
        });
    });
  return {
        status: data
    }
};
```

Click on save to save the code then click on Test. You will likely have to create a new test event. You can leave the defaults and type in any name in Event Name click **Create**. Click on **Test** button and it will run your test. If successful it will return a `{status: 200}` JSON object back.

# CloudWatch Trigger
For a down detector you will want to run this at least once every 5 minutes. For my site I used every 1 minute because `1*60*24*31 = 44640` invocations a month which is covered under the always free tier of Lambda. To set this up click on **Add Trigger** under lambda page and click on **CloudWatch Events**. Under Rule click on **Create a new Rule** and name it whatever you’d like and click on **Schedule Expression** and set your schedule ex `rate(2 minute)` and click **Add**.

# CloudWatch Alarm
Once you have this function running every 1–5 minutes you’ll want it to alert you when it fails. To do this set up a CloudWatch alarm. Go to Services -> CloudWatch. Then click on **Alarms** on the left side. Click on **Create Alarm**. Click **Select Metric** and click on **Lambda**, **By Function Name** and find your function name and find the one with metric of **Errors**. Set the **Statistic** as **Sum**, and the Period at 5 minutes. Set the Threshold type as **Status** and select “Whenever Errors is..” **Greater** than threshold value **0**. Click on **Next**. Click on **In Alarm** then **Create new Topic** and make a new topic. You can name it anything and put your email to be notified via email when the SNS Topic has a new message. Click **Create Topic** then click **Next**. Name it anything you’d like and click **Next** then click **Create Alarm**.

# SNS Simple Notification Service
To get the email notification you will have to go to your email and confirm your subscription to the topic. It will be named something like “AWS Notification — Subscription Confirmation”.

If you want to be notified via text message go to Services -> SNS. Then click on **Text Messaging (SMS)**. Click **Subscribe number to topic**. Type in your phone number with the leading one (ex. 18887666746). For non-us numbers type in the full number with any leading numbers included. Click “Create Subscription” and it will subscribe your number to outage notifications. If you want to test your SNS topic click on **Topics** and then click on the ID of your topic. Click on **Publish Message** and then type in a subject (needed for email delivery) and then in the mesage body type in whatever you want and click **Publish Message**. You should receive an email and a text with your message.

Congratulations! You have made a down detector.

# Costs (estimate)
I have not yet figured out the exact costs but depending on how many text messages you get I think that’s the main cost.
**SNS** — 1 million free requests always free tier, I don’t think texts are included in this though so texts cost roughly 0.6 cents per text
**CloudWatch** — 10 free custom metrics and alarms always free
**Lambda** — 1 Million free requests per month and 3.2 millions seconds compute
**CloudWatch Logs** — The pricing is confusing for this so that may incur slight costs but it sounds like it’s free for up to 5 Gigs of lows. If you have better info regarding this please comment below.
# Troubleshooting
The only trouble I had was when I first subscribed my email to a topic and sent a test message I did not get the message but I believe it was because I did not set a Subject for the email test message.
I also noticed for my site that the default timeout of the lambda function of 3 seconds timed out once so I bumped that up to 6 seconds. I would suggest keeping that low so the function doesn’t end up running forever and potentially bumping up costs.

## Updates / Issues
After using this in the wild for a while I have noticed that it will occasionally timeout for seemingly no reason. I have yet to find a great way to determine if it's an issue with my site or with lambda but to avoid false positives I set the cloudwatch threshold to greater than 1 error in 5 minutes. If that's the case then the site is probably actually down vs a timeout that happens here and there