LoginSignup
7
8

More than 5 years have passed since last update.

Lambda、Amazon SNS、CloudWatchを使ってサーバの死活監視を行う方法(備忘録)

Posted at

作業の備忘録としてまとめました。

やりたいこと

  • 15分間隔でWebサーバーを死活監視
  • 正常動作はリクエストした時に帰ってくるHTTPステータスコード(200)で判断
  • エラーが発生した場合はメール通知

参考にした記事

事前準備

  • ローカル環境にPython3をインストールしておくこと

手順

本設定は以下の手順で行いました。
なお、手順1~手順3はローカル環境、手順4~手順8のはAWS上での作業となります。

1. PythonのHTTPライブラリのインストール

カレントディレクトにlibサブディレクトリを作成して、libサブディレクトリにHTTPライブラリをインストールします。

# pip install -U requests -t ./lib

2. 死活監視用のプログラム作成

上記記事を参考にプログラムを作成。作成したプログラムは、libサブディレクトリと同じ階層に配置します。

checkservers.py
import json
import boto3
import sys
import os

sys.path.append(os.path.join(os.path.abspath(os.path.dirname(__file__)), 'lib'))

import requests

BUCKET_NAME = os.environ['BUCKET_NAME']
OBJECT_NAME = os.environ['OBJECT_NAME']
SNS_TOPICS_NAME = os.environ['SNS_TOPICS_NAME']

def lambda_handler(event, context):
    if len(BUCKET_NAME) == 0 or len(OBJECT_NAME) == 0 or len(SNS_TOPICS_NAME) == 0:
        print("Please input BUCKT NAME, OBJECT NAME and SNS_TOPICS_NAME")
        sys.exit()
    target_json = get_target_servers()
    check_target_servers(target_json)

def get_target_servers():
    s3 = boto3.resource('s3')
    obj = s3.Object(BUCKET_NAME, OBJECT_NAME)
    response = obj.get()
    body = response['Body'].read()
    return body.decode('utf-8')

def check_target_servers(target_json):
    data = json.loads(target_json)
    servers = data['servers']

    error_servers = []

    for server in servers:
        name = server['name']
        url = server['url']
        try:
            res = requests.get(url)
            if res.status_code != 200:
                error_servers.append(server)
        except Exception:
            error_servers.append(server)

    if len(error_servers) == 0:
        print("Successful finished servers checking")
    else:
        response = send_error(name, url, error_servers)
        print("Error occured:")
        print(response)
        print(error_servers)

def send_error(name, url, error_servers):
    sns = boto3.client('sns')
    sns_message = "Error happens:\n\n" + json.dumps(error_servers, indent=4, separators=(',', ': '))
    subject = '[ServerMonitor] Error happens'
    response = sns.publish(
        TopicArn=SNS_TOPICS_NAME,
        Message=sns_message,
        Subject=subject
    )
    return response

3. Lambdaにアップロードするzipファイルの作成

手順1と手順2で作成したlibサブディレクトリとプログラム(checkserver.py)をzip化します。この時、libサブディレクトリとプログラムを配置したディレクトリをzip化するのではなく、libサブディレクトリとプログラムを直接zip化します。
(Lambda関数のハンドラー設定に関わってくるので注意が必要)

4. Amazon SNSの通知設定

死活監視でエラーとなった際に通知するメール送信先を設定します。
Amazon SNSコンソールを開き、「新しいトピックの作成」からトピックを作成します。「サブスクリプションの作成」でプロトコルに「Email」、エンドポイントにエラー通知先のメールアドレスを入力してサブスクリプションを作成します。

5. IAM ロールの作成

Lambda関数作成時に設定するロールを作成します。アタッチするポリシーには、以下の3つを選択します。
(ポリシーの内容をきちんと確認できていませんが、動作確認は取れています)

  • AWSLambdaBasicExecutionRole
  • AWSLambdaS3ExecutionRole-XXXXXXXXXXXXX
  • AmazonSNSFullAccess

6. S3に監視対象を記載したjsonファイルをアップロード

手順2で作成したプログラムから参照する監視対象を記載したjsonファイルをS3のバケットにアップロードします。jsonファイルは、以下のように記載します。

{
    "servers": [
        { "name": "server_name_1", "url": "https://www.google.co.jp" },
        { "name": "server_name_2", "url": "https://www.yahoo.co.jp" }
    ]
}

7. Lambda関数の作成

関数の作成は「設計図」からではなく「一から作成」を選択します。続いて、任意の名前を入力してからランタイムに「Python 3.6」を選択、ロールには手順5で作成したロールを選択します。

関数を作成した後、関数コードのコードエントリタイプから「.zipファイルをアップロード」を選択し、手順3で作成したzipファイルをアップロードします。ハンドラは、「プログラムファイル名.プログラム内のハンドラー定義」の形で設定します。例えば、アップロードしたプログラムが「checkservers.py」の場合、「checkservers.lambda_handler」と設定します。この時、手順3の内容で正しくzip化しておかないとハンドラが認識されないため注意が必要です。
2.png

次に、プログラム内で参照している環境変数を定義します。

  • BUCKET_NAME  :jsonファイルをアップロードしたバケット名
  • OBJECT_NAME  :アップロードしたjsonファイル名
  • SNS_TOPICS_NAME:手順4で作成したAmazon SNSのトピックのARN 3.png

ここで、テストを行います。テストイベントの設定でイベントテンプレートに「Amazon CloudWatch」を選択し、任意のイベント名を設定してテストイベントを作成します。このとき、テンプレートの内容を変更する必要はありません。
4.png
テストを実行する際、jsonファイルに実在しないURLを設定しておけば、死活監視のエラーメールが送信されることを確認することができます。テストに失敗する場合は、「所要時間」や「使用中の最大メモリ」の結果を確認し、必要に応じて基本設定の「メモリ(MB)」や「タイムアウト」を調整してください。

8. CloudWatch イベントのルール作成

CloudWatch イベントのルールを作成します。今回は15分間隔で死活監視を行うため、イベントソースのスケジュールから「一定の速度」を選択して15分を設定します。ターゲットの機能には、作成したLambda関数を設定します。
5.png

最後に、Lambda関数のDesignerから「CloudWatch Events」を選択して、作成したルールが正しく設定されていることを確認できたら終了です。設定が「有効」になっていることも忘れずに確認してください。
6.png

7
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
8