はじめに
定期的な処理をAmazon EventBridge Ruleを使って実行していましたが、スケジューリング機能がAWS EventBridge Schedulerとして登場してきました。今後はどんどんAmazon EventBridge Schedulerを使っていくと思うので、こっちを使うように進めています。
やりたいこと
定期処理をAmazon EventBridge Schedulerとして定義し、コストを最小にするためにEC2が起動している間は定期処理を実行、停止している間は定期処理を停止したいです。定期処理=Lambdaで一定間隔で同期処理を行う等。
今回は人の手を介さず、自動でAmazon EventBridge Schedulerの有効化、無効化を行います。(EC2の状態に連動する部分は別途、記事を書こうかと思います。)
AWSマネジメントコンソールでの有効化、無効化
AWSマネジメントコンソールだとどんな感じになるでしょう・・・
スケジュール有効化
対象のスケジュールを選択し、右上の「有効化」をクリックすることで有効化されます。
スケジュール無効化
有効化と同様に対象のスケジュールを選択し、右上の「無効化」をクリックすることで無効化されます。
すごく簡単にできますね。じゃあ、なんか簡単にできそうな気がしてきます。
APIの確認
APIを確認してみます。EventBridge RuleだとEnableRule、DisableRuleのような有効化、無効化と簡単なAPIがあったので、同じ感じだろうと思っていました。が、甘かった。。。
↓↓ Amazon EventBridge Scheduler API
Enable〜、Disable〜がない。。。(2023/2/14時点)
ではでは、次はUpdateですね。UpdateScheduleを見てみると、
Updates the specified schedule. When you call UpdateSchedule, EventBridge Scheduler uses all values, including empty values, specified in the request and overrides the existing schedule. This is by design. This means that if you do not set an optional field in your request, that field will be set to its system-default value after the update.
Before calling this operation, we recommend that you call the GetSchedule API operation and make a note of all optional parameters for your UpdateSchedule call.
だそうです。(英語を読めてる雰囲気出して翻訳つかってます。)
UpdateScheduleを呼び出すと、EventBridge スケジューラはリクエストで指定された空の値を含むすべての値を使用し、既存のスケジュールを上書きします。しかも、リクエストでオプションのフィールドを設定しない場合、そのフィールドは更新後にシステムのデフォルト値に設定されますよ、と。
さらに、このオペレーションを呼び出す前に、GetSchedule APIオペレーションを呼び出し、UpdateSchedule呼び出しのすべてのオプション パラメータを書き留めておくことをお勧めします、とのことです。
ということで、
GetSchedule → UpdateSchedule
が必要になるとのことです。EventBridge Ruleのように簡単にできないぞ、そんなことはないでしょ、と疑いはじめてマネジメントコンソールを見てみます。
AWSマネジメントコンソールの動作確認
スケジュールの無効化ボタンをクリックした際のリクエストを確認してみます。
1つ目のリクエスト
レスポンスの内容は以下です。
※一部、マスキングしています。
{
"Arn": "arn:aws:scheduler:ap-northeast-1:XXXXXXXXXXXX:schedule/default/execute-sync",
"CreationDate": 1.676300282709E9,
"Description": "",
"EndDate": null,
"FlexibleTimeWindow": {
"MaximumWindowInMinutes": null,
"Mode": "OFF"
},
"GroupName": "default",
"KmsKeyArn": null,
"LastModificationDate": 1.676384549268E9,
"Name": "execute-sync",
"ScheduleExpression": "cron(*/5 * * * ? *)",
"ScheduleExpressionTimezone": "Asia/Tokyo",
"StartDate": null,
"State": "ENABLED",
"Target": {
"Arn": "arn:aws:lambda:ap-northeast-1:XXXXXXXXXXXX:function:data-sync",
"DeadLetterConfig": null,
"EcsParameters": null,
"EventBridgeParameters": null,
"Input": "{}",
"KinesisParameters": null,
"RetryPolicy": {
"MaximumEventAgeInSeconds": 86400,
"MaximumRetryAttempts": 3
},
"RoleArn": "arn:aws:iam::XXXXXXXXXXXX:role/service-role/Amazon_EventBridge_Scheduler_LAMBDA_XXXXXXXXXXXX",
"SageMakerPipelineParameters": null,
"SqsParameters": null
}
}
2つ目のリクエスト
次のリクエストを見てみます。PUTのリクエストが飛んでいます。
ペイロードは以下です。
※一部、マスキングしています。
{
"GroupName": "default",
"ScheduleExpression": "cron(*/5 * * * ? *)",
"Target": {
"Arn": "arn:aws:lambda:ap-northeast-1:XXXXXXXXXXXX:function:data-sync",
"RoleArn": "arn:aws:iam::XXXXXXXXXXXX:role/service-role/Amazon_EventBridge_Scheduler_LAMBDA_XXXXXXXXXXXX",
"RetryPolicy": {
"MaximumEventAgeInSeconds": 86400,
"MaximumRetryAttempts": 3
},
"Input": "{}"
},
"State": "DISABLED",
"FlexibleTimeWindow": { "Mode": "OFF" },
"Description": "",
"ScheduleExpressionTimezone": "Asia/Tokyo",
"ClientToken": "b77b6823-472e-49b2-a605-8d50c81e36b9"
}
疑いながら見てみましたが、そんなことありました。
GetSchedule → UpdateSchedule
をやっていました。これをやるしかありません。
AWS Systems Manager Automationを使う
Lambdaで関数を作って、行うこともできますが、面倒なので作りたくありません。なるべくメンテしたくない。。。
というわけで、AWS Systems Manager Automationを使います。
ドキュメント確認
もしかして、Amazon EventBridge Schedulerのドキュメントが提供されているんじゃない?と思って見てみます。
残念。ありません。Ruleはありますね。
仕方ありません。ドキュメント作っちゃいます。
Amazon EventBridge Scheduler有効化・無効化ドキュメント
こんな感じです。使ってみてください。
description: |-
Document name - ChangeStateEventBridgeScheduler
## What does this document do?
The ChangeStateEventBridgeScheduler Automation document state the scheduler in EventBridgeScheduler
## Input Parameters
* SchedulerName: (Required) Name of the EventBridge scheduler.
* State: (Required) ENABLED or DISABLED.
* AutomationAssumeRole: (Optional) The Amazon Resource Name (ARN) of the role that allows SSM Automation to perform the actions on your behalf.
## Output parameters
None
schemaVersion: '0.3'
assumeRole: '{{AutomationAssumeRole}}'
parameters:
SchedulerName:
type: String
description: (Required) Name of the EventBridge scheduler
State:
type: String
description: (Required) ENABLED or DISABLED
allowedValues:
- ENABLED
- DISABLED
AutomationAssumeRole:
type: String
description: (Optional) The Amazon Resource Name (ARN) of the role that allows SSM Automation to perform the actions on your behalf.
default: ''
allowedPattern: '^arn:aws(-cn|-us-gov)?:iam::\d{12}:role\/[\w+=,.@_\/-]+|^$'
mainSteps:
- name: GetEventBridgeScheduler
action: 'aws:executeAwsApi'
inputs:
Service: scheduler
Api: get_schedule
Name: '{{SchedulerName}}'
outputs:
- Name: Arn
Selector: $.Arn
Type: String
- Name: Description
Selector: $.Description
Type: String
- Name: FlexibleTimeWindow
Selector: $.FlexibleTimeWindow
Type: StringMap
- Name: GroupName
Selector: $.GroupName
Type: String
- Name: Name
Selector: $.Name
Type: String
- Name: ScheduleExpression
Selector: $.ScheduleExpression
Type: String
- Name: ScheduleExpressionTimezone
Selector: $.ScheduleExpressionTimezone
Type: String
- Name: Target
Selector: $.Target
Type: StringMap
description: Get a scheduler in EventBridge
- name: ChangeStateEventBridgeScheduler
action: 'aws:executeAwsApi'
inputs:
Service: scheduler
Api: update_schedule
Description: '{{ GetEventBridgeScheduler.Description }}'
FlexibleTimeWindow: '{{ GetEventBridgeScheduler.FlexibleTimeWindow }}'
GroupName: '{{ GetEventBridgeScheduler.GroupName }}'
Name: '{{ GetEventBridgeScheduler.Name }}'
ScheduleExpression: '{{ GetEventBridgeScheduler.ScheduleExpression }}'
ScheduleExpressionTimezone: '{{ GetEventBridgeScheduler.ScheduleExpressionTimezone }}'
State: '{{State}}'
Target: '{{ GetEventBridgeScheduler.Target }}'
description: Change a scheduler in EventBridge
ドキュメントの動作確認
ドキュメントの作成
AWS Systems Manager Automationのページで「ドキュメントの作成」をクリックします。
次にドキュメントの名前を入力します。
「エディタ」タブを選択し、「編集」をクリックします。その後、ドキュメント内容を貼り付けます。
最後に「オートメーションを作成する」をクリックし、作成します。
以上、作成完了です。
実行してみる(有効化してみる)
AWS Systems Manager Automationのページで先程作成したドキュメントを選択し、「オートメーションを実行する」をクリックします。
入力パラメータのSchedulerName、Stateを設定し、実行します。
無事、有効化することができました。
まとめ
AWS Systems Manager Automationを使うことで人の手を介さず、Amazon EventBridge Schedulerの有効化、無効化することをできることがわかりました。単純に考えるとLambdaを作ったりしないといけませんが、Automationで対応することができました。まだ、ドキュメントが提供されていませんが、載せてあるサンプルを使うことで実現できますので、使ってみてください。
おまけ
ドキュメント作成でひっかかった部分
「ステップ1で取得したデータをステップ2でどうやって使えるの?」とパッとやり方がわかりませんでした。各ステップで取得したデータの受け渡しは以下に記載があります。ここを参考に作成しました。