Python

Using AWS Lambda to monitor websites

I run a couple of websites for personal use, Nextcloud (an open source Dropbox alternative) and this WordPress site for personal use using a single EC2 instance.  As this architecture is susceptible to a host of problems due to a lack of redundancy, I needed a way to keep an eye on site availability and get notified if the websites were unavailable for any reason.

I had a couple of basic requirements:

  • The monitoring needed to be run outside the server to rule out any issues with the EC2 instance
  • The monitoring needed to check the websites from multiple locations
  • The monitoring needed to be free or as close to free as possible

There were a few ways I could solve this:

  • Use a managed service like pingdom, but the free tier is usually limited to only 1 url
  • install a dedicated monitoring solution
  • write a basic custom solution

I only need to check if the websites are up every 5 minutes, so any solution requiring the use of a virtual server or container that runs all the time would be a waste of resources, not to mention expensive.  As a result, I chose to use a serverless function that is triggered every 5 minutes using AWS Lambda which gives me solution that is “almost free”, i.e. a few cents a month.

The basic architecture for this serverless monitoring is as follows:

  • Check the website using an AWS Lambda function
  • If a HTTP 200 or HTTP 304 is returned, the site is up and a metric value of 200 is sent to AWS CloudWatch
  • If anything else is returned the site is unavailable and a metric value of < 200 is sent to AWS CloudWatch so an alert can be raised.

 

Here’s a checklist of things that need to be in place for this to work:

  • The python script that will check website availability
  • AWS Simple Notification Service Topic
  • IAM Role (lambda_basic_execution) with the following permissions for the Lambda Function:
{
    "Version": "2012-10-17",
    "Statement": [
    {
        "Sid": "AllowLogCreation",
        "Effect": "Allow",
        "Action": [
            "logs:CreateLogStream",
            "logs:PutLogEvents",
            "logs:CreateLogGroup"
            ],
        "Resource": "arn:aws:logs:*:*:*"
    },
    {
    "Sid": "AllowMetricAlarmCreation",
    "Effect": "Allow",
    "Action": [
            "cloudwatch:PutMetricAlarm",
            "cloudwatch:PutMetricData"
            ],
        "Resource": "*"
        },
    ]
}

Read More