Event Bridge SchedulerとTerraformでCloudWatch Alarmの監視除外期間をお手軽に実装する。
はじめに
皆様こんにちは、あかいけです。
CloudWatch Alarm で監視除外期間を設定したいと思ったことはありますか?
私はあります。
もしメトリクスデータがない場合でアラームが発生しないようにしたいのであれば、
CloudWatch Alarm で欠落データの処理を Missing (見つからない) か Not breaching (しきい値内) に設定しておけば事足りる場合が多いと思います。
ただアプリ側のメトリクスなどで欠落データもアラート (breaching:しきい値を超過) として扱いたい場合、
夜間停止などでインスタンスを停止した際もアラートが発生してしまいます。
このような場合にいわゆる監視除外期間が必要となりますが、
CloudWatch Alarm 単体だと実装できず、他の AWS サービスと組み合わせて実装する必要があります。
- 例 1. CloudWatch Metric Math を使った条件式
- 例 2. Lambda 関数での CloudWatch Alarm の有効 / 無効を切り替え
- 例 3. Event Bridge Scheduler での CloudWatch Alarm の有効 / 無効を切り替え
その中でも Event Bridge Scheduler による CloudWatch Alarm の有効 / 無効を切り替える方法は、
他の方法に比べて比較的簡単に実装できます。
とはいえ、一連の監視の流れを完成させるために以下リソースの作成が必要で、
設計してみると意外と考慮事項が多くてめんどくさいです…。
- CloudWatch Alarm
- SNS Topic
- SNS Subscription
- Event Bridge Scheduler
というわけで、Terraform でまとめて作成できるようにしてみました。
また記事内の module は Terraform Registry で公開しているので、お気軽にご利用ください。
構成
構成は以下の通りで、赤枠の中のリソースが作成対象です。
上記のイメージ図であれば、08:00 にアラームを有効化、20:00 にアラームを無効化します。
これにより 20:00 ~ 翌日 08:00 の間を擬似的に監視除外期間にできます。
使う方法
Terraform のルートモジュールで呼び出すだけです。
詳細は以下 README をご確認ください。
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
: スケジュール実行のタイムゾーン
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
: 通知先メールアドレスのリスト
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 の機能としていつか実装されたら嬉しいですね。