EC2のStatus Checkの変異をSNSを通してPagerDutyからSlackへ通知させる
July 12, 2016
EC2がちょくちょくStatus ChecksがコケてTerminateされていたので
CloudWatchで見ているStatus Checkの値の変異を見て
SNSに通知をさせている。
SNS <-> PagerDuty <-> Slack
参考URL
一番良いのはEC2が立ち上がってきた時に自分自身に下記設定を導入し
自分が消える時に設定を削除するのが好ましいが、所々事情があり
下記のようなスクリプトを特定のEC2で回している。
#!/usr/bin/env ruby
region = 'REGION'
# インスタンスID一覧を取得する ( --max-items XXX # インスタンス数次第 )
instance_ids = `aws --region #{region} ec2 describe-instances \
--max-items XXX \
--filters Name=tag-key,Values=Name \
| jq -r '.Reservations[].Instances[].InstanceId'
`
# CloudWatchでStatusCheckFailed_Checkが設定されているインスタンスID一覧 ( --max-items XXX # インスタンス数次第 )
checked_instance_ids = `aws --region #{region} cloudwatch describe-alarms \
--max-items XXX \
| jq -r '.MetricAlarms[].AlarmName' \
| grep 'StatusCheckFailed_Check' \
| cut -f 1 -d ' '
`
# 改行で要素を分割
instance_ids = instance_ids.split("\n")
checked_instance_ids = checked_instance_ids.split("\n")
# インスタンス一覧にあってCloudWatch側にない監視追加対象のインスタンスID一覧を抽出
new_instance_ids = instance_ids - checked_instance_ids
# CloudWatch側にあってインスタンス一覧にない削除対象のインスタンスID一覧を抽出
deleted_instance_ids = checked_instance_ids - instance_ids
# 監視追加対象のインスタンスID一覧が空でなければCloudWatchに追加していく
unless new_instance_ids.empty?
new_instance_ids.each do |instance_id|
# StageというKeyのタグで本番かそれ以外を分けている
stage = `aws --region #{region} ec2 describe-instances \
--instance-ids #{instance_id} \
--query 'Reservations[].Instances[].Tags[?Key==\`Stage\`].Value' \
--output text
`.chomp
# 本番の場合は通知先が違うのでSNSの向き先を変える
if stage == 'production'
sns_topic = 'PRODUCTION_SNS_TOPIC'
else
sns_topic = 'OTHER_SNS_TOPIC'
end
# MAIN: ここで設定を追加する
`aws --region #{region} cloudwatch put-metric-alarm \
--alarm-name "#{instance_id} StatusCheckFailed_Check" \
--metric-name StatusCheckFailed \
--namespace AWS/EC2 \
--statistic Maximum \
--dimensions Name=InstanceId,Value=#{instance_id} \
--period 60 \
--unit Count \
--evaluation-periods 1 \
--threshold 0 \
--comparison-operator GreaterThanThreshold \
--ok-actions #{sns_topic} \
--alarm-actions #{sns_topic} \
--insufficient-data-actions #{sns_topic}
`
puts "#{instance_id} StatusCheckFailed_Check is created"
end
end
# 削除対象のインスタンスID一覧が空でなければ設定を削除していく
unless deleted_instance_ids.empty?
deleted_instance_ids.each do |instance_id|
# MAIN: ここで設定を削除する
`aws --region #{region} cloudwatch delete-alarms \
--alarm-names "#{instance_id} StatusCheckFailed_Check"`
puts "#{instance_id} StatusCheckFailed_Check is deleted"
end
end
こんな感じでやってる。