OSパッチ適用結果をメール通知してみた

前回投稿した「OSパッチ適用を自動化」させた後、結果をメールに通知させる方法をまとめてみました。
OSパッチ適用を自動化させる方法はこちらをご参照ください。

AWS Systems Manager の Patch Manager で OS パッチ適用を自動化してみた
AWS Systems Manager でパッチ適用を自動化する方法をまとめてみました。

 

アーキテクチャ

今回は赤枠内を実装してみました。
Amazon CloudWatch Logs に出力されたログから、指定した任意の文字列をトリガーに Amazon SNS 経由で適用結果をメールで通知する関数を作成します。

 

AWS Lambdaとは、
サーバーをプロビジョニングまたは管理することなくコードを実行することができるサービスです。
https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/welcome.html

 

Amazon SNSとは、
Amazon Data Firehose、Amazon SQS、AWS Lambda、HTTP、電子メール、モバイルプッシュ通知、モバイルテキストメッセージ (SMS) などのサポートされているエンドポイントタイプを使用して、クライアントが公開されたメッセージを受信することができるサービスです。
https://docs.aws.amazon.com/sns/latest/dg/welcome.html

 

設定手順

前回設定したOS「Windows2022」のEC2にパッチ適用した結果を、メール通知させる手順をまとめました。
1.トピックの作成
2.サブスクリプションの作成
3.Lambda関数の作成
4.Lambda サブスクリプションフィルターの作成

 

1.トピックの作成

Amazon SNSの左メニュー「トピック」をクリックし、「トピックの作成」をクリックします。

 

▼ 詳細
「タイプ」欄は、「スタンダード」を選択します。
「名前」欄は、任意のトピック名を入力します。
「表示名」欄は、任意の表示名を入力します(表示名が実際のメール差出人の名前になります)。

 

以下の欄はデフォルトのままにし、「トピックの作成」をクリックします。
▼暗号化 – オプション
▼アクセスポリシー – オプション
▼データ保護ポリシー – オプション
▼配信ポリシー (HTTP/S) – オプション
▼配信ステータスのログ記録 – オプション
▼タグ – オプション
▼アクティブトレース – オプション

 

2.サブスクリプションの作成

作成したトピックから、「サブスクリプションの作成」をクリックします。

 

▼ 詳細
「プロトコル」欄は、「Eメール」を選択します。
「エンドポイント」欄は、通知先のメールアドレスを入力します。

以下の欄はデフォルトのままにし、「サブスクリプションの作成」をクリックします。
▼サブスクリプションフィルターポリシー – オプション
▼Redrive ポリシー (デッドレターキュー) – オプション

 

しばらくすると、指定したアドレス宛に確認のメールが届くので、「Confirm Subscription」をクリックし、「Subscription confirmed!」が表示されることを確認する。

サブスクリプションのステータスが「確認済み」になっていることを確認する。

 

3.Lambda関数の作成

Lambdaの左メニュー「関数」をクリックし、「関数を作成」をクリックします。

 

▼ 関数の作成
「一から作成」を選択します。

 

▼ 基本的な情報
「関数」欄は、任意の関数名を入力します。
「ランタイム」欄は、Lambda関数で記述するプログラミング言語を選択します。
今回はPythonを選択しました。

▼ アクセス権限
「実行ロール」欄は、適切なアクセス権が付与された任意のロールを選択します。

 

以下の欄はデフォルトのままにし、「関数の作成」をクリックします。
▼ その他の構成

 

▼ コード
コードソースを以下のコードに修正し、「Deploy」をクリックする。
※Deployをクリックしないと、変更が反映されないので注意してください。

 

import logging
import json
import base64
import gzip
import boto3
import os

logger = logging.getLogger()
logger.setLevel(logging.INFO)

def lambda_handler(event, context):
    # CloudWatchLogsからのデータはbase64エンコードされているのでデコード
    decoded_data = base64.b64decode(event['awslogs']['data'])
    # バイナリに圧縮されているため展開
    json_data = json.loads(gzip.decompress(decoded_data))

    logger.info("EVENT: " + json.dumps(json_data))

    # ログデータ取得
    log = json_data['logEvents'][0]['message']
    instanceid_position = log.find('PatchGroup')
    instanceidtmp = log[:instanceid_position]
    instanceid = instanceidtmp.replace('Patch Summary for ','')
    print(instanceid)
    result_position = log.find('Results')
    result = log[result_position:]
    print(result)
    patchGroup_start = log.find('PatchGroup')
    patchGroup_end = log.find('BaselineId')
    patchGrouptmp = log[patchGroup_start:patchGroup_end]
    patchGroup = patchGrouptmp.replace('PatchGroup          : ','')
    print(patchGroup)
    messagetmp = """
パッチ適用結果を通知します。
対象インスタンス・適用結果は下記となります。

〇対象インスタンス{0}
〇パッチグループ
{1}
〇適用結果
{2}
    """
    message = messagetmp.format(instanceid,patchGroup,result)
    print(message)

    try:
        sns = boto3.client('sns')
        #SNS Publish
        publishResponse = sns.publish(
        TopicArn = os.environ['SNS_TOPIC_ARN'],
        Message = message,
        Subject = os.environ['ALARM_SUBJECT']
        ) 

    except Exception as e:
        print(e)

 

▼ 環境変数
「設定」タブ>「環境変数」にて、「編集」をクリックする。

 

「環境変数」をクリックし、以下のキーと値を入力し、「保存」をクリックする。

キー
ALARM_SUBJECT パッチ適用通知
SNS_TOPIC_ARN 作成したSNSトピックのARN名

 

4.Lambda サブスクリプションフィルターの作成

CloudWatchの左メニュー「ロググループ」をクリックし、SSMでログの出力先に設定したロググループを検索します。

 

「サブスクリプションフィルター」タブをクリックし、「作成」>「Lambdaサブスクリプションフィルターを作成」をクリックします。

 

▼ 送信先を選択
「Lambda関数」欄は、「3.Lambda関数の作成」で作成した関数名を選択します。

 

▼ ログ形式とフィルターを設定
「ログの形式」欄は、「JSON」を選択します。
「サブスクリプションフィルターのパターン」欄は、フィルターする任意の文字列を入力します。
「サブスクリプションフィルター名」欄は、任意のフィルター名を入力します。

すべての項目を設定後、「ストリーミングを開始」をクリックします。

 

メール通知確認

パッチ適用完了後に以下のようなメール届くことを確認します。

 

まとめ

Lambda↔SNS間の通知機能を実装することで、パッチ適用結果の通知にかかわらずあらゆるサービスの状態をメールで受け取ることができるようになります。

皆さんのお役に立てば幸いです。

タイトルとURLをコピーしました