【AWS】CloudWatch Alarmをシェルスクリプトで一括設定

【AWS】CloudWatch Alarmをシェルスクリプトで一括設定

インターステラの阿形です。

CloudWatchのアラームの設定を、既にあるEC2インスタンス全部に一括設定する機会があったので、簡単なシェルスクリプトで処理してみました。
AWSのCLIツールの出力をフィルタするのに慣れていないと意外と手間取るので、参考になれば。

前提条件

当然ですが、awsコマンドがインストールされ、アクセスキーなどの設定も完了している前提で進めます。
あと、CloudWatchのアラームを通知するのにSNSを使用しますので、SNSのTopicの設定が完了している前提とします。

スクリプト

かなりやっつけですが、こんな感じのスクリプトを作りました。

#!/bin/bash

TEMP="./temp.txt"
ARN="arn:aws:sns:ap-northeast-1:01234567890:sns-topic"

# インスタンスIDの取得
aws ec2 describe-tags 
    --filter "Name=resource-type,Values=instance" 
             "Name=value,Values=*PRODUCTION*" 
    --query "Tags[*].[Value,ResourceId]" 
    --output text |tr 't' ','>${TEMP}

# 取得したインスタンスIDを元に逐次処理
while read LINE
do
    # インスタンス名とIDを切り出し
    NAME=`echo ${LINE}|cut -d ',' -f 1`
    ID=`echo ${LINE}|cut -d ',' -f 2`
    
    # CPUUtilizationのアラームを設定
    aws cloudwatch put-metric-alarm 
        --alarm-name "AOS-${NAME}-CPUUtilization" 
        --namespace AWS/EC2 
        --metric-name CPUUtilization 
        --dimensions "Name=InstanceId,Value=${ID}" 
        --period 300 
        --statistic Average 
        --threshold 80 
        --comparison-operator GreaterThanOrEqualToThreshold 
        --evaluation-periods 1 --alarm-actions ${ARN}
done <${TEMP}

インスタンスIDの取得

今回、インスタンス名のタグに「PRODUCTION」と入っているインスタンスだけ抽出して設定したかったので、awsコマンドのフィルタを

--filter "Name=resource-type,Values=instance" 
         "Name=value,Values=*PRODUCTION*" 

と設定しています。
Name=resource-type,Value=instanceは、タグの中からResource-TypeがInstanceのものだけをフィルタしています。
指定がキャメルケースではないのがハマりやすいので注意ですね。自分もしょっちゅう間違えます。

出力は–queryを使用して、ValueとResourceIdのみにしています。

    --query "Tags[*].[Value,ResourceId]" 

またフォーマットはjsonではなく、textを指定しています。

    --output text |tr 't' ','>${TEMP}

シェルスクリプトだとjson扱いにくいのでね…。
trでタブをカンマに変換して、最後に出力結果をテンポラリファイルに保存しています。
そのまま保存してもいいんですが、あとでなんか使うかなーと思ったのでやりましたが、まあこのへんは適当にいじってください。

取得したインスタンスIDで逐次処理

あとはwhileに保存したテンポラリファイルを読むようにして処理していくだけです。
インスタンス名をアラーム名に使うのでIDと共にそれぞれ変数に読み込んでいます。

    NAME=`echo ${LINE}|cut -d ',' -f 1`
    ID=`echo ${LINE}|cut -d ',' -f 2`

最後に再びawsコマンドでCloudWatchの設定を行っています。

    aws cloudwatch put-metric-alarm 
        --alarm-name "AOS-${NAME}-CPUUtilization" 
        --namespace AWS/EC2 
        --metric-name CPUUtilization 
        --dimensions "Name=InstanceId,Value=${ID}" 
        --period 300 
        --statistic Average 
        --threshold 80 
        --comparison-operator GreaterThanOrEqualToThreshold 
        --evaluation-periods 1 --alarm-actions ${ARN}

パラメータ多くて面倒ですが、見れば何となく分かるかと思います。

まとめ

AWS CLIを使ってシェルスクリプトでCloudWatchの一括設定をやってみました。
やっぱりこうやって自動化すると間違いがなくていいですね。
まーそもそもCloudWatchの設定も、最初からインスタンスの起動スクリプトに組み込むとかしたほうがいいと思いますけどね。
今回は簡単な内容だったのでシェルスクリプトでさくっとやりましたが、もっと凝ったことをやるならPythonとかで書いたほうがいいかもしれません。

タイトル

本文