結論
本記事では、営業時間外にRDSクラスター内のインスタンスを自動停止することで、RDSの利用料金を削減する方法を紹介します。
AWS料金見積もりツールの結果
AWS料金見積もりツールによる試算では、夜間(21:00〜8:00)や土日にRDSを停止する運用に切り替えた場合は、約32.20% のコスト削減が見込めるとのことです。
見積もりツール試算結果
月額料金:91.25 USD ➔ 61.87 USD
月額料金(日本円換算):約14,343円 ➔ 約9,717円
更に、祝日含むと更なるコスト削減を見込むことができます。
URL:AWS料金見積もりツール
また、本記事は自身のスキルを証明する一つの材料として執筆しております。
本記事は下記のサービスにて公開しております。公開日時:2025年01月04日
複数のプラットフォームで発信することで、多くの方にご覧いただき、少しでも参考になれば幸いです。
- Zenn
- Qiita
- Findy
- Forkwell
- LAPRAS
- 職務経歴書のレジュメ
- etc
構成図
- AWS
- VPC
- プライベートサブネット
- RDS
- プライベートサブネット
- RDS
- プライベートサブネット
- EventBridge Scheduler
- IAMロール
- EventBridge Schedulerにアタッチする
- VPC
EventBridge Schedulerで実装している理由
EventBridge Schedulerで実装している理由については、EC2 や RDS の起動・停止をスケジュールする一番簡単な方法を参考にしております。この内容については下記のように説明されています。
以前から利用できる方法
料金を節約するために EC2 や RDS のインスタンスを自動的に止めたいというニーズはありふれているため、これを実現するための手法はさまざまにあります。そして、より簡単に設定できるよう AWS それ自体の機能も進化してきました。
プリミティブな方法を含めて、以前から利用可能だった手法には、例えば次のものがあります。
- AWS 外のシステム上の cron から AWS CLI コマンドを実行する
- 常時起動している EC2 インスタンス上の cron から AWS CLI コマンドを実行する
- CloudWatch イベントから Lambda 関数を実行する
- EventBridge ルールから Lambda 関数を実行する
- EventBridge ルールから Systems Manager オートメーションを実行する
一番簡単な方法
現在では、AWS コンソールの設定だけで EC2 や RDS の停止と再開をスケジュールでき、もはや Lambda 関数を書く必要もなくなっています。
具体的には、Amazon EventBridge Scheduler を使用してスケジュールを作成します。
ソースコード
ソースコードは下記リンクにて公開しております。Terraformにて構築しております。
下記にポイントなる箇所を一部抜粋します
//////////////////////////////////////////////////
// EventBridgeScheduler
// Aurora クラスタを起動
//////////////////////////////////////////////////
resource "aws_scheduler_schedule" "aurora_start" {
name = "aurora-start"
group_name = "default"
flexible_time_window {
// フレックスタイムウィンドウは使用しない
mode = "OFF"
}
// 平日 (MON-FRI) の 8:00 に起動
// cron(分 時 日 月 曜日 年) の順で指定
// 年の指定は * にすることで毎年有効となる
schedule_expression = "cron(0 8 ? * MON-FRI *)"
schedule_expression_timezone = "Asia/Tokyo"
target {
arn = "arn:aws:scheduler:::aws-sdk:rds:startDBCluster"
role_arn = aws_iam_role.eventbridge-scheduler-rds-start-stop-role.arn
input = jsonencode({
DbClusterIdentifier = aws_rds_cluster.default.cluster_identifier
})
retry_policy {
maximum_event_age_in_seconds = 600 // リトライする最大のイベントの経過時間:10分
maximum_retry_attempts = 1 // リトライ最大回数
}
}
}
//////////////////////////////////////////////////
// EventBridgeScheduler
// Aurora クラスタを停止
//////////////////////////////////////////////////
resource "aws_scheduler_schedule" "aurora_stop" {
name = "aurora-stop"
group_name = "default"
flexible_time_window {
// フレックスタイムウィンドウは使用しない
mode = "OFF"
}
// 平日 (MON-FRI) の 21:00 に停止
schedule_expression = "cron(0 21 ? * MON-FRI *)"
schedule_expression_timezone = "Asia/Tokyo"
target {
arn = "arn:aws:scheduler:::aws-sdk:rds:stopDBCluster"
role_arn = aws_iam_role.eventbridge-scheduler-rds-start-stop-role.arn
input = jsonencode({
DbClusterIdentifier = aws_rds_cluster.default.cluster_identifier
})
retry_policy {
maximum_event_age_in_seconds = 600 // リトライする最大のイベントの経過時間:10分
maximum_retry_attempts = 1 // リトライ最大回数
}
}
}
動作確認
リソースが作成されていることを確認
自動停止されていることを確認
一時的に毎時指定20時50分にて動作確認した結果、自動的に停止されることを確認しております。
//////////////////////////////////////////////////
// EventBridgeScheduler
// Aurora クラスタを停止 (定期的: 毎日 20:50 JST)
//////////////////////////////////////////////////
resource "aws_scheduler_schedule" "aurora_stop" {
name = "aurora-stop"
group_name = "default"
flexible_time_window {
mode = "OFF"
}
// 毎日 (day-of-week は問わない) 20:50 JST
// cron(Minute Hour Day-of-month Month Day-of-week Year)
// 日・月は「*」=毎日、曜日は「?」としています。
schedule_expression = "cron(50 20 * * ? *)"
schedule_expression_timezone = "Asia/Tokyo"
target {
arn = "arn:aws:scheduler:::aws-sdk:rds:stopDBCluster"
role_arn = aws_iam_role.eventbridge-scheduler-rds-start-stop-role.arn
input = jsonencode({
DbClusterIdentifier = aws_rds_cluster.default.cluster_identifier
})
retry_policy {
maximum_event_age_in_seconds = 600
maximum_retry_attempts = 1
}
}
}