Cloudwatchの機能を使ってEC2の自動復旧(オートリカバリー)を設定することができますが、管理しているEC2が増えてくるとアラーム設定自体がとても面倒で、かつ設定漏れのリスクも出てきます
そこで、EC2自動復旧の自動一括設定ができるようにします
#前提条件
- 自動復旧がサポートされているEC2インスタンスタイプであること
サポートされているEC2を確認 - Cloudwatch利用
#lambdaを使ってEC2のオートリカバリーを自動設定する
Cloudwatchで、EC2の「StatusCheckFailed_System」を検知し自動再起動する設定ができます
lambdaを使って、特定のタグを設定したEC2に対して、オートリカバリーのCloudwatchアラームを自動一括設定できるようにします
##まずは、lambdaを作成します
python 3.9でlambda関数を作成しました
import json
import boto3
import config
# Cloudwatchアラーム設定関数
def put_cwalarm(instanceId, ec2_name):
print ("instanceId = ", instanceId)
print ("ec2 name tag = ", ec2_name)
cloudWatch = boto3.client('cloudwatch')
result = cloudWatch.put_metric_alarm(
AlarmName = config.ALARM_NAME + "_" + instanceId,
AlarmDescription = ec2_name + config.ALARM_DESC,
AlarmActions = [
config.ALARM_TOPIC,
config.ALARM_ACTION
],
OKActions = [
config.ALARM_TOPIC
],
MetricName = config.METRIC_NAME,
Namespace = config.NAMESPACE ,
Statistic = config.STATISTICS,
Dimensions = [{"Name": "InstanceId", "Value": instanceId}],
Period = config.ALARM_PERIOD,
EvaluationPeriods = config.EVALUATION_PERIOD,
Threshold = config.THRESHOLD,
ComparisonOperator = config.COMPARISON
)
print ("responce = ", result)
#put metric alarmに対する戻り値の中のHTTPStatusCodeのみをリターンする
return result["ResponseMetadata"]["HTTPStatusCode"]
def lambda_handler(event, context):
msg = ""
err_msg = ""
ins_id = ""
#TAG KEYが設定されているEC2に対しCloudwatchアラーム設定関数を実行する
for reservation in boto3.client('ec2').describe_instances(Filters=[{'Name': 'instance-state-name','Values': ['running']}])["Reservations"]:
for instance in reservation["Instances"]:
for tag in instance["Tags"]:
if(tag["Key"] == config.TAG_KEY and tag["Value"] == config.TAG_VALUE):
#InstanceIdを取得する
ins_id = instance["InstanceId"]
#Name tagを取得する
ec2_tags = dict([(tag['Key'], tag['Value']) for tag in instance['Tags']])
name_tag = ec2_tags['Name']
#alarmを設定する
res = put_cwalarm(ins_id, name_tag)
#200OK以外はエラーをメッセージに入れておく
if(res == 200) :
msg = "[OK]" + ins_id + " : created/updated alert" + msg + " / "
else :
err_msg = "[ERROR]" + ins_id + " : failed alert create" + err_msg + " / "
return {
'statusCode': 200,
'body': msg,
'err': err_msg
}
環境設定値は別ファイルにしました
対象のタグ名、閾値等はお好みで設定してください、下記は参考です
ALARM_ACTION = "arn:aws:automate:ap-northeast-1:ec2:recover"
METRIC_NAME = "StatusCheckFailed_System"
NAMESPACE = "AWS/EC2"
STATISTICS = "Maximum"
ALARM_PERIOD = 60
EVALUATION_PERIOD = 2
THRESHOLD = 1
COMPARISON = "GreaterThanOrEqualToThreshold"
##lambdaの設定
- 対象のEC2が多い場合は実行時間がかかるので、lambdaのタイムアウトを長く設定しておいた方がタイムアウトエラーを回避できます
- EC2とCloudwatchへのアクセスが必要なので、ロールを付与しておいてください
- アラーム通知先のSNSを先に作成しておいてください
##EC2の設定
- TAGを設定しておいてください
##実行
上記のlambda関数に引数は必要ないので、トリガー設定なしでそのまま実行すればOK
lambdaのコンソールからTestで実行してしまいましょう
#結果
Cloudwatchコンソールを確認し、アラームが設定されていれば成功です
#閾値等の設定値を変更したい時、対象のEC2が増えた時
lambdaの設定値を変更して、再度lambdaを実行するだけでOKです
既存のアラームは更新され、そうではない場合は新規アラームが作成されます
アラーム名などCloudwatchで変更不可能の要素は変更できないので注意です