CloudWatchAlarmをAWSCLIから設定する

# はじめに
新規の構築作業で大量のCloudWatchアラームを設定しなければいけないが、
GUIからポチポチなんてやっていられない&絶対抜け漏れが起きるのでCLIで一気に投入する方法を調査・検証した。
TerraformやCloudFormation等のIaCツールを利用してやるのがクラウド環境の構築という観点では良い手法だが、
プロジェクトの都合(S-in後はGUI管理前提)や期間、案件メンバーの兼ね合いで完全にはコード化できない状況は多々あると思われる。
そういった場合にAWS CLIでのコマンド操作なら構築手法として受け入れてもらい易いため、やってみようと思った次第。

# 環境
CloudShellからの実行を想定。記事作成時点のCloudShell上でのバージョンは以下の通り。
- AWS CLI:2.15.21
- jq:1.6(設定確認時に利用)

コマンドとは直接関係ないが、以下のような設計資料があり、この値からパラメータを拾って
設定用コマンドを出力することを想定している。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/561546/fd762312-cf69-b849-ce10-1e55331f2499.png)


# 設定コマンド
`aws cloudwatch put-metric-alarm`を利用すればCloudWatchAlarmを設定できる。

https://awscli.amazonaws.com/v2/documentation/api/latest/reference/cloudwatch/put-metric-alarm.html

オプションで指定する値をExcelの設定一覧から拾ってコマンドを生成してくれるExcelシートを作成すると素敵だと思います。
アラームの設定値で指定する各オプションのポイントを以下にピックアップ。

### --dimensions
`--metric-name`で指定するメトリクス名を特定できるディメンションをここに記載する。
`Name=<ディメンション名> Value=<値>`形式で指定する。**NameとValueの間は半角スペースであることに注意**。
カスタムメトリクス等でディメンションを複数指定する場合は、NameとValueのセットを","区切りで記載する。
例)`Name=<ディメンション名1> Value=<値1>,Name=<ディメンション名2> Value=<値2>`
ディメンションの区切りとなる","に**半角スペースを挟まない点に注意**。

### --comparison-operator
アラーム条件の定義。以下のいずれかを指定。
- GreaterThanOrEqualToThreshold: ≧閾値
- GreaterThanThreshold: > 閾値
- LessThanOrEqualToThreshold: ≦ 閾値
- LessThanThreshold: < 閾値

### --evaluation-periods, --datapoints-to-alarm
GUIの「アラームを実行するデータポイント」の部分。
[--datapoints-to-alarm] **/** [--evaluation-periods]
となる。

### --treat-missing-data
GUIの「欠落データの処理」の部分。以下のいずれかを指定。
- missing:見つかりませんとして処理(デフォルト)
- notBreaching:閾値内として処理
- breaching:閾値を超えているとして処理
- ignore:無視(現状のアラーム状態維持)

## コマンドサンプル
### 標準メトリクス(EC2 CPUUtilization)
```bash
aws cloudwatch put-metric-alarm \
--alarm-name "gp-alm-cpu-01" \
--alarm-description "cpu使用率80%超過" \
--metric-name "CPUUtilization" \
--namespace "AWS/EC2" \
--dimensions Name=InstanceId Value=i-xxxxxxxxxx \
--statistic "Average" \
--period 300 \
--threshold 80 \
--evaluation-periods 5 \
--datapoints-to-alarm 2 \
--comparison-operator GreaterThanOrEqualToThreshold \
--treat-missing-data missing \
--alarm-actions "arn:aws:sns:ap-northeast-1:xxxxxxxxxx"
```

### カスタムメトリクス(EC2プロセス監視)
```bash
aws cloudwatch put-metric-alarm \
--alarm-name "gp-alm-httpd-01" \
--alarm-description "プロセス監視 - httpd" \
--metric-name "procstat_lookup_pid_count" \
--namespace "CWAgent-MetricsData" \
--dimensions Name=InstanceId,Value=i-xxxxxxxxxx Name=exe,Value=httpd Name=pid_finder,Value=native \
--statistic "Maximum" \
--period 60 \
--threshold 1 \
--evaluation-periods 1 \
--datapoints-to-alarm 1 \
--comparison-operator LessThanThreshold \
--treat-missing-data breaching \
--alarm-actions "arn:aws:sns:ap-northeast-1:xxxxxxxxxx"
```

# アラーム設定確認
単体テストとしてパラメータ確認をやる場合もCLIでアラーム設定一覧を取得できると嬉しいので考えてみた。
`aws cloudwatch describe-alarms`を利用すればアラーム設定を取得できる。
`--alarm-names`オプションでアラーム名を指定すればそのアラームだけ出力。

https://awscli.amazonaws.com/v2/documentation/api/latest/reference/cloudwatch/describe-alarms.html

JSON形式で取得できるので、jqに渡して成形・出力する。

### コマンドサンプル
```bash
aws cloudwatch describe-alarms | \
jq -c '.MetricAlarms[] | [.AlarmName, .AlarmDescription, .AlarmActions[], .MetricName, .Namespace, .Statistic, .Period, .Dimensions[], .EvaluationPeriods, .DatapointsToAlarm, .Threshold, .ComparisonOperator, .TreatMissingData]'
```
抽出項目や並び順は必要に応じて変える。

### 実行結果サンプル
```bash
["gp-alm-cpu-01","cpu使用率80%超過","arn:aws:sns:ap-northeast-1:xxxxxxxxxx","CPUUtilization","AWS/EC2","Maximum",300,{"Name":"InstanceId","Value":"i-xxxxxxxxxx"},2,1,80.0,"GreaterThanOrEqualToThreshold","missing"]
["gp-alm-cpu-02","cpu使用率80%超過","arn:aws:sns:ap-northeast-1:xxxxxxxxxx","CPUUtilization","AWS/EC2","Maximum",300,{"Name":"InstanceId","Value":"i-xxxxxxxxxx"},2,1,80.0,"GreaterThanOrEqualToThreshold","missing"]
["gp-alm-httpd-01","プロセス監視 - httpd","arn:aws:sns:ap-northeast-1:xxxxxxxxxx","procstat_lookup_pid_count","CWAgent-MetricsData","Maximum",60,{"Name":"InstanceId","Value":"i-xxxxxxxxxx"},{"Name":"exe","Value":"httpd"},{"Name":"pid_finder","Value":"native"},1,1,1.0,"LessThanThreshold","breaching"]
["gp-alm-messages-01","messagesログ監視","arn:aws:sns:ap-northeast-1:xxxxxxxxxx","var/log/messages","LogMetrics","Maximum",60,1,1,0.0,"GreaterThanThreshold","notBreaching"]
```
この実行結果をExcelに貼り付け、区切り位置でセルに分けてお好みのやり方で設計書と比較する等すると良いと思います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/561546/6fe26df4-ec58-8e93-b15a-fe55c95309b2.png)

以上。

## 余談
コピペ等やり辛いのでCloudShellで流す前にPowershellでテストをやっていたが、jqに渡すと日本語(AlarmDescription部分)が文字化けする問題が発生して困った。今のところ解決していない。
```powershell:Powersehllでの実行結果
 aws cloudwatch describe-alarms | jq -c '.MetricAlarms[] | [.AlarmName, .AlarmDescription, .AlarmActions[], .MetricName, .Namespace, .Statistic, .Period, .Dimensions[], .EvaluationPeriods, .DatapointsToAlarm, .Threshold, .ComparisonOperator, .TreatMissingData]'
["gp-alm-cpu-01","cpu???80%??","arn:aws:sns:ap-northeast-1:(省略)]
```