インフラブログ

とあるWEBサイトのインフラを構築運用するメモ

AWS SNSでメール通知を行う

AWS Cloudwatchで監視を行っていてしきい値超えを検知した場合に、AWS SNSで設定されている通知を行う事ができます。 SNSでの通知としては・メールを送信・指定のURLにアクセスする・APNsにPush通知を行うなどがありますが、今回は指定のメールアドレスにメールを送信します。

下記のように3つのトピックを用意して、アラートの重要度に合わせて通知先を振り分けるようにします。

  • systemalert
    • ただちにサービスレベルに影響しない(ディスク残量低下、オートスケール発動の通知)
  • systemcritical
    • サービスレベルに影響がある(ELBのレスポンスタイムが2秒以上、RDSのレプリケーション遅延を10秒以上検知)
  • systemservicedown
    • サービスダウンしている状態(サイトヘルスチェックでNG)

トピックアクションとして、以下のように指定のメールアドレスにメール送信を行うようにします。

  • systemalert-{stage|production}@watch.example.com
  • systemcritical-{stage|production}@watch.example.com
  • systemservicedown-{stage|production}@watch.example.com
  • 上記メールアドレスにメールが送られてきたらskepeのアラート部屋にも発信したいので、watchサーバ上の/etc/aliasesで設定をしておきます。 設定はこんなかんじ

上記トピックをスクリプトで新規作成できるようにしておきます。 なおトピックのサブスクリプション作成時に、指定したメールアドレスに確認用のメールが送信されるので、受信してメールの中の確認用URLにアクセスする必要があります。

stage = ARGV.shift
stage ||= "staging"
az = ARGV.shift
az ||="main"
domain = "@watch.example.com"
topics = ["systemalert-#{stage}", "systemcritical-#{stage}", "systemservicedown-#{stage}"]

AWS.config(YAML.load(File.read('/etc/scripts/aws/config.yml')))

client = AWS::SNS::Client.new

topics.each{|topic|
  # create topic
  response = client.create_topic(
    :name => topic
  )
  # subscript
  client.subscribe(
    :topic_arn => response[:topic_arn],
    :protocol => "email",
    :endpoint => topic + domain
  )
}