TL;DR
- 専用Slackアプリを作らなくてもSlackワークフローでWebhook通知作れるじゃん!
- SNS → LambdaでSlack通知を作ろう
- エラーログをSlack通知するとスタンプ機能が使えて便利
はじめに
CloudWatchのアラートをSlackで通知したいな~と思いつつも、専用チャンネルもないし一旦メール通知でと逃げていましたが、メールで通知を受け取ってから誰が確認するのか振り分けたりするのも面倒ですし、Slack通知を実装していきます。
今回はWebhookでアラートがあることをお知らせするのみで、アラート内容の確認はCloudWatchで行いますので、SlackワークフローのWebhookメッセージを使ってシンプルに作っていきます。
本記事は以前に書いた上記の記事の続きが含まれます。
CloudWatchのメトリクス作成やアラート設定などの基本的な操作については以前の記事に記載したため、今回は省略させていただきます。
実装手順
セキュリティに関する注意点
今回使用する「SlackワークフローのWebhook」は、URLが漏えいすると外部から誰でもメッセージを送信できてしまうという制約があります(トークン認証等を今回盛り込んでいないため)
機密性の高い情報を扱う場合や本番環境での運用には、Slack Appの利用を強く推奨します。
Slackワークフローを作成する
今回Slack通知を送りたいチャンネルを開いたら、右上の三点リーダーをクリックし、「ワークフローを追加する」からワークフローの作成を行っていきます。
ワークフローに適当な名前を設定したら、イベント選択に移っていきます。
Slackのイベントから「Webhook」からを選択し、この後作成するLambda関数からのリクエストを受け付けられるようにします。
Webhookの設定画面に移ったら、今回Slack通知で実際に送るメッセージを挿入する変数を作成します。
「変数を設定する」をクリックし、今回はキーを「text」としておきます。
「終了」ボタンをクリックしてデータ変数を保存したら、「続行する」ボタンをクリックしてWebhookの設定を完了します。
続いてWebhookを使った後のステップを追加していきます。
「チャンネルへメッセージを送信する」というステップを追加し、Lambdaから受け取った通知メッセージをチャンネルに送信できるようにします。
チャンネルへのメッセージ送信の設定で、送信するチャンネルを選択し、メッセージの部分で先ほど設定したデータ変数が送られるように設定します。
右下の「変数を挿入する」から選択すると簡単に設定できますね。
メッセージの設定ができたら、「保存する」でメッセージ送信の設定を完了しましょう。
再度Webhookの設定を開くと、一番下に「ウェブリクエストのURL」というものが表示されています。このURLは後でLambda関数に設定しますので、コピーしておいてください。
設定が完了したら、「完了」ボタンをクリックし、ワークフローを公開しましょう。
これでSlack側の設定は完了です。
ワークフローの公開設定にて公開範囲をワークスペース全体にすると、Slackワークスペース内の全員からWebhook URLが参照できてしまいます。
Webhook URLの漏えいを防ぐため、公開範囲を最小に絞ることを推奨します。
Lambda関数を設定する
以前作成したCloudWatchアラートとSNSのサブスクリプションの設定を変更し、先ほどのWebhook URLに対して、Lambda関数経由で通知を送信するように設定していきます。
まず、AWS マネジメントコンソールからLambdaを選択し、「関数を作成」に進みます。
関数を作成すると、画面下に「コードソース」というエディタが表示されます。
今回は先に、先ほど取得したWebhookのURLを設定しておきます。
設定タブを開いてから「環境変数」を開き、環境変数にURLを設定していきます。
環境変数の編集にてキーに「SLACK_WEBHOOK_URL」と設定し、値に先ほど取得したURLを設定します。
SLACK_WEBHOOK_URLの値はセキュリティの観点からコードソースに入力しないようにしましょう!
環境変数の設定が行えたら、コードソースに戻り、下記のPythonコードをコピペしてください。
import os
import json
import urllib.request
# 環境変数から取得
SLACK_WEBHOOK_URL = os.environ.get('SLACK_WEBHOOK_URL')
def lambda_handler(event, context):
if not SLACK_WEBHOOK_URL:
print("Error: SLACK_WEBHOOK_URL is not set.")
return
# SNSからのメッセージを取得
sns_message = event['Records'][0]['Sns']['Message']
# Slackに送るペイロードの作成
# ※Slackワークフローで設定した変数名(例: text)に合わせて調整してください
slack_data = {
"text": f"🚨 *CloudWatchでアラートが発生しました!*\n{sns_message}"
}
req = urllib.request.Request(
SLACK_WEBHOOK_URL,
data=json.dumps(slack_data).encode('utf-8'),
headers={'Content-Type': 'application/json'}
)
with urllib.request.urlopen(req) as res:
return res.read().decode('utf-8')
コードの設定が行えたら、テストを行いSlackへメッセージが届くことを確認します。
テスト用のイベントJSONはこちらを使用してみてください。
{
"Records": [
{
"EventSource": "aws:sns",
"Sns": {
"Message": "これはLambdaからのテスト通知です。Slackワークフローへの疎通確認に成功しました!"
}
}
]
}
テストイベントの設定を行えたら、「保存」を行ったのち、「テスト」を実行し、Slackにメッセージが届いていることを確認しましょう。
無事Slackにメッセージが届いていたら、コードソースに戻り、「Deploy」ボタンからデプロイを行ってLambda関数の設定は完了です。
SNSとLambdaを紐づける
続いて作成したLambda関数をSNSトピックと紐づけ、CloudWatchのアラートとの接続を確保していきます。
Lambda関数から「トリガーを追加」を選択し、SNSとの接続設定を行います。
SNSを選択し、トピックとして作成済みのSNSトピックを選択します。
まだSNSトピックなどを作成していない場合は、記事冒頭の前回記事より作成してみてください。
これでCloudWatchからSNSを経由してLambdaを使用したSlack通知が実現できました。
サービスのエラー通知などをSlack通知しておくと、気づきやすさが増しますしスタンプなので、現在の確認ステータスなども手軽にチェックできるのでどんどん活用していきたいですね
さいごに
MSOL Digitalでは、ミッション・ビジョンの実現に向けて、新たな仲間を募集しています。
少しでもご興味をお持ちいただけましたら、ぜひエントリーをご検討ください。
また、すぐに転職をお考えでない場合でも、カジュアル面談からのスタートも大歓迎です。
まずはお気軽にお話しできますと幸いです!
■エントリーページ
■カジュアル面談の申し込み












