[AWS Step Functions] 名前のプレフィックスが一致するEventBridgeルールを一定期間有効化や無効化するステートマシンを作成してみた
一定期間EventBridgeルールを有効化もしくは無効化しておきたい
こんにちは、のんピ(@non____97)です。
皆さんは一定期間EventBridgeルールを有効化や無効化したいと思ったことはありますか? 私はあります。
例えばメンテナンスをしており、EventBridgeルールのターゲットが必ず失敗する場面では、ターゲットを実行したくないと考えると思います。そのような場合の対応方法として、EventBridgeルールを無効化することが挙げられます。
しかし、EventBridgeルールを手動で無効化すると、メンテナンス明けに有効化し忘れるリスクがあります。
そこで、名前のプレフィックスが一致するEventBridgeルールを一定期間有効化や無効化するステートマシンを作成して、楽したいと思います。
こちらのステートマシンはAWS CDKを使って、簡単にデプロイできるようにしています。こちらのコードのリポジトリは以下になります。
ステートマシンの構成
ステートマシンは以下の通り2つ用意しています。
- 複数のEventBridgeルールを有効化もしくは無効化をするステートマシン (
EnableOrDisableEventBridgeRulesStateMachine
) - 1.のステートマシンを実行するステートマシン (
ChangeStatusEventBridgeRulesStateMachine
)
「なんでステートマシンを2つ作成しているの?」と思われるかもしれません。これはEventBridgeルールの「有効化」、「無効化」と同じような処理を何度も定義しないようにするためです。
処理のパターンは以下の2パターンです。
- 一定期間EventBridgeルールを有効化 :
- EventBridgeルールを有効化するまで待機
- 複数のEventBridgeルールを有効化
- EventBridgeルールを無効化するまで待機
- 複数のEventBridgeルールを無効化
- 一定期間EventBridgeルールを無効化 :
- EventBridgeルールを無効化するまで待機
- 複数のEventBridgeルールを無効化
- EventBridgeルールを有効化するまで待機
- 複数のEventBridgeルールを有効化
以上の通り、同じような処理が繰り返されていることがわかります。
1つのステートマシンで愚直にこの処理を実装しようとすると、同じような処理を何度も定義する必要があります。そのため、以下のような処理を行うステートマシンを定義してあげます。
- EventBridgeルールを有効化もしくは無効化するまで待機
- 複数のEventBridgeルールを有効化もしくは無効化
図で表すと、以下のようになります。
こちらのステートマシンを呼び出す定義を以下2パターン分してあげます。
- 一定期間EventBridgeルールを有効化
- 複数のEventBridgeルールを有効化もしくは無効化をするステートマシンを呼び出す
- 複数のEventBridgeルールを有効化もしくは無効化をするステートマシンを呼び出す
- 一定期間EventBridgeルールを無効化
- 複数のEventBridgeルールを有効化もしくは無効化をするステートマシンを呼び出す
- 複数のEventBridgeルールを有効化もしくは無効化をするステートマシンを呼び出す
ステートマシンを呼び出す際は、有効化なのか無効化なのかを判断するパラメーターを渡してあげます。
図で表すと、以下のようになります。
ちなみに各ステートマシンの定義は以下の通りです。
{ "StartAt": "isTimestamp", "States": { "isTimestamp": { "Type": "Choice", "Choices": [ { "Variable": "$$.Execution.Input.WaitTime.isTimestamp", "BooleanEquals": true, "Next": "WaitTimestamp" } ], "Default": "WaitSeconds" }, "WaitSeconds": { "Type": "Wait", "SecondsPath": "$.WaitTime.Value", "Next": "ListRules" }, "ListRules": { "Next": "isEnableRules", "Type": "Task", "ResultPath": "$", "Resource": "arn:aws:states:::aws-sdk:eventbridge:listRules", "Parameters": { "NamePrefix.$": "$$.Execution.Input.EventBridgeRule.NamePrefix", "EventBusName.$": "$$.Execution.Input.EventBridgeRule.EventBusName" } }, "WaitTimestamp": { "Type": "Wait", "TimestampPath": "$.WaitTime.Value", "Next": "ListRules" }, "isEnableRules": { "Type": "Choice", "Choices": [ { "Variable": "$$.Execution.Input.isEnableRules", "BooleanEquals": true, "Next": "EnableRuleMap" } ], "Default": "DisableRuleMap" }, "DisableRuleMap": { "Type": "Map", "End": true, "Iterator": { "StartAt": "DisableRule", "States": { "DisableRule": { "End": true, "Type": "Task", "Resource": "arn:aws:states:::aws-sdk:eventbridge:disableRule", "Parameters": { "Name.$": "$.Name", "EventBusName.$": "$$.Execution.Input.EventBridgeRule.EventBusName" } } } }, "ItemsPath": "$.Rules" }, "EnableRuleMap": { "Type": "Map", "End": true, "Iterator": { "StartAt": "EnableRule", "States": { "EnableRule": { "End": true, "Type": "Task", "Resource": "arn:aws:states:::aws-sdk:eventbridge:enableRule", "Parameters": { "Name.$": "$.Name", "EventBusName.$": "$$.Execution.Input.EventBridgeRule.EventBusName" } } } }, "ItemsPath": "$.Rules" } } }
{ "StartAt": "isEnableToDisable", "States": { "isEnableToDisable": { "Type": "Choice", "Choices": [ { "Variable": "$$.Execution.Input.isEnableToDisable", "BooleanEquals": true, "Next": "StartExecutionStateMachineToEnableRules1" } ], "Default": "StartExecutionStateMachineToDisableRules1" }, "StartExecutionStateMachineToDisableRules1": { "Next": "StartExecutionStateMachineToEnableRules2", "Type": "Task", "Resource": "arn:aws:states:::states:startExecution.sync:2", "Parameters": { "Input": { "EventBridgeRule.$": "$$.Execution.Input.EventBridgeRule", "WaitTime.$": "$$.Execution.Input.DisableWaitTime", "isEnableRules": false }, "StateMachineArn": "arn:aws:states:us-east-1:<AWSアカウントID>:stateMachine:EnableOrDisableEventBridgeRulesStateMachine9A1900B2-Si0PdHxNfdDg" } }, "StartExecutionStateMachineToEnableRules2": { "End": true, "Type": "Task", "Resource": "arn:aws:states:::states:startExecution.sync:2", "Parameters": { "Input": { "EventBridgeRule.$": "$$.Execution.Input.EventBridgeRule", "WaitTime.$": "$$.Execution.Input.EnableWaitTime", "isEnableRules": true }, "StateMachineArn": "arn:aws:states:us-east-1:<AWSアカウントID>:stateMachine:EnableOrDisableEventBridgeRulesStateMachine9A1900B2-Si0PdHxNfdDg" } }, "StartExecutionStateMachineToEnableRules1": { "Next": "StartExecutionStateMachineToDisableRules2", "Type": "Task", "Resource": "arn:aws:states:::states:startExecution.sync:2", "Parameters": { "Input": { "EventBridgeRule.$": "$$.Execution.Input.EventBridgeRule", "WaitTime.$": "$$.Execution.Input.EnableWaitTime", "isEnableRules": true }, "StateMachineArn": "arn:aws:states:us-east-1:<AWSアカウントID>:stateMachine:EnableOrDisableEventBridgeRulesStateMachine9A1900B2-Si0PdHxNfdDg" } }, "StartExecutionStateMachineToDisableRules2": { "End": true, "Type": "Task", "Resource": "arn:aws:states:::states:startExecution.sync:2", "Parameters": { "Input": { "EventBridgeRule.$": "$$.Execution.Input.EventBridgeRule", "WaitTime.$": "$$.Execution.Input.DisableWaitTime", "isEnableRules": false }, "StateMachineArn": "arn:aws:states:us-east-1:<AWSアカウントID>:stateMachine:EnableOrDisableEventBridgeRulesStateMachine9A1900B2-Si0PdHxNfdDg" } } } }
やってみた
一定期間EventBridgeルールを有効化
それではステートマシンをnpx cdk deploy
でデプロイして、ステートマシンを実行してみます。
まずは、一定期間EventBridgeルールを有効化するパターンから試します。
ステートマシン実行前のEventBridgeルールは以下のような状態です。名前がStateMachineTest001-
から始まるEventBridgeルールを無効化しています。
以下パラメーターを入力してステートマシンを実行します。
{ "EnableWaitTime": { "Value": 5, // 5秒後にEventBridgeルールを有効化 "isTimestamp": false // タイムスタンプではなく秒数を指定 }, "DisableWaitTime": { "Value": 10, // 10秒後にEventBridgeルールを有効化 "isTimestamp": false // タイムスタンプではなく秒数を指定 }, "isEnableToDisable": true, // EventBridgeルールを有効化 -> 無効化の順番でステータスを変更 "EventBridgeRule": { "NamePrefix": "StateMachineTest001-", // 名前が "StateMachineTest001-" から始まるEventBridgeルール "EventBusName": "default" // EventBridgeルールが存在するEventBridge Bus } }
ステートマシンを実行して数秒待つと、名前がStateMachineTest001-
から始まるEventBridgeルールが有効化されました。
さらに数秒待つと、有効化されたEventBridgeルールが無効化されました。
ステートマシンのステータスを確認すると、実行ステータスが成功
になっていました。
意図した期間EventBridgeルールが有効化されていたか確認するために、AWS X-Rayのトレースマップを見てみます。トレースマップを見てみると、パラメーターで指定した通り、5秒待機した後にEventBridgeルールが有効化され、その10秒後に無効化されたことが確認できます。
一定期間EventBridgeルールを無効化
次に一定期間EventBridgeルールを無効化するパターンを試します。
ステートマシン実行前のEventBridgeルールは以下のような状態です。名前がStateMachineTest001-
から始まるEventBridgeルールを有効化しています。
以下パラメーターを入力してステートマシンを実行します。
{ "DisableWaitTime": { "Value": "2022-02-10T02:30:00Z", // 2022-02-10 02:30:00 (UTC) にEventBridgeルールを無効化 "isTimestamp": true // タイムスタンプを指定 }, "EnableWaitTime": { "Value": "2022-02-10T02:31:00Z", // 2022-02-10 02:31:00 (UTC) にEventBridgeルールを有効化 "isTimestamp": true // タイムスタンプを指定 }, "isEnableToDisable": false, // EventBridgeルールを無効化 -> 有効化の順番でステータスを変更 "EventBridgeRule": { "NamePrefix": "StateMachineTest001-", // 名前が "StateMachineTest001-" から始まるEventBridgeルール "EventBusName": "default" // EventBridgeルールが存在するEventBridge Bus } }
日本時間の11:30になると、名前がStateMachineTest001-
から始まるEventBridgeルールが有効化されました。また、日本時間の11:31になると、名前がStateMachineTest001-
から始まるEventBridgeルールが無効化されました。 (画面キャプチャは代わり映えしないので割愛します)
ステートマシンのステータスを確認すると、実行ステータスが成功
になっていました。
意図した期間EventBridgeルールが無効化されていたか確認するために、AWS X-Rayのトレースマップを見てみます。トレースマップを見てみると、パラメーターで指定した通り、しばらく待機した後にEventBridgeルールが無効化され、その約1分後に有効化されたことが確認できます。
AWS Step Functionsはやっぱり便利
名前のプレフィックスが一致するEventBridgeルールを一定期間有効化や無効化するステートマシンを作成してみました。
AWS Step Functionsを使えば、Lambdaも使わず簡単に実装できます。
なお、ステートマシンの最大実行時間は1年間です。そのため、こちらのステートマシンを使用して、1年以上有効化もしくは無効化しておきたい場合は、注意が必要です。
この記事が誰かの助けになれば幸いです。
以上、AWS事業本部 コンサルティング部の のんピ(@non____97)でした!