CloudWatch Alarmアクションの無効をスケジューリングしてみた

CloudWatch Alarmのアクションは設定するとデフォルトで有効となります。マネジメントコンソールではアクションを無効にすることができないみたいなのでaws-cliで無効化をしてみました。
また、CloudWatchEventでスケジューリングも検証します。

# TL;DR

CloudWatchAlarmのアクションはaws-cliでなら無効化できます。
Lambda(Python)でもやってみました。
LambdaとCloudWatchEventでスケジューリングします。

# 対象読者 or 前提条件 or 環境

* ある一定の期間だけ監視による処理を無効化したい人
* AWS-CLI
* AWS SDK (Python - boto3)
* 2019/08/22時点の情報
* CloudWatchAlarmは設定済

# AWSマネジメントコンソールでの表記

CloudWatchのコンソール画面で、**アクションの有効/無効**を確認します。

最近、CloudWatchのコンソール画面のUIは新しいデザインに変更となりました。

* 旧コンソール
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/160365/7ae3e620-b0da-7b45-8bfa-67a73bfbfcdd.png)

[**アクションが有効になっています**]にチェックを入れ、確認します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/160365/1acacbf3-e63a-24dd-ac22-3fe540096b55.png)

* 新コンソール

新デザインの画面ではこのような感じです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/160365/273a531a-527a-f206-574b-e5633e79a0f9.png)

有効/無効の確認はコンソールではこのように確認できます。

# AWS-CLIで無効化

## CloudWatchアラームの表示

* アラーム一覧を表示してみます

```sh

aws cloudwatch describe-alarms
``` 

コマンドのオプションは次のとおり
>  describe-alarms
[--alarm-names <value>]
[--alarm-name-prefix <value>]
[--state-value <value>]
[--action-prefix <value>]
[--cli-input-json <value>]
[--starting-token <value>]
[--page-size <value>]
[--max-items <value>]
[--generate-cli-skeleton <value>]

この記事では`demo-alerm`というNameのアラームを以降対象とします。
※`alarm`のスペルが間違っているのはスルーしてください。('ω')

```sh

aws cloudwatch describe-alarms --alarm-names demo-alerm
```
```json

{
    "MetricAlarms": [
        {
            "AlarmName": "demo-alerm",
            "AlarmArn": "arn:aws:cloudwatch:ap-northeast-1:************:alarm:demo-alerm",
            "AlarmDescription": "demo",
            "AlarmConfigurationUpdatedTimestamp": "2019-08-22T01:24:19.696Z",
            "ActionsEnabled": true,
            "OKActions": [],
            "AlarmActions": [
                "arn:aws:sns:ap-northeast-1:************:test"
            ],
            "InsufficientDataActions": [],
            "StateValue": "INSUFFICIENT_DATA",
            "StateReason": "Insufficient Data: 1 datapoint was unknown.",
            "StateReasonData": "{\"version\":\"1.0\",\"queryDate\":\"2019-08-05T13:11:02.108+0000\",\"statistic\":\"Average\",\"period\":300,\"recentDatapoints\":[],\"threshold\":90.0}",
            "StateUpdatedTimestamp": "2019-08-05T13:11:02.112Z",
            "MetricName": "CPUUtilization",
            "Namespace": "AWS/EC2",
            "Statistic": "Average",
            "Dimensions": [
                {
                    "Name": "InstanceId",
                    "Value": "i-*****************"
                }
            ],
            "Period": 300,
            "EvaluationPeriods": 1,
            "DatapointsToAlarm": 1,
            "Threshold": 90.0,
            "ComparisonOperator": "GreaterThanThreshold",
            "TreatMissingData": "missing"
        }
    ]
}
```

`"ActionsEnabled": true`になっているのが確認できました。

これをfalseに変更します。

## アクションの無効化

`disable-alarm-actions`を使用します。
オプションは次のとおり。
> disable-alarm-actions
--alarm-names <value>
[--cli-input-json <value>]
[--generate-cli-skeleton <value>]

```sh
aws cloudwatch disable-alarm-actions --alarm-names demo-alerm
```

確認してみます。

```json
{
    "MetricAlarms": [
        {
            "AlarmName": "demo-alerm",
            "AlarmArn": "arn:aws:cloudwatch:ap-northeast-1:************:alarm:demo-alerm",
            "AlarmDescription": "demo",
            "AlarmConfigurationUpdatedTimestamp": "2019-08-22T02:15:26.395Z",
            "ActionsEnabled": false,
            "OKActions": [],
            "AlarmActions": [
                "arn:aws:sns:ap-northeast-1:************:test"
            ],
            "InsufficientDataActions": [],
            "StateValue": "INSUFFICIENT_DATA",
            "StateReason": "Insufficient Data: 1 datapoint was unknown.",
            "StateReasonData": "{\"version\":\"1.0\",\"queryDate\":\"2019-08-05T13:11:02.108+0000\",\"statistic\":\"Average\",\"period\":300,\"recentDatapoints\":[],\"threshold\":90.0}",
            "StateUpdatedTimestamp": "2019-08-05T13:11:02.112Z",
            "MetricName": "CPUUtilization",
            "Namespace": "AWS/EC2",
            "Statistic": "Average",
            "Dimensions": [
                {
                    "Name": "InstanceId",
                    "Value": "i-*****************"
                }
            ],
            "Period": 300,
            "EvaluationPeriods": 1,
            "DatapointsToAlarm": 1,
            "Threshold": 90.0,
            "ComparisonOperator": "GreaterThanThreshold",
            "TreatMissingData": "missing"
        }
    ]
}
```

`"ActionsEnabled": false` falseに変更されました。

コンソールを確認してみましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/160365/645073ca-8a19-ac23-0f99-afb288ea8836.png)

無効になっていることが確認できました。

## アクションの有効化

有効にするには、`enable-alarm-actions`を使用します。

```sh
aws cloudwatch enable-alarm-actions --alarm-names demo-alerm
```

同様にオプションは次のとおり。
> enable-alarm-actions
--alarm-names <value>
[--cli-input-json <value>]
[--generate-cli-skeleton <value>]

確認をして`"ActionsEnabled": true`,画面では`有効`になっていればOKです。


# AWS SDK (Python boto3)でアラームを無効化（Lambda)

AWS-CLIでやったことをAWS-SDK(Python-boto3)でやってみます。


## CloudWatchアラームの表示

boto3 でアラームを表示してみます。
※json形式をコマンドラインに見やすく表示するためにpprintを使用しています。

ソースコードは次のとおり。

```python
import boto3
from pprint import pprint

client = boto3.client('cloudwatch')
response = client.describe_alarms(AlarmNames=['demo-alerm']) 
pprint(response)
```

## アクションの無効化

CloudWatchAlarmのアクションを無効化します。
ソースコードは次のとおり。

```python
import boto3
from pprint import pprint

def show_cloudwatch_alarm():
    client = boto3.client('cloudwatch')
    response = client.describe_alarms(AlarmNames=['demo-alerm']) 
    pprint(response)

cloudwatch = boto3.resource('cloudwatch')
alarm = cloudwatch.Alarm('demo-alerm')

#alarm.enable_actions()
alarm.disable_actions()

show_cloudwatch_alarm()
```

`'ActionsEnabled': False`となっていればOKです。


## アクションの有効化
CloudWatchAlarmのアクションを有効化します。
ソースコードは次のとおり。

```python
import boto3
from pprint import pprint

def show_cloudwatch_alarm():
    client = boto3.client('cloudwatch')
    response = client.describe_alarms(AlarmNames=['demo-alerm']) 
    pprint(response)

cloudwatch = boto3.resource('cloudwatch')
alarm = cloudwatch.Alarm('demo-alerm')

alarm.enable_actions()
#alarm.disable_actions()

show_cloudwatch_alarm()
```

`'ActionsEnabled': True`となっていればOKです。

# LambdaとCloudWatchEventで無効化をスケジューリングする

細かい設定はこの記事では割愛します。

## Lambdaを準備する

IAMロールには`CloudWatchFullAccess`を使用しました。

テストイベントは次の２つを用意し対応させています。

テストイベント①

```json
{
  "param": "enable"
}
```
テストイベント②

```json
{
  "param": "disable"
}
```
ソースコード

```python
import boto3
from pprint import pprint

def show_cloudwatch_alarm():
    client = boto3.client('cloudwatch')
    response = client.describe_alarms(AlarmNames=['demo-alerm']) 
    pprint(response)

def lambda_handler(event, context):
    
    cloudwatch = boto3.resource('cloudwatch')
    alarm = cloudwatch.Alarm('demo-alerm')
    
    param = event['param']
    if(param == 'enable'):
        alarm.enable_actions()
    elif(param == 'disable'):
        alarm.disable_actions()
    else:
        print('パラメータが正しく設定されていません。')
        
    show_cloudwatch_alarm()
 
```

## CloudWatchEventでLambdaをスケジューリングする

Lambda関数の名前は`CloudWatchAlarmActionManager`としました。

無効化する場合には、次の図のように`{ "param": "disable" }`と入力します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/160365/4bfcd97b-5ca7-bbbc-da95-8f14a74b8ee2.png)

有効化する場合には、`{ "param": "enable" }`とします。


## result

５分後に設定し、無事無効化できました。

# 参考

* [AWS CLI Docs (cloudwatch)](https://docs.aws.amazon.com/cli/latest/reference/cloudwatch/index.html)
* [Boto 3 Docs (cloudwatch)]([https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/cloudwatch.html](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/cloudwatch.html))

# あとがき

これで、任意のタイミングで通知やその他の監視によるトリガーのアクションを無効にしておくことができるようになりました。

記事を作成した後に検索してみたら、既に情報は出回ってました。('ω')
下記に一部取り上げておきます。ご参考までにどうぞ。

* [運用作業を行うのでCloudWatchのアラーム設定を無効化させたい](https://dev.classmethod.jp/cloud/ops-cloudwatch-alarm-invalidation/)
* [AWS CLIでCloudWatchのアラームを制御する](http://ubw.hatenablog.com/entry/2016/11/23/193111)