SlackからTeamsに移行して久しい弊社では、CloudWatch AlarmやGhost InspectorのSlack通知のためだけにSlackを起動しているような人がいました。
見落としや業務効率の低下を招くので、Teamsに一本化してやろうというお話。
Ghost InspectorのTeams連携についてはGhost Inspector – Teams通知連携を参照。
軽く調べたらWebhookを使えばいいらしい。簡単~~~!!
1. Teamsのコネクタを作成
Slackで言うところのIntegration。
通知を受け取りたいチャネルにて、下記の設定を行う。
通知用のチャネルを作るのが良さそう。




※忘れてしまっても、コネクタ > 構成済み > Incoming Webhook > (構成済みを展開) > 管理 から再度確認できる。
余談
アイコン画像は下記のように6角形に切り抜かれて使用されるため、周囲の余白をいい感じに調整すると気分が良い。

2. Teams通知のLambdaを作成
下記のような関数をさっくりと作成。
参考にした記事のほぼそのまま。
コンパクトにしたかったのでいくらか省略し、組み込みのライブラリだけ使うように書き換えた程度。かっこよくはない。
import json
import logging
from urllib.request import Request, urlopen
from urllib.error import URLError, HTTPError
HOOK_URL = "(WebhookURLを記載)"
logger = logging.getLogger()
logger.setLevel(logging.INFO)
def lambda_handler(event, context):
    logger.info("Event: " + str(event))
    
    subjet = event['Records'][0]['Sns']['Subject']
    
    message_json = json.loads(event['Records'][0]['Sns']['Message'])
    logger.info("Message: " + str(message_json))
    newStateReason = message_json['NewStateReason']
    newStateValue = message_json['NewStateValue']
    nameSpace = message_json['Trigger']['Namespace']
    metricName = message_json['Trigger']['MetricName']
    alarm_description = message_json['AlarmDescription']
    # Create contents to POST to Microsoft Teams.
    text = [
        newStateReason,
        "\r\n\r\n",
        "**Alarm State:** {0}          **Name Space:**: {1}".format(newStateValue, nameSpace),
        "**Metric:** {0}".format(metricName),
        "\r\n\r\n",
        alarm_description,
        ]
    request_data = {
        'title': subjet,
        'text': '\r\n\r\n'.join(text)
        }
    # POST to Microsoft Teams.
    request = Request(
        HOOK_URL, 
        data=json.dumps(request_data).encode('utf-8'),
        method="POST"
    )
    try:
        with urlopen(request) as response:
            response_body = response.read().decode('utf-8')
            logger.info(response_body)
    except HTTPError as err:
        logger.error(err.code)
    except URLError as err:
        logger.error(err.reason)
3. SNSトピックを作成
既存の通知先を置き換えることになったので、サブスクリプションの置換のみ。

※SNSトピックとの紐付けは、Lambda関数の「トリガー」設定からでも行なえる。(関数の概要 > トリガーを追加 > SNSを選択 > トピックを選択 > [追加])
4. CloudWatch アラームを作成
既存のアラームの通知先を変えただけなので詳細は省略。
アラームのアクションとして通知先に先程のSNSトピックを指定する。
5. 動作確認
適当にしきい値を下げてアラーム状態にしてみると、コネクタ設定をしたチャネルにて、下記のような投稿が確認できた。

(投稿者の名称が手順と異なるのはそのため)
課題
Teamsは現状、Webhookによる投稿でチャネル通知(Slackの@channel的なメンション)が使えないらしく、アラーム通知に気付きにくいという問題がある。
- Notification for connectors – Welcome to UserVoice!
- Webhook needs to support forced notification a la “@channel”, “@team”, “@person” – Welcome to UserVoice!
- Allow Webhooks Extensions to @mention individuals and channels – Welcome to UserVoice!
今後に期待……
