背景・目的
開発・検証用の Aurora クラスタを常時稼働させていると、夜間や休日など使っていない時間帯にもコストが発生します。Aurora は停止しておけばコンピューティング料金がかからないため、業務時間外は停止しておくことでコスト最適化できます。
ただし、手動での停止・起動は忘れがちで、運用負荷にもなります。また、Aurora は停止後 7 日経つと自動的に再起動されるため、手動での停止を繰り返す運用は現実的ではありません。
これまでは EventBridge Scheduler から Lambda を経由して RDS API を呼び出す方法で運用していましたが、EventBridge Scheduler の Universal Target Parameter(UTP)を使えば Lambda なしで RDS API を直接呼び出せることを知り、試してみました。
本記事では、UTP を使って Aurora クラスタを平日の業務時間帯のみ自動で起動・停止する仕組みをCloudFormation で構築します。
まとめ
下記に特徴をまとめます。
| 特徴 | 説明 |
|---|---|
| ユニバーサルターゲット | カスタマイズ可能なパラメータセット 多くの AWS サービスに対して幅広い API オペレーションを呼び出すことができる |
| UTP | ユニバーサルターゲットパラメータ |
| EventBridgeスケジューラーのUTP | 下記を指定する。 ・RoleArn ・Arn ・Input |
| EventBridgeスケジューラーがサポートしてないUTP | 基本的には、読み取り専用APIアクションをサポートしてない |
概要
下記の記事を基に整理します。
ユニバーサルターゲットはカスタマイズ可能なパラメータセットで、多くの AWS サービスに対して幅広い API オペレーションを呼び出すことができます。例えば、ユニバーサルターゲットパラメータ (UTP) を使用して、CreateQueue オペレーションを使用して新しい Amazon SQS キューを作成できます。
- ユニバーサルターゲットは、カスタマイズ可能なパラメータセット
- APIオペレーションを呼び出すことができる
- UTPは、ユニバーサルターゲットパラメータのこと
- 例:UTPのCreateQueue オペレーションを使用して新しい Amazon SQS キューを作成できる
AWS CLI または EventBridge スケジューラのいずれかの SDK を使用してスケジュールにユニバーサルターゲットを設定するには、次の情報を指定する必要があります。
- RoleArn — ターゲットに使用したい実行ロールの ARN。指定する実行ロールには、スケジュールの対象とする API オペレーションを呼び出す権限が必要です。
- Arn — ターゲットとする API オペレーションを含むサービス ARN 全体を、次の形式で示します: arn:aws:scheduler:::aws-sdk:service:apiAction
例えば、Amazon SQS の場合、指定するサービス名は arn:aws:scheduler:::aws-sdk:sqs:sendMessage です。- Input — EventBridge スケジューラがターゲット API に送信するリクエストパラメータで指定する、正しい形式の JSON。Input に設定する JSON のパラメータと形状は、スケジュールが呼び出すサービス API によって決まります。この情報については、対象とするサービスの API リファレンスをご覧ください。
-
CLIまたは、EventBridgeスケジューラのいずれかのSDKを使用してスケジュールにユニバーサルターゲットを設定するには、下記の情報を指定する必要がある
-
RoleArn
- ターゲットを使用した実行ロールのARN
-
Arn
- ターゲットとするAPIオペレーションを含むサービスARN全体を指定する
-
Input
- EventBridgeスケジューラがターゲットAPIに送信するリクエストパラメータで指定する
- JSON形式
EventBridge スケジューラは、以下のプレフィックスのリストで始まる一般的な GET オペレーションなどの読み取り専用 API アクションをサポートしていません。
- 読み取り専用APIアクションをサポートしてない
実装
前提
IaC (Cfn)の作成
1.下記のようにテンプレートを作成します
- パラメータ
- ClusterName:Auroraクラスタ名
- Environment:環境を指定
- リソース
- Role:Auroraの起動と停止ができるロール
- スケジューラー
- 起動:平日の8:50
- 停止:平日の20:00
AWSTemplateFormatVersion: '2010-09-09'
Description: Aurora Cluster Start/Stop Scheduler (UTP Direct)
Parameters:
ClusterName:
Type: String
Description: Aurora DB Cluster Identifier
Environment:
Type: String
AllowedValues: [dev]
Conditions:
IsDev: !Equals [!Ref Environment, dev]
Resources:
SchedulerExecutionRole:
Type: AWS::IAM::Role
Condition: IsDev
Properties:
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service: scheduler.amazonaws.com
Action: sts:AssumeRole
Policies:
- PolicyName: AuroraStartStop
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- rds:StartDBCluster
- rds:StopDBCluster
Resource: !Sub arn:aws:rds:${AWS::Region}:${AWS::AccountId}:cluster:${ClusterName}
StartSchedule:
Type: AWS::Scheduler::Schedule
Condition: IsDev
Properties:
Name: !Sub ${ClusterName}-start
ScheduleExpression: cron(50 8 ? * MON-FRI *)
ScheduleExpressionTimezone: Asia/Tokyo
FlexibleTimeWindow:
Mode: 'OFF'
Target:
Arn: arn:aws:scheduler:::aws-sdk:rds:startDBCluster
RoleArn: !GetAtt SchedulerExecutionRole.Arn
Input: !Sub '{"DbClusterIdentifier": "${ClusterName}"}'
RetryPolicy:
MaximumRetryAttempts: 0
StopSchedule:
Type: AWS::Scheduler::Schedule
Condition: IsDev
Properties:
Name: !Sub ${ClusterName}-stop
ScheduleExpression: cron(0 20 ? * MON-FRI *)
ScheduleExpressionTimezone: Asia/Tokyo
FlexibleTimeWindow:
Mode: 'OFF'
Target:
Arn: arn:aws:scheduler:::aws-sdk:rds:stopDBCluster
RoleArn: !GetAtt SchedulerExecutionRole.Arn
Input: !Sub '{"DbClusterIdentifier": "${ClusterName}"}'
RetryPolicy:
MaximumRetryAttempts: 0
デプロイ
1.下記のコマンドでデプロイします
aws cloudformation create-stack --stack-name aurora-cluster-scheduler --template-body file://XXXX/aurora-cluster-scheduler.yaml --parameters file://XXXX/params/dev/aurora-cluster-scheduler.json --capabilities CAPABILITY_IAM
リソースの確認
起動スケジューラーの確認
-
dms-target-aurora-startをクリックします
停止スケジューラーの確認
- dms-target-aurora-stopをクリックします
- ターゲットタブをクリックします。想定通りのAPIおよび、対象となるAuroraクラスタ名が設定されていました
- スケジュールタブをクリックします。月〜金の20:00に停止します。想定通りです
停止の動作確認
動作確認するため、停止スケジューラーを修正します。
起動確認はしていません
実行前の確認
修正とデプロイ
1.スケジューラーを修正します(月〜金:20:00から、毎日17:35 に変更しました)
StopSchedule:
Type: AWS::Scheduler::Schedule
Condition: IsDev
Properties:
Name: !Sub ${ClusterName}-stop
ScheduleExpression: cron(35 17 ? * * *)
2.スタックを更新します
aws cloudformation update-stack --stack-name aurora-cluster-scheduler --template-body file://XXXX/aurora-cluster-scheduler.yaml --parameters file://XXXX/params/dev/aurora-cluster-scheduler.json --capabilities CAPABILITY_IAM
動作確認
停止を設定した時刻の17:35になったので確認します。
2.CloudTrailでAPI実行を確認します
aws cloudtrail lookup-events --lookup-attributes AttributeKey=EventName,AttributeValue=StopDBCluster --max-results 1 --output json
3.StopDBClusterが、dms-target-auroraに対して、AmazonEventBridgeSchedulerから実行されたことが確認できました(必要な箇所のみ抜粋しています)
{
"Events": [
{
"EventName": "StopDBCluster",
"EventTime": "2026-03-29T17:35:24+09:00",
"EventSource": "rds.amazonaws.com",
"CloudTrailEvent": "{・・・
"userAgent\":\"AmazonEventBridgeScheduler XXXXX"
・・・・
requestParameters": {"dBClusterIdentifier": "dms-target-aurora"}
4.Auroraクラスタのステータスが「一時的に停止済み」になりました

5.Auroraクラスタのログとイベントをクリックします
6.「最近のイベント」では17:47に、システムノートに「DB cluster stopped」が記録されました。

考察
UTP は Lambda が不要でリソース数が少なくシンプルですが、運用面で今回の検証で気になったいくつかの留意点があります。
- EventBridge Scheduler 自体の実行履歴を確認する API がなく、CloudTrail の userAgent から間接的に確認する必要がある(確認方法が複雑)
- RetryPolicy はエラーの種類で分岐できない。既に停止済みのエラーも、一時的なネットワークエラーも同じ扱いになると考えられる(柔軟性がない)
- Lambda 経由と比べて、通知や条件分岐などの拡張がしにくい(柔軟性がない)
Lambda 経由との比較
以下に Lambda 経由との比較と、運用上のポイントを整理します。
| 項目 | UTP (今回) | Lambda 経由 |
|---|---|---|
| リソース数の少なさ | ◯ Scheduler × 2 + IAM Role |
△ Scheduler × 2 + Lambda + IAM Role × 2 |
| 実行時の確認 | △ CloudTrail から間接的に確認 |
◯ LambdaでCloudWatch Logs に出力する |
| エラーハンドリング | △ RetryPolicy のみ |
◯ Lambda 内で自由に実装可能 |
| 拡張性 | △ API 呼び出しのみ |
◯ 通知・条件分岐など追加しやすい |
運用上のポイント
UTP と Lambda 経由のどちらを採用するかは、運用要件次第と考えます。
- 開発・検証環境のコスト削減が目的であれば、UTP 直接パターンで十分
- 失敗時の即時通知や、停止前の接続確認などが必要な場合は Lambda 経由を検討する
参考







