Event Bridge SchedulerとTerraformでCloudWatch Alarmの監視除外期間をお手軽に実装する。

Event Bridge SchedulerとTerraformでCloudWatch Alarmの監視除外期間をお手軽に実装する。

Clock Icon2025.07.13

はじめに

皆様こんにちは、あかいけです。

CloudWatch Alarm で監視除外期間を設定したいと思ったことはありますか?
私はあります。

もしメトリクスデータがない場合でアラームが発生しないようにしたいのであれば、
CloudWatch Alarm で欠落データの処理を Missing (見つからない) か Not breaching (しきい値内) に設定しておけば事足りる場合が多いと思います。

https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/monitoring/AlarmThatSendsEmail.html#alarms-and-missing-data

ただアプリ側のメトリクスなどで欠落データもアラート (breaching:しきい値を超過) として扱いたい場合、
夜間停止などでインスタンスを停止した際もアラートが発生してしまいます。

このような場合にいわゆる監視除外期間が必要となりますが、
CloudWatch Alarm 単体だと実装できず、他の AWS サービスと組み合わせて実装する必要があります。

  • 例 1. CloudWatch Metric Math を使った条件式
  • 例 2. Lambda 関数での CloudWatch Alarm の有効 / 無効を切り替え
  • 例 3. Event Bridge Scheduler での CloudWatch Alarm の有効 / 無効を切り替え

その中でも Event Bridge Scheduler による CloudWatch Alarm の有効 / 無効を切り替える方法は、
他の方法に比べて比較的簡単に実装できます。

https://dev.classmethod.jp/articles/deisable-and-enable-cloudwatch-alarm-actions-amazon-eventbridge-scheduler/

とはいえ、一連の監視の流れを完成させるために以下リソースの作成が必要で、
設計してみると意外と考慮事項が多くてめんどくさいです…。

  • CloudWatch Alarm
  • SNS Topic
  • SNS Subscription
  • Event Bridge Scheduler

というわけで、Terraform でまとめて作成できるようにしてみました。
また記事内の module は Terraform Registry で公開しているので、お気軽にご利用ください。

https://registry.terraform.io/modules/Lamaglama39/alarm-scheduler/aws/latest

構成

構成は以下の通りで、赤枠の中のリソースが作成対象です。

image.drawio

上記のイメージ図であれば、08:00 にアラームを有効化、20:00 にアラームを無効化します。
これにより 20:00 ~ 翌日 08:00 の間を擬似的に監視除外期間にできます。

使う方法

Terraform のルートモジュールで呼び出すだけです。
詳細は以下 README をご確認ください。

https://registry.terraform.io/modules/Lamaglama39/alarm-scheduler/aws/latest

main.tf
module "alarm_scheduler" {
  source  = "Lamaglama39/alarm-scheduler/aws"
  version = "0.1.0"
}

使用例

(1).Event Bridge Scheduler だけ実装したい場合

既存の CloudWatch Alarm に監視除外期間を設定したい場合です。
指定するパラメータは以下の通りで、複数のアラームを一括で指定できます。

パラメータ詳細:

  • existing_alarm_names: 監視除外期間を設定したい既存のCloudWatch Alarm名のリスト
  • disable_schedule_expression: アラームを無効化するスケジュール(cron形式)
  • enable_schedule_expression: アラームを有効化するスケジュール(cron形式)
  • schedule_timezone: スケジュール実行のタイムゾーン
main.tf
terraform {
  required_version = ">= 1.0"
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = ">= 6.0"
    }
  }
}

provider "aws" {
  region = "ap-northeast-1"
}

module "alarm_scheduler" {
  source  = "Lamaglama39/alarm-scheduler/aws"
  version = "0.1.0"

  name = "app-name"

  existing_alarm_names = [
    "dev-alarm-1",
    "dev-alarm-2",
    "dev-alarm-3",
  ]

  disable_schedule_expression = "cron(0 22 * * ? *)"
  enable_schedule_expression  = "cron(0 6 * * ? *)"
  schedule_timezone           = "Asia/Tokyo"

  tags = {
    Environment = "dev"
    Project     = "alarm-scheduler"
  }
}

(2).CloudWatch Alarm と SNS も実装したい場合

次は CloudWatch Alarm と SNS もまとめて作成する場合です。
CloudWatch Alarm は複数作成可能で、SNS トピックは共通のものを利用しています。
また通知先のメールアドレス(SNS サブスクリプション)も複数作成可能です。

パラメータ詳細:

  • create_alarms: CloudWatch Alarmを作成するかのフラグ(true/false)
  • alarms: 作成するアラームの設定(mapオブジェクト)
  • create_sns_topic: SNSトピックを作成するかのフラグ(true/false)
  • sns_topic_name: 作成するSNSトピック名
  • sns_display_name: SNSトピックの表示名
  • sns_email_addresses: 通知先メールアドレスのリスト
main.tf
terraform {
  required_version = ">= 1.0"
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = ">= 6.0"
    }
  }
}

provider "aws" {
  region = "ap-northeast-1"
}

module "alarm_scheduler" {
  source  = "Lamaglama39/alarm-scheduler/aws"
  version = "0.1.0"

  name = "app-name"

  create_alarms = true
  alarms = {
    "ec2-cpu-high" = {
      alarm_description   = "High CPU utilization on EC2 instance"
      comparison_operator = "GreaterThanThreshold"
      evaluation_periods  = 5
      metric_name         = "CPUUtilization"
      namespace           = "AWS/EC2"
      period              = 60
      statistic           = "Average"
      threshold           = 80
      dimensions = {
        InstanceId = "i-XXXXXXXXXXXXXXXXX"
      }
      treat_missing_data = "missing"
    }
  }

  create_sns_topic = true
  sns_topic_name   = "alarm-notifications"
  sns_display_name = "Alarm Notifications"
  sns_email_addresses = [
    "example_1@example.com",
    "example_2@example.com"
  ]

  disable_schedule_expression = "cron(0 22 * * ? *)"
  enable_schedule_expression  = "cron(0 6 * * ? *)"
  schedule_timezone           = "Asia/Tokyo"

  tags = {
    Environment = "dev"
    Project     = "alarm-scheduler"
  }
}

さいごに

以上、Event Bridge Scheduler と Terraform で CloudWatch Alarm の監視除外期間をお手軽に実装する方法でした。
紹介したmoduleはTerraform Registryで公開しているため、お気軽にご利用ください。

今回のようにユーザー側で工夫して実装するのもいいですが、この機能は利用したいケースが多いと思うので、CloudWatch Alarm の機能としていつか実装されたら嬉しいですね。

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.