CloudWatch Alarm を SNS 経由で Slack に通知するときのメッセージ内容を良い感じにしてみた
2018-12-20CloudWatch でアラームの設定をして、SNS 経由で Slack に通知する際のメッセージを、見やすい形に整形する Lambda を作ってみました。
経緯
CloudWatch Alarm を Slack に通知すること自体は非常に簡単で、下記の方法で通知させることが可能です。
- SNS トピックを作成
- 作成したトピックのサブスクリプションに、
HTTPS
のプロトコルで Slack の Incoming Webhooks のエンドポイントを指定 - CloudWatch Alarm の通知先に、作成した SNS トピックを指定
ただ、これだけでは CloudWatch Alarm から送られてくる JSON の文字列がそのままメッセージ本文として通知されるので、非常に見づらいです。
これを良い感じに整形します。
やったこと
方法としては、SNS のサブスクリプションで直接 Incoming Webhooks のエンドポイントを指定するのではなく、 Lambda 関数を指定します。そして、その Lambda 関数内でメッセージの整形・ Slack への通知を実行します。
で、作ったのは次のような Lambda 関数。
import boto3
import json
import logging
import os
from base64 import b64decode
from urllib.error import URLError, HTTPError
from urllib.request import Request, urlopen
SLACK_CHANNEL = os.environ['slackChannel']
ENCRYPTED_HOOK_URL = os.environ['kmsEncryptedHookUrl']
HOOK_URL = boto3.client('kms').decrypt(CiphertextBlob=b64decode(ENCRYPTED_HOOK_URL))['Plaintext'].decode('utf-8')
logger = logging.getLogger()
logger.setLevel(logging.INFO)
def lambda_handler(event, context):
"""Lambda handler."""
logger.info('Event: ' + str(event))
message = json.loads(event['Records'][0]['Sns']['Message'])
logger.info('Message: ' + str(message))
alarm_name = message['Trigger']['MetricName']
new_state = message['NewStateValue']
reason = message['NewStateReason']
state_color = '#00FF00'
if new_state != 'OK':
state_color = '#FF0000'
slack_message = {
'channel': SLACK_CHANNEL,
'icon_emoji': ':cloudwatch-%s:' % (new_state.lower()),
'attachments': [
{
'color': state_color,
'fields': [
{
'value': "*%s* state is now *%s*\n```\n%s\n```" % (alarm_name, new_state, reason)
}
]
}
]
}
req = Request(HOOK_URL, json.dumps(slack_message).encode('utf-8'))
try:
response = urlopen(req)
response.read()
logger.info('Message posted to %s', slack_message['channel'])
except HTTPError as e:
logger.error('Request failed: %d %s', e.code, e.reason)
except URLError as e:
logger.error('Server connection failed: %s', e.reason)
'icon_emoji': ':cloudwatch-%s:' % (new_state.lower())
の部分では通知用のアイコンをカスタム絵文字で指定しています。
事前に :cloudwatch-ok:
と :cloudwatch-alarm:
という名前でカスタム絵文字を作成しておくと、より それっぽさが出ます。不要な場合はこの 1 行を削除すれば ok です。
実際は次のような形で通知が届きます。
とりあえず OK
と ALARM
の場合のみを考慮したパターンになってますが、適宜 INSUFFICIENT_DATA
の状態についても色とかメッセージを変えることもできそうです。
comments powered by Disqus