CloudWatch AlarmのダウンタイムをLambda+EventBridgeで設定する
やりたいこと
CloudWatch Alarm Actionを毎日決まった時間に停止/再開したい。(ダウンタイムを設定したい)
検討した方法
CloudWatch Alarm自体にはダウンタイムを設定する機能がありません。
ググって以下の2通りの方法を見つけました。
- CloudWatch Metric Math 関数を利用 (参考: CloudWatch アラームのダウンタイム(特定期間の発報抑止)を Metric Math を使用して実現してみた)
- Lambda + CloudWatch Eventsを利用 (参考: CloudWatchAlarmにLambdaでダウンタイム設定をいれてみた)
1は余計なリソースを作成しなくてすむ方法ですが、指定時間のメトリクスを欠落させることになるため、今回の私の目的では2を採用しました。
やったことは2の記事とほぼ同じですが、以下の点は新規性ということで一応私の作業ログをインターネットの肥やしにします。先行資料があったらすみません。
- おそらく2の記事が書かれた頃(2020.10)からコマンドが変わっておりAWSのリファレンスと差異がある
- CloudWatch Eventsではなく後継であるAmazon EventBridgeを利用した
事前確認
初めにCLIで、無効化/有効化した際のステータス表示を確認しました。
参考: Command Reference
$ aws cloudwatch disable-alarm-actions --alarm-names "my_alarm_name"
$ aws cloudwatch describe-alarms --alarm-names "my_alarm_name"
{
"MetricAlarms": [
{
"AlarmName": "Smy_alarm_name",
:
"ActionsEnabled": false,
:
$ aws cloudwatch enable-alarm-actions --alarm-names "my_alarm_name"
$ aws cloudwatch describe-alarms --alarm-names "my_alarm_name"
{
"MetricAlarms": [
{
"AlarmName": "Smy_alarm_name",
:
"ActionsEnabled": true,
:
Lambda+EventBridgeでスケジューリング
完成図
EventBridgeでダウンタイムの開始(disable)/終了(enable)ルールをそれぞれ作成し、Lambda Functionを実行します。
enableに戻すのに失敗して気づかないままずっとdisableになってしまうとまずいので、失敗時にSNSに通知します。
Lambda Functionの作成
Python 3.8
import boto3
# Create CloudWatch client
cloudwatch = boto3.client('cloudwatch')
def lambda_handler(event, context):
# define param
alarm_action = event['alarm_action']
alarm_name = event['alarm_name']
# Actions
if alarm_action == 'enable':
cloudwatch.enable_alarm_actions(
AlarmNames=[(alarm_name)],
)
elif alarm_action == 'disable':
cloudwatch.disable_alarm_actions(
AlarmNames=[(alarm_name)],
)
以下でテストします。
{
"alarm_action": "disable",
"alarm_name": "my_alarm_name"
}
cloudwatch describe-alarmsコマンドと、念のためコンソールでも確認します。
うまくいきました。
{
"alarm_action": "enable",
"alarm_name": "my_alarm_name"
}
こちらも大丈夫そうです。
SNS設定
SNS Topicを作成してチャットに飛ばすようにしました。
IAMロール設定
Lambda実行用のIAMロールを以下のように設定するとともに対象のリソースを絞ります。
- CloudWatch:
- DisableAlarmActions
- EnableAlarmActions
- CloudWatch Logs:
- CreateLogGroup
- CreateLogStream
- PutLogEvents
- SNS:
- Publish
Amazon EventBridge
Amazon EventBridge でルールを作成します。
イベントスケジュールはcronで設定して、jsonでパラメータを入れます。
テスト
実行時間(cronで指定した時間)を適当に変えてイベントを発生させます。
うまくいきました。やったー
(Lambdaのテストパラメータにenable/disable以外の値を入れるなどして失敗させ、失敗時にSNSに通知されることも確認します。)
Discussion