How I created a 'physical' alarm to warn me when my servers are down
Tags: showdev, aws, iot, serverless
Published: 2020-10-19 11:24:33

This post contains a weekend project I worked on to create an alarm when my AWS EC2 servers are down.
Tools and technologies used: AWS Lambda, EventBridge, Greengrass, Raspberry Pi, Active Buzzer and LED light (as the alarm), GPIO, etc.

# Architecture:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/r5q2hdmwmvm54rpcjmqt.png)

# How it works:

1. When an EC2 is stopped or terminated, EventBridge will capture the event.

2. EventBrige will trigger the Lambda function (PublishToIotCloud) which publish a message to IOT cloud with the topic 'alarm'.

3. Within the Greengrass group, there is a subscription for the topic 'alarm'. Once it receive a message to 'alarm' topic, it sends message to Greengrass core within Raspberry Pi.

4. Within Raspberry Pi, Lambda will be triggered, and connected alarm (active buzzer and led light) will fire.


# Implementation

#### Installing Greengrass

First it is required to install AWS Greengrass software within the pi. Please refer my other post which will detail all the steps required to install Greengrass within the Pi. [Getting started with AWS Greengrass and Raspberry Pi
](https://dev.to/pubudusj/getting-started-with-aws-greengrass-and-raspberry-pi-1kij)

#### Set up alarm

Here I used active buzzer with a LED light as the alarm. Used a breadboard to connect those to pi. Please make sure you keep the GPIO pin numbers for both active buzzer and LED light as those are required in the next steps to configure the lambda.
Learn more about GPIO [here](https://www.raspberrypi.org/documentation/usage/gpio/).

#### Create services

I have used [AWS SAM](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/what-is-sam.html) to create the required Lambdas and EventBridge rules and targets.

Repository: [https://github.com/pubudusj/iot-alarm](https://github.com/pubudusj/iot-alarm)

Install AWS SAM. Clone above repository and run `sam build --use-container` and `sam deploy -g` which will take you through the required parameters. (Please make sure you create your stack in the same region as the AWS GreengrassCore created in the `Installing Greengrass` section.)

#### Configure Greengrass Group

1. Goto AWS IoT > Greengrass > Groups and select the group already created.

2. Goto Lambda under this group and click on `Add Lambda` button.

3. Click on `Use existing Lambda` and search IotLambda and select the lambda function and click Next.

4. In the next screen, select the `Alias: Iotdeployment` option and click finish.

5. Once Lambda is created, click on Lambda's `Edit Configuration` and increase the `Timeout` value upto 20 seconds.
Also add below `Environment variables`:
    BuzzerPin: [GPIO pin number for active buzzer]
    LedPin: [GPIO pin number for LED light]

6. Next, goto the `Resources` section of the group and click on `Add a local resource`. This is required to configure Raspberry Pi to talk with Greengrass.

7. Add below values:
    Resource Name: `GPIO`
    Device path: `/dev/gpiomem` 
    Group owner file access permission: `Automatically add OS group permissions of the Linux group that owns the resource`
    Lambda function affiliations: select the same lambda function selected in step 3 and select `Read and write access` and save.

8. Once done, goto `Deployments` section and click on `Deploy` which will configure the lambda within the pi.

9. If deployment failed, you can log into the pi and try find the issue within the logs files at `/greengrass/ggc/var/log/system/localwatch/localwatch.log` or at `/greengrass/ggc/var/log/user/[region]/[account_no]/[lambda_function.log]`

#### Configure the trigger events

1. Goto `Subscriptions` section of the group and click on `Add Subscription` button.

2. Select `IoT Cloud` as source and for the target, select the IotLambda function under Lambdas section and click on Next.

3. In the next view, add Topic filter as `alarm`. and save.

#### Testing

To test the functionality within AWS IoT console, goto `Test` section and publish a message adding the topic `alarm`. 
This should trigger the alarm connected to the pi.

#### Demo

Create a EC2 instance in the same region as your stack. Once up and running, change the instance state to `Stop Instance` or `Terminate Instance`. The alarm should trigger.

{% youtube fRM9vhjdtG0 %}

# Some points to highlight

1. Whenever the Lambda is modified, need to re-deploy the Greengrass Group.

2. Lambda configurations set up in SAM is not valid for IOT, you need to specifically set up env variables, timeout for IOT Lambda within Greengrass group.

3. You can extent the functionality to any event supported by EventBridge (not limited to AWS events).

4. In the IotLambda function, `time.sleep(1)` used to make the light and sound to be more like an alarm. Having `sleep` within Lambdas are not really recommended.

5. For the `IotLambda` function, I have used Python3.7 as the run time, as Python3.7 is already installed in the latest Raspberry Pi OS (previously called Raspbian). But you may use any Python version by installing it in the Raspberry Pi.

Please feel free to try this and let me know your thoughts.

*Keep building. Keep sharing!*