作業の備忘録としてまとめました。
やりたいこと
- 15分間隔でWebサーバーを死活監視
- 正常動作はリクエストした時に帰ってくるHTTPステータスコード(200)で判断
- エラーが発生した場合はメール通知
参考にした記事
事前準備
- ローカル環境にPython3をインストールしておくこと
手順
本設定は以下の手順で行いました。
なお、手順1~手順3はローカル環境、手順4~手順8のはAWS上での作業となります。
1. PythonのHTTPライブラリのインストール
カレントディレクトにlibサブディレクトリを作成して、libサブディレクトリにHTTPライブラリをインストールします。
# pip install -U requests -t ./lib
2. 死活監視用のプログラム作成
上記記事を参考にプログラムを作成。作成したプログラムは、libサブディレクトリと同じ階層に配置します。
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化しておかないとハンドラが認識されないため注意が必要です。
次に、プログラム内で参照している環境変数を定義します。
- BUCKET_NAME :jsonファイルをアップロードしたバケット名
- OBJECT_NAME :アップロードしたjsonファイル名
- SNS_TOPICS_NAME:手順4で作成したAmazon SNSのトピックのARN
ここで、テストを行います。テストイベントの設定でイベントテンプレートに「Amazon CloudWatch」を選択し、任意のイベント名を設定してテストイベントを作成します。このとき、テンプレートの内容を変更する必要はありません。
テストを実行する際、jsonファイルに実在しないURLを設定しておけば、死活監視のエラーメールが送信されることを確認することができます。テストに失敗する場合は、「所要時間」や「使用中の最大メモリ」の結果を確認し、必要に応じて基本設定の「メモリ(MB)」や「タイムアウト」を調整してください。
8. CloudWatch イベントのルール作成
CloudWatch イベントのルールを作成します。今回は15分間隔で死活監視を行うため、イベントソースのスケジュールから「一定の速度」を選択して15分を設定します。ターゲットの機能には、作成したLambda関数を設定します。
最後に、Lambda関数のDesignerから「CloudWatch Events」を選択して、作成したルールが正しく設定されていることを確認できたら終了です。設定が「有効」になっていることも忘れずに確認してください。