AWS CLIでCloudWatchのカスタムメトリックスとそのアラート設定


参考にしたページ

EC2の起動時・停止時に処理を実行する方法 
http://www.infoscoop.org/blogjp/2014/06/04/ec2-boot-stop-shell/

AWSのCloudWatchでカスタムメトリックスを使用する
http://d.hatena.ne.jp/ke-16/20130311/1363025895

##AWS CLIのインストール
`pip install awscli` でインストールするにはPython 2.6以降が必要だそうなので確認してください。
またpython-pipパッケージのインストールはEPELリポジトリが必要です。


```bash
yum install python-pip
pip install awscli
```

##AWS CLIの設定
`aws configure`で設定するのが通常なのですが、chefとかで管理した場合どうやるのかわからなかったので、ファイルに書いて、それを読み込む形で使ってます。

```bash:/path/to/config
[default]
aws_access_key_id=****
aws_secret_access_key=*****
region=ap-northeast-1
```

こんな感じの設定ファイルを用意して、、
使う時はシェルスクリプト内で読み込みます。

```bash
#!/bin/sh
export AWS_CONFIG_FILE=/path/to/config
```

##CloudWatchカスタムメトリクスの作成

ローカルIPのhttpに接続してステータスコードが200以外なら、Valueを1として通知。

```bash:http_status_check.sh
#!/bin/sh

export AWS_CONFIG_FILE=/root/aws/config
EC2_INSTANCE_ID=$(curl -s http://169.254.169.254/latest/meta-data/instance-id)
URI=`curl -s http://169.254.169.254/latest/meta-data/local-ipv4`

# http status check
status=`curl -s http://${URI} -o /dev/null -w "%{http_code}"`
if [ ${status} -eq 200 ]; then
Fail=0
else
Fail=1
fi

aws cloudwatch put-metric-data \
--metric-name "HttpStatusfail" \
--namespace "Custom Metrix" \
--dimensions "InstanceId=$EC2_INSTANCE_ID" \
--value "$Fail" \
--unit "Count"
```

このファイルをcronに設定

```
*/5 * * * * root /root/aws/aws_status_check.sh
```

この状態でAWS CloudWatchの管理画面でデータが取れてる。

##CloudWatchカスタムメトリクスのアラート設定

(参考)EC2の起動時・停止時に処理を実行する方法
http://www.infoscoop.org/blogjp/2014/06/04/ec2-boot-stop-shell/

こちらのブログを参考にインスタンス起動時にアラートを設定、インスタンス終了時にアラート設定を削除するようにしました。


```bash:/etc/init.d/cloudwatch_alart
#!/bin/bash
# chkconfig: 2345 99 10
# description: Create & Delete CloudWatch Alarm

export AWS_CONFIG_FILE=/path/to/config

EC2_INSTANCE_ID=$(curl -s http://169.254.169.254/latest/meta-data/instance-id)
prog=cloudwatch_alarm
lock=/var/lock/subsys/$prog

case "$1" in
  start)

      #HTTP STATUS CHECK
      aws cloudwatch put-metric-alarm \
      --alarm-name HttpStatusCheck-for-$EC2_INSTANCE_ID \
      --alarm-description "Alarm when HttpStatusCheck has a value of one for two periods" \
      --metric-name HttpStatusfail \
      --namespace "Custom Metrix" \
      --statistic Maximum \
      --dimensions Name=InstanceId,Value=$EC2_INSTANCE_ID \
      --period 300 \
      --unit Count \
      --evaluation-periods 2 \
      --threshold 1 \
      --comparison-operator GreaterThanOrEqualToThreshold \
      --alarm-actions arn:aws:sns:ap-northeast-1:**** \
      --insufficient-data-actions arn:aws:sns:ap-northeast-1:****

      touch $lock
      ;;
  stop)
      aws cloudwatch delete-alarms --alarm-names HttpStatusCheck-for-$EC2_INSTANCE_ID

      rm -f $lock
      ;;
  restart)
      ;;
  *)
      echo $"Usage: $0 {start|stop}"
      exit 2
esac

exit
```

サービスに追加したり自動起動設定としたりする

```
chmod 755 /etc/init.d/cloudwatch_alarm
chkconfig --add cloudwatch_alarm
chkconfig cloudwatch_alarm　on
```

##以下はまったところ

###GreaterThanThreshold にしててエラーにならなかった

今回、200のステータスコード以外であれば「1」が記録される設定なので`comparison-operator`は`GreaterThanOrEqualToThreshol`とします。

`comparison-operator`にどんな設定ができるのかドキュメントで見つからなかったのですが
http://exploreaws.doorblog.jp/archives/24701093.html
のブログに詳細が書かれていたので助かりました。

###namespaceが"AWS/EC2"になっててアラートがinsufficient dataになってた
`namespace`はカスタムメトリックスなので作成した時に指定したnamespaceと同じ `"Custom Metrix"`を指定します。"AWS/EC2"にしててステータスがinsufficient dataのままではまりました。

###insufficient dataもアラート扱いにする
Error時にアラート発信は当然なのですが、データが取得できない時の「insufficient data」時もアラートを発信するようにします。

###不明点
CloudWatchのアラートってアラート状態である限りアラートを発信し続けてくれる設定にできないのかな。