複数のRDSを自動定期停止させたい…。
こんにちは!AWS事業本部のおつまみです。
みなさん!2022年末にリリースされたAWSの新機能「EventBridge Scheduler」使ってますか?
EventBridge Schedulerは、様々なAWSサービスのAPIと連携し、イベントの定期的な実行をスケジュールすることができます。
以前こちらのブログで、RDSを自動定期停止させてみました。
ただしRDSを停止するAPIStopDBInstance
は複数のリソースを指定することができません。
AWS公式のAPIリファレンスを確認すると、Request ParametersのDBInstanceIdentifierはType: String
となっています。
そのため複数のRDSに停止スケジュールを設定したい場合は、EventBridge Schedulerを1つずつ実装する必要があります。
手動で実装するのが面倒なため、今回はCloudFormationテンプレートを作成し、1発で実装できるようにしたいと思います!
構成図
今回はこちらの2つを作成します。
- 停止用のEventBridge Scheduler
- 上記Schedule実行用のIAMロール
やってみた
CloudFormationテンプレート
実行するCloudFormationテンプレートです。
---
AWSTemplateFormatVersion: '2010-09-09'
Description: EventBridge Scheduler to stop RDS instance
Parameters:
InstanceId:
Type: String
ScheduleStopTime:
Type: String
Default: "cron(0 20 * * ? *)"
ScheduleTimezone:
Type: String
Default: Japan
Resources:
## EventBridgeSchedulerの作成
ScheduleRDSStop:
Type: AWS::Scheduler::Schedule
Properties:
Name: !Sub 'RDS-Stop-${InstanceId}'
Description: Stop RDS Instance
ScheduleExpression: !Ref ScheduleStopTime
ScheduleExpressionTimezone: !Ref ScheduleTimezone
FlexibleTimeWindow:
Mode: "OFF"
State: ENABLED
Target:
Arn: arn:aws:scheduler:::aws-sdk:rds:stopDBInstance
Input: !Sub |-
{
"DbInstanceIdentifier": "${InstanceId}"
}
RoleArn:
Fn::GetAtt:
- SchedulerRDSStopRole
- Arn
## EventBridgeSchedulerに紐付けるIAMロールの作成
SchedulerRDSStopRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service:
- scheduler.amazonaws.com
Action:
- sts:AssumeRole
Path: "/"
Policies:
- PolicyName: rdsstop
PolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Action:
- rds:StopDBInstance
Resource:
- "*"
スタック作成時に、こちらのパラメータを指定するだけです。
- 対象インスタンス
- 停止のスケジュール
- タイムゾーン
作成されたリソースを確認
スタック作成完了後、Amazon EventBridgeのスケジュールから作成されたリソースを確認できます。
動作確認
設定したスケジュールで、下準備として用意したRDSが停止されるか見守ります。 今回はテンプレートを使い回し、RDS2台にEventBridge Schedulerを設定しました。
無事、設定した時刻になると起動中→停止中→一時的に停止済みとなりました!
ちょっとハマったところ
EventBridge SchedulerのTarget ServiceArnに指定する[apiAction]
がわからなくハマりました。
CloudFormaitonテンプレートのこの部分です。
ScheduleRDSStop:
Type: AWS::Scheduler::Schedule
Properties:
Name: !Sub 'RDS-Stop-${InstanceId}'
Description: Stop RDS Instance
ScheduleExpression: !Ref ScheduleStopTime
ScheduleExpressionTimezone: !Ref ScheduleTimezone
FlexibleTimeWindow:
Mode: "OFF"
State: ENABLED
Target:
Arn: arn:aws:scheduler:::aws-sdk:rds:stopDBInstance
Input: !Sub |-
{
"DbInstanceIdentifier": "${InstanceId}"
}
RoleArn:
Fn::GetAtt:
- SchedulerRDSStopRole
- Arn
公式ドキュメントのユニバーサルターゲットパラーメータ(APIオペレーション)を確認すると、arn:aws:scheduler:::aws-sdk:rds:[apiAction]
と記載されていました。
[apiAction]
に[StopDBInstance]
を指定すると、CloudFormation実行時にこのようなエラーが発生します。
Resource handler returned message: "Invalid request provided: Invalid RequestJson provided. Reason The api StopDBInstance is not valid for the service aws-sdk:rds.
社内で相談したところ、実行するAPIはStopDBInstance
ですが、stopDBInstance
と頭文字を小文字で指定する必要があると分かりました。
AWS SDKの指定では大文字、小文字がしっかり判定されるようです。
ちなみにインプットに指定するRequest ParametersもDBInstanceIdentifier
ではなく、DbInstanceIdentifier
であることに注意です。
最後に
今回はEventBridge SchedulerでRDSの自動定期停止をCloudFormationで実装してみました。
便利なEventBridge SchedulerをCloudFormationと組み合わせることで、さらに便利になりますね!
また弊社が提供するAWS運用簡単サービスopswitchでは、GUI操作で複数のRDS起動・停止をスケジュールできます。 ご興味がある方はこちらのブログをご参考下さい。
最後までお読みいただきありがとうございました!
どなたかのお役に立てれば幸いです。
以上、おつまみ(@AWS11077)でした!
参考
Amazon EventBridge Scheduler resource type reference - AWS CloudFormation
Universal target - EventBridge Scheduler
EventBridge Schedulerを使ってEC2を定期起動・停止するCloudFormationテンプレート | DevelopersIO