【小ネタ】CloudWatchアラーム群を定期的にON, OFFする仕組みをCloudFormationテンプレートで作成する

2023.12.23

特定の時間だけCloudWatchアラームを OFFにして、通知を抑制しようとしています。 抑制の仕組みは、今では EventBridgeスケジューラー を使えば比較的簡単に実装できます。 以下ブログです。

img

▲ 上記ブログより画像を引用

本ブログはこの仕組みを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する仕組みを展開します。

img

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ロール

展開後の確認

以下のように、期間中にアクションが無効化されていることを確認できました。

img

img

おわりに

以上、CWアラームのON,OFFをスケジュールする仕組みをCFnテンプレート化してみました。

内容自体は すでにあるブログ の二番煎じですが、 「沢山のスケジュールを展開したい!」といったときに役に立てば幸いです。

参考