AWS Lambda で CloudWatch アラームからの障害対応自動化
概要
障害対応 = 昔からよくあるアラート検知したらとりあえずプロセス再起動的なやつ。
CloudWatch アラームの SNS メッセージを Lambda で受け取って、対象インスタンスに対して EC2 Run Command (SSM) で定義されたコマンドを実行する。
EC2 セットアップ
1. IAM Role 作成
EC2 に紐付ける Role に以下の Policy をアタッチして作成する。
- AmazonSSMFullAccess
2. EC2 インスタンス作成
上記で作成した IAM Role を付与してインスタンス作成。
OS は以下で構築。
- Amazon Linux AMI 2016.09.1 (HVM)
3. SSM エージェントインストール
起動したインスタンスで以下コマンドでインストール。
$ sudo rpm -ivh https://amazon-ssm-us-east-1.s3.amazonaws.com/latest/linux_amd64/amazon-ssm-agent.rpm
エージェントが起動しているか確認。
$ sudo status amazon-ssm-agent
amazon-ssm-agent start/running, process 22819
Lambda セットアップ
1. SNS topic 作成
とりあえず subscription は空で OK。
2. Lambda function 作成
trigger で先ほど作成した SNS topic を選択。
(Enable trigger にチェックを入れる)
Runtime は Python2.7 を選択。
Lambda コードは以下の通り。
from __future__ import print_function
import boto3
import json
import logging
logger = logging.getLogger()
logger.setLevel(logging.INFO)
ssm = boto3.client('ssm')
def lambda_handler(event, context):
logger.info("Event: " + str(event))
message = json.loads(event['Records'][0]['Sns']['Message'])
logger.info("Event: " + event['Records'][0]['Sns']['Message'])
instanceid = message['Trigger']['Dimensions'][0]['value']
alarm_name = message['AlarmName']
new_state = message['NewStateValue']
reason = message['NewStateReason']
logger.info("%s - %s state is now %s: %s" % (instanceid, alarm_name, new_state, reason))
try:
ssm.send_command(
InstanceIds = [
instanceid
],
DocumentName = "AWS-RunShellScript",
Parameters = {
"commands": [
"service httpd restart"
],
"executionTimeout": ["3600"]
},
)
logger.info("restarting httpd.")
except Exception as e:
logger.error(e)
※EC2 Run Command が実行されるインスタンスは、Cloudwatch アラーム から instanceid を取得して指定する。
※インスタンスで実行されるコマンドを commands にカンマ区切りで記載する。
※実行するコマンドは、とりあえず apache 再起動。
Create a custom role で作成した Role に、以下の Policy をアタッチする。
- CloudWatchLogsFullAccess
- AmazonSSMFullAccess
Cloudwatch アラーム作成
1. ALARM 作成
トリガーとなるメトリクスに閾値、Action を設定する。
Actions に以下を設定する。
Whenever this alarm: State is ALARM
Send notification to: "先ほど作成した SNS topic を指定"
実行テスト
Cloudwatch ALARM 送信
テストなので閾値低めとか、プロセス停止とか。
実行結果確認
Lambda の実行結果は CloudWatch Logs から確認できる。
EC2 Run Command からも Output が確認できる。