特定の時間だけCloudWatchアラームを OFFにして、通知を抑制しようとしています。 抑制の仕組みは、今では EventBridgeスケジューラー を使えば比較的簡単に実装できます。 以下ブログです。
▲ 上記ブログより画像を引用
本ブログはこの仕組みをCloudFormationテンプレート化してみます。 複数プロジェクトのCWアラーム群を効率よく制御したいのが テンプレート化のモチベーションです。
CloudFormationテンプレートを書いた
早速ですがテンプレートを書きました。
AWSTemplateFormatVersion: 2010-09-09
Transform: AWS::LanguageExtensions
Parameters:
Project:
Type: String
ScheduleExpressionOFF:
Type: String
ScheduleExpressionON:
Type: String
AlarmNames:
Type: CommaDelimitedList
Resources:
# EventBridge Scheduler (Disable CloudWatch Alarms)
ScheduleCWAlarmOFF:
Type: AWS::Scheduler::Schedule
Properties:
Name: !Sub "${Project}-cwalarm-off"
Description: !Sub "Disable ${Project} CloudWatch Alarms"
ScheduleExpression: !Ref ScheduleExpressionOFF
ScheduleExpressionTimezone: "Japan"
FlexibleTimeWindow:
Mode: "OFF"
State: ENABLED
Target:
Arn: arn:aws:scheduler:::aws-sdk:cloudwatch:disableAlarmActions
Input:
Fn::ToJsonString:
AlarmNames: !Ref AlarmNames
RoleArn: !GetAtt "SchedulerRole.Arn"
# EventBridge Scheduler (Enable CloudWatch Alarms)
ScheduleCWAlarmON:
Type: AWS::Scheduler::Schedule
Properties:
Name: !Sub "${Project}-cwalarm-on"
Description: !Sub "Enable ${Project} CloudWatch Alarms"
ScheduleExpression: !Ref ScheduleExpressionON
ScheduleExpressionTimezone: "Japan"
FlexibleTimeWindow:
Mode: "OFF"
State: ENABLED
Target:
Arn: arn:aws:scheduler:::aws-sdk:cloudwatch:enableAlarmActions
Input:
Fn::ToJsonString:
AlarmNames: !Ref AlarmNames
RoleArn: !GetAtt "SchedulerRole.Arn"
# Role for EventBridge Scheduler
SchedulerRole:
Type: AWS::IAM::Role
Properties:
RoleName: !Sub "${Project}-scheduler-role-for-cwalarm"
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service:
- scheduler.amazonaws.com
Action:
- sts:AssumeRole
Path: "/"
Policies:
- PolicyName: CloudWatchAlarmONOFF
PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Action:
- cloudwatch:DisableAlarmActions
- cloudwatch:EnableAlarmActions
Resource:
- "*"
指定するパラメータ(Parameters)
以下 4つのパラメータを指定します。
- Project : プロジェクト名。スケジュール名のプレフィクスになります
- ScheduleExpressionOFF : アラームを無効化させたい時刻の cron です
- ScheduleExpressionON : アラームを有効化させたい時刻の cron です
- AlarmNames : 対象のアラーム群です (カンマ区切り)
作られるリソース(Resources)
以下 3リソースが作られます。
- ScheduleCWAlarmOFF : 指定した時刻(ScheduleExpressionON)に 指定したCWアラーム(AlarmNames) を無効化する EventBridgeスケジューラ
- ScheduleCWAlarmON : 指定した時刻(ScheduleExpressionON)に 指定したCWアラーム(AlarmNames) を有効化する EventBridgeスケジューラ
- SchedulerRole : 上記 2つの EventBridgeスケジューラで使われるIAMロール
展開してみる
事前に 2つのCWアラームを用意しました (ec2-aaa-status-check-alarm,ec2-bbb-status-check-alarm)。 これらを定期的にON,OFFする仕組みを展開します。
CLIで展開
CloudShellから AWS CLI でテンプレートを展開します。 template_body に 先程のCFnテンプレートyamlを指定します。
### スタック展開の各種パラメータ
stack_name="example-cwalarms-on-off-schedule"
template_body="./example/template.yaml"
project="example"
cron_off="cron(20 09 * * ? *)"
cron_on="cron(25 09 * * ? *)"
alarm_names="ec2-aaa-status-check-alarm,ec2-bbb-status-check-alarm"
### スタック展開
aws cloudformation create-stack \
--stack-name "${stack_name}" \
--template-body "file://${template_body}" \
--parameters \
"[
{\"ParameterKey\": \"Project\", \"ParameterValue\": \"${project}\"} ,
{\"ParameterKey\": \"ScheduleExpressionOFF\", \"ParameterValue\": \"${cron_off}\"} ,
{\"ParameterKey\": \"ScheduleExpressionON\", \"ParameterValue\": \"${cron_on}\"} ,
{\"ParameterKey\": \"AlarmNames\", \"ParameterValue\": \"${alarm_names}\"}
]" \
--capabilities CAPABILITY_NAMED_IAM CAPABILITY_AUTO_EXPAND
このパラメータで作られるリソースは以下のとおりです。 (検証のために off にしている時間を 5分間にしています)
- example-cwalarm-off : 毎日 09:20 に CWアラーム(ec2-aaa-status-check-alarm,ec2-bbb-status-check-alarm)を 無効化するEventBridgeスケジューラ
- example-cwalarm-on : 毎日 09:25 に CWアラーム(ec2-aaa-status-check-alarm,ec2-bbb-status-check-alarm)を 有効化するEventBridgeスケジューラ
- example-scheduler-role-for-cwalarm : 上記 2つの EventBridgeスケジューラで使われるIAMロール
展開後の確認
以下のように、期間中にアクションが無効化されていることを確認できました。
おわりに
以上、CWアラームのON,OFFをスケジュールする仕組みをCFnテンプレート化してみました。
内容自体は すでにあるブログ の二番煎じですが、 「沢山のスケジュールを展開したい!」といったときに役に立てば幸いです。