#AWS Lambdaを使用したAWSアラーム通知機能構築

# Lambdaを使用したアラーム通知について：
本記事はアラーム通知の必要性からlambdaの構築、サンプルlambdaの紹介の流れで説明したいと思います。

AWSを運用する際にアラームやエラーログをメールやTeamsに通知する必要があります：

● 障害迅速な対応：アラームやエラーログをメールで受け取ることで、問題が発生したことを即座に把握し、迅速に対応できます。特にシステムの可用性に重要な影響を与えるエラーの場合、即座の通知は早期な障害復旧に大きく影響します。

● リアルタイムな監視：エラーログの自動通知はリアルタイムでシステムの健全性を監視する手段の一つです。通知を受けることで、運用チームは問題が発生しているかどうかをすぐに把握できます。

● ユーザーへの影響最小化：エラーが発生した際にユーザーに影響がある場合、それに早急に対応することで、ユーザーエクスペリエンスの損失を最小限に抑えることができます。

● トラブルシューティング：エラーログを通知メールとして受け取ることで、運用チームは迅速に問題の原因を特定し、解決策を見つけることができます。これはサービスの安定性やパフォーマンスの向上に不可欠です。

● 監査と記録：エラーがどのような状況で発生したかをメールで通知することで、後で監査目的で利用したり、将来の改善のために情報を記録しておくことができます。

# 処理フロー:
1. 指定していたロググループに対象ログが検知された
↓
2. アラーム通知用Lambdaを呼び出す
↓
3. Lambda内エラーログを取得する
↓
4. Webhookとメールで通知を飛ばす
↓
5. 終了

本記事は(4)が中心にサンプルをお見せします。

# Lambda構築手順について：
以下の手順を踏んで作成します

1. AWSコンソール画面の上部にある検索欄から「Lambda」を入力し、検索する
2. Lambda詳細画面の左メニューの「関数」をクリックする
3. 右上の「関数の作成」をクリックする
4. 「一から作成」を選択する
5. 「関数名」には任意の文字を入力する
6. 「ランタイム」は「Python 3.8」を選択する
7. 「関数の作成」をクリックする
8. Lambda初期生成完了まで待つ
9. 「設定」タブをクリックし、「一般設定」を編集する
10. 「タイムアウト」項目を1分に修正する
11. 「環境変数」項目を必要な環境変数を入力する 
12. 「保存」を押す
13. 「アクセス権限」をクリックし、ロール名をクリックする
14. ロール設定画面に遷移され、許可ポリシーに必要な権限を付与する
15. Cloudwatch画面に遷移し、対象ロググループを選択する
16. サブスクリプションフィルターを選択し、フィルタパターンを入力する
17. サブスクリプションターゲットに先ほど作成したLambdaを指定する 
完了

# Lambdaサンプルコード：
```notification.py
import base64
import boto3
import datetime
import json
import os
import urllib3
import zlib

from botocore.exceptions import ClientError

# 環境変数を設定する
sns_topic_arn = os.environ['SNS_TOPIC_ARN']
print('sns_topic_arn：'+ sns_topic_arn)

teams_webhook_url = os.environ['TEAMS_WEBHOOK_URL']
print('teams_webhook_url：'+ teams_webhook_url)

def lambda_handler(event, context):
        # ここに送信したい件名を設定する
        subjectmsg = "「アラーム」テスト送信"
               
        # 項目別で整形する
        msg_aws_account_id      = "■ AWS Account ID：" + "\n" 
        msg_target_id           = "■ Target ID：" + "\n" 
        msg_time                = "■ 発生時刻：" + "\n" 
        msg_error_log           = "■ 詳細ログ：" + "\n"
        
        # 本文を整形する
        msg = ""+ "\n\n" + msg_aws_account_id + "\n\n" + msg_target_id + "\n\n" + msg_time + "\n\n" + msg_error_log 
        
        try:
            # メール通知送信関数でメッセージを飛ばす
            send_mail_notification(subjectmsg, msg)
            # Teams通知送信関数でメッセージを飛ばす
            send_teams_notification(subjectmsg, msg)
        except Exception as e:
            # 関数が実行失敗した場合、ログに残す
            print("Function lambda_handler() failed:", e)
            
    return {
        'statusCode': 200,
        'body': json.dumps('Processed all log events.')
    }      
            
# メール通知送信関数      
def send_mail_notification(subjectmsg, message):
    sns = boto3.client('sns')
    try:
        # 変数を通知に代入しメールを配信する
        publishResponse = sns.publish(
            TopicArn=sns_topic_arn,
            Subject=subjectmsg,
            Message=message
        )
    except Exception as e:
        # 関数が実行失敗した場合、ログに残す
        print("Function send_mail_notification() failed:", e)      
            
# Teams通知送信関数
def send_teams_notification(subjectmsg, message):
    try:
        # httpリクエスト管理を可能にする
        http = urllib3.PoolManager()
        # httpリクエストヘッダーを設定する
        headers = {
            "Content-Type": "application/json"
        }
        # 変数を通知メッセージに代入する
        payload = {
            "title": subjectmsg,
            "text": message
        }
        # 通知メッセージをJsonにエンコードする
        encoded_data = json.dumps(payload).encode('utf-8')
        # httpリクエストでメッセージを飛ばす
        response = http.request('POST', teams_webhook_url, body=encoded_data, headers=headers)
        # httpリクエストが成功した場合、ログに残す
        if response.status == 200:
            print("Succeed to send notification to Microsoft Teams. Status code:", response.status)
        # httpリクエストが失敗した場合、ログに残す
        if response.status != 200:
            print("Failed to send notification to Microsoft Teams. Status code:", response.status)
    except Exception as e:
        # 関数が実行失敗した場合、ログに残す
        print("Function send_teams_notification() failed:", e)
```

# 最後に：
AWSを運用する際に、エラーログを早く知りたい時があります。そこはメールやWehbookを利用したTeams通知やSlack通知は必ずお役に立つと思います。
本記事を参考いただき、お役に立っていれば幸いです。