I wanted to write up a quick post on how easy it was to add AWS Simple Notification Service messaging support to deadman-check, a monitoring application written in Ruby.

Deadman-check was put together to be an alerting service that can alert when data isn't present or is stale. This is known as a deadman switch monitoring concept. Initially, it supported alerting to Slack channels directly. This was great but SNS support would be awesome! You may be wondering why support SNS? In a nutshell, SNS is a broadcast point. In deadman-check we can encapsulate the alert message into one message that can be sent to one endpoint and from there be broadcast to an unlimited number of subscribers. These subscribers may be SMS, email or possibly AWS Lambda functions that can all simultaneously receive the one message sent from deadman-check (I really like the last one). The SNS to AWS Lambda triggers really open up a lot of event driven alerting possibilities!

To add SNS support to Deadman-check I simply needed to initialize a Ruby object via the AWS Ruby SDK. I would produce the initialization only when the CLI flag is present and requesting it.

In my class initialization for the switch monitor I added the attr_accessors needed - alert_to_sns and alert_to_sns_region

These new accessors will be the SNS ARN (the unique AWS identifier for the SNS topic to send messge to) and the AWS region the topic is in.

    def initialize(host, port, target, alert_to_slack, alert_to_sns,
                  alert_to_sns_region, recurse, daemon_sleep)
    --snip--
    end

During initialization I will create the connection to SNS unless the variables are nil.

    unless @alert_to_sns.nil?
      @sns = Aws::SNS::Client.new(
        region: @alert_to_sns_region
        )
    end

To be able to talk to SNS from the application there are a few different ways you can authenticate.

1. ENV['AWS_ACCESS_KEY_ID'] and ENV['AWS_SECRET_ACCESS_KEY']
2. The shared credentials ini file at ~/.aws/credentials (more information)
3. From an instance profile when running on EC2

Depending on how you deploy the deadman-check service one of the above methods should be easy to make available on the running EC2 instance or from a server in your datacenter.

Now that the client connection to AWS is taken care of let's move onto the message publish function! This part is the juicy part of generating the one message that will get sent to the SNS topic for broadcast.

    def sns_alert(alert_to_sns, target, epoch_diff)
      @sns.publish(
        target_arn: @alert_to_sns,
        message_structure: 'json',
        message: {
          :default => "Alert: Deadman Switch triggered for #{target}",
          :email => "Alert: Deadman Switch triggered for #{target}, with
          #{epoch_diff} seconds since last run",
          :sms => "Alert: Deadman Switch for #{target}"
        }.to_json
      )
    end

This function will take in some business logic from other parts of deadman-check and generate a message that will publish to the topic (target). In the message: hash element you can see we can define a 'default' and then more specific messages based on the type of SNS subscriber. SMS messages can be shorter and more concise, while maybe Email might be more wordy given we have more screen real estate to work with.

That is it! The application is now ready to publish to SNS. The sky's the limit.