CloudWatchアラームに定時ダウンタイム設定をいれる


1. はじめに

  • あるEC2サーバで、毎日早朝に動くバッチのCPU使用率が高く、クリティカル通知で起こされるので、バッチの時間帯だけ CPU使用率クリティカル アラートの通知を止めたかった。
  • CloudWatch アラームにダウンタイム機能は提供されていないので、CloudWatch イベントと Lambda で自作する。
  • ここでいう「ダウンタイム設定」とは、何時から何時までの間はアラームアクションを無効にして、アラーム状態になっても通知を飛ばさないこと。

2. 概要

  • この自作ダウンタイム設定では、CloudWatchアラーム名に空白があると動かないので、空白がある場合はあらかじめ空白をなくした名前に変更しておく。
    • 例えば、「EC2 base CPU Utilization crit」を「EC2_base_CPU-Utilization_crit」 という感じにする。
  • CloudWatch アラームの有効/無効化は、次のアクションを利用する。
  • CloudWatch イベントで、決められた時間に指定したCloudWatchアラーム名のアラートアクションを有効/無効化する Lambda を実行する。この時、CloudWatch イベントから "CloudWatchアラーム名" と "有効/無効" の引数を Lambda へ渡す。

3. 設定

3.1. LambdaにアタッチするIAMロールを作成

  • IAMポリシー: cloudwatch-alarm-downtime
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "cloudwatch:EnableAlarmActions",
                "cloudwatch:DisableAlarmActions"
            ],
            "Resource": "*"
        }
    ]
}
  • IAMロール: cloudwatch-alarm-downtime

    • 信頼されたエンティティ
      • lambda.amazonaws.com
    • アタッチするポリシー
      • cloudwatch-alarm-downtime
      • AWSLambdaBasicExecutionRole (AWS 管理ポリシー)

3.2. Lambda作成

  • 関数名: cloudwatch-alarm-downtime
  • ランタイム: Python 3.7
  • 実行ロール: cloudwatch-alarm-downtime
  • 関数
import boto3
import logging
logger = logging.getLogger()
logger.setLevel(logging.INFO)
def lambda_handler(event, context):
    alarm_name=event['alarm_name']
    state=event['state']
    cloudwatch = boto3.client('cloudwatch')
    if state == 'enabled':
        cloudwatch.enable_alarm_actions (
            AlarmNames=[alarm_name]
        )
        logger.info(alarm_name)
        logger.info(state)
    elif state == 'disabled':
        cloudwatch.disable_alarm_actions(
            AlarmNames=[alarm_name]
        )
        logger.info(alarm_name)
        logger.info(state)

3.3. CloudWatchイベントルール設定

3.3.1. 日本時間 03:45に CloudWatch アラーム「EC2_base_CPU-Utilization_crit」のアラートアクションを無効にする

  • イベントソース設定
    Cron式: 10 11 * * ? * (03:45 JST)

  • ターゲット設定
    Lambda関数: CloudWatchAlarmDowntime
    定数(JSON テキスト): { "alarm_name": "EC2_base_CPU-Utilization_crit", "state": "disabled" }

  • ルールの定義
    名前: CWDowntime_EC2_base_CPU-Utilization_crit_disabled
    説明: (45 18 * * ? *) disabled

3.3.2. 日本時間 04:15に CloudWatch アラーム「EC2_base_CPU-Utilization_crit」のアラートアクションを有効にする

  • イベントソース設定
    Cron式: 15 19 * * ? * (04:15 JST)

  • ターゲット設定
    Lambda関数: CloudWatchAlarmDowntime
    定数(JSON テキスト): { "alarm_name": "EC2_base_CPU-Utilization_crit", "state": "enabled" }

  • ルールの定義
    名前: CWDowntime_EC2_base_CPU-Utilization_crit_enabled
    説明: (15 19 * * ? *) enabled

4. 確認

4.1. Lambda実行ログ

  • CloudWatch ロググループの 「/aws/lambda/cloudwatch-alarm-downtime」にログストリームが出力される。

4.2. CloudWatchアラーム 「EC2_base_CPU-Utilization_crit」 の履歴


2020-04-07 18:45:15 設定の更新 Alarm "EC2_base_CPU-Utilization_crit" updated
⇒CloudWatch アラームを無効にした

2020-04-07 18:53:00 状態の更新 OKからアラーム状態に更新したアラーム
⇒CPU使用率上昇で、スタータスが OK から アラーム に変更された。
 アラート通知は飛ばない。

2020-04-07 19:02:00 状態の更新 アラーム状態からOKに更新したアラーム
⇒CPU使用率上昇で、スタータスが アラーム から OK に変更された。
 アラート通知は飛ばない。

2020-04-07 19:15:14 設定の更新 Alarm "EC2_base_CPU-Utilization_crit" updated
⇒CloudWatch アラームを有効にした