AWS CDKとEventBridge Schedulerで実装するAurora Serverless v2のキャパシティ自動調整

AWS CDKとEventBridge Schedulerで実装するAurora Serverless v2のキャパシティ自動調整

Clock Icon2025.05.19

こんにちは!製造ビジネステクノロジー部の小林です!

Aurora Serverless v2は、最小 - 最大で設定したACU間を負荷に合わせて自動でスケールします。今回は、AWS CDKとEventBridge Schedulerを使用して、Amazon Aurora Serverless v2のキャパシティを時間帯に応じて自動的に調整する仕組みを構築する方法を紹介します。

実装する内容

EventBridge Schedulerを使用して時間帯ごとのキャパシティ調整を設定します。

  • 既存のAuroraクラスター設定:最小0 ACU、最大1ACU
  • スケジュール1:日本時間23:40にACUを0.5に増やす
  • スケジュール2:日本時間23:45にACUを0に戻す

やってみた

EventBridge Schedulerの実装

Aurora Serverless v2 のキャパシティを時間帯に応じて自動調整するため、EventBridge Scheduler を使ったコンストラクトを作成しました。
まず、EventBridge SchedulerがAuroraクラスターを操作するための IAMロールを設定します。

// EventBridge Scheduler がAuroraクラスターを操作するためのIAMロールを作成
const role = new iam.Role(this, "SchedulerRole", {
  assumedBy: new iam.ServicePrincipal("scheduler.amazonaws.com"),
});

// Aurora クラスターのキャパシティ変更権限をIAMロールに付与
role.addToPolicy(
  new iam.PolicyStatement({
    actions: ["rds:ModifyDBCluster"],
    resources: [cluster.clusterArn],
  }),
);

この IAM ロールにより、EventBridge Scheduler は Aurora クラスターのキャパシティを変更する権限を持ちます。

次に、2つのスケジュールを設定します。既存の Aurora クラスター(最小 0 ACU、最大 1 ACU)に対して、

  • 23:40 に ACU を 0.5 に増やす
  • 23:45 に ACU を 0 に戻す
    // 日本時間23:40に最小キャパシティを0.5に設定
    new scheduler.Schedule(this, "SetMinCapacity0.5", {
      schedule: scheduler.ScheduleExpression.cron({
        minute: "40",
        hour: "23",
        timeZone: cdk.TimeZone.ASIA_TOKYO,
      }),
      target: new scheduler_targets.Universal({
        service: "rds",
        action: "modifyDBCluster",
        role,
        input: scheduler.ScheduleTargetInput.fromObject({
          DbClusterIdentifier: cluster.clusterIdentifier,
          ServerlessV2ScalingConfiguration: {
            MinCapacity: 0.5,
          },
          ApplyImmediately: true,
        }),
      }),
    });

    // 日本時間23:45に最小キャパシティを0に設定
    new scheduler.Schedule(this, "SetMinCapacity0", {
      schedule: scheduler.ScheduleExpression.cron({
        minute: "45",
        hour: "23",
        timeZone: cdk.TimeZone.ASIA_TOKYO,
      }),
      target: new scheduler_targets.Universal({
        service: "rds",
        action: "modifyDBCluster",
        role,
        input: scheduler.ScheduleTargetInput.fromObject({
          DbClusterIdentifier: cluster.clusterIdentifier,
          ServerlessV2ScalingConfiguration: {
            MinCapacity: 0,
          },
          ApplyImmediately: true,
        }),
      }),
    });

全体のソースはこちらです。

全体のソース
import * as cdk from "aws-cdk-lib";
import * as iam from "aws-cdk-lib/aws-iam";
import * as rds from "aws-cdk-lib/aws-rds";
import * as scheduler from "aws-cdk-lib/aws-scheduler";
import * as scheduler_targets from "aws-cdk-lib/aws-scheduler-targets";
import { Construct } from "constructs";

interface AcuSchedulerConstructProps {
  cluster: rds.DatabaseCluster;
}

export class AcuSchedulerConstruct extends Construct {
  constructor(scope: Construct, id: string, props: AcuSchedulerConstructProps) {
    super(scope, id);

    const { cluster } = props;

    /**
     * Aurora データベースのキャパシティを自動的に切り替えるスケジューラー
     */

    // EventBridge Scheduler がAuroraクラスターを操作するためのIAMロールを作成
    const role = new iam.Role(this, "SchedulerRole", {
      assumedBy: new iam.ServicePrincipal("scheduler.amazonaws.com"),
    });

    // Aurora クラスターのキャパシティ変更権限をIAMロールに付与
    role.addToPolicy(
      new iam.PolicyStatement({
        actions: ["rds:ModifyDBCluster"],
        resources: [cluster.clusterArn],
      }),
    );

    // 日本時間23:40に最小キャパシティを0.5に設定
    new scheduler.Schedule(this, "SetMinCapacity0.5", {
      schedule: scheduler.ScheduleExpression.cron({
        minute: "40",
        hour: "23",
        timeZone: cdk.TimeZone.ASIA_TOKYO,
      }),
      target: new scheduler_targets.Universal({
        service: "rds",
        action: "modifyDBCluster",
        role,
        input: scheduler.ScheduleTargetInput.fromObject({
          DbClusterIdentifier: cluster.clusterIdentifier,
          ServerlessV2ScalingConfiguration: {
            MinCapacity: 0.5,
          },
          ApplyImmediately: true,
        }),
      }),
    });

    // 日本時間23:45に最小キャパシティを0に設定
    new scheduler.Schedule(this, "SetMinCapacity0", {
      schedule: scheduler.ScheduleExpression.cron({
        minute: "45",
        hour: "23",
        timeZone: cdk.TimeZone.ASIA_TOKYO,
      }),
      target: new scheduler_targets.Universal({
        service: "rds",
        action: "modifyDBCluster",
        role,
        input: scheduler.ScheduleTargetInput.fromObject({
          DbClusterIdentifier: cluster.clusterIdentifier,
          ServerlessV2ScalingConfiguration: {
            MinCapacity: 0,
          },
          ApplyImmediately: true,
        }),
      }),
    });
  }
}

実装のポイント

  1. EventBridge Schedulerの活用
    EventBridge Schedulerはタイムゾーンの直接指定が可能です(timeZone: cdk.TimeZone.ASIA_TOKYO)これにより日本時間でスケジュールを設定できるため、時刻設定が分かりやすいです!

  2. Universalターゲットの使用
    scheduler_targets.Universal クラスを使用することで、AWS SDKで利用可能な任意のAPI オペレーションを呼び出すことができます。今回はrds:modifyDBCluster APIを使用してAuroraクラスターの設定を変更しています。

動作確認

実装したシステムをデプロイし、CloudWatch メトリクスで動作を確認しました。
確認するメトリクスは「ServerlessDatabaseCapacity」です。このメトリクスはAurora Serverless v2のキャパシティ使用状況をモニタリングできます。
https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/AuroraUserGuide/aurora-serverless-v2.setting-capacity.html#aurora-serverless-v2.viewing.monitoring

23:40のスケジュール実行結果

スクリーンショット 2025-05-19 0.55.41

結果

  • 23:40頃、キャパシティが0から上昇
  • 最大1ACUに到達

原因

  • 23:40に設定されたスケジュールにより、最小キャパシティが0.5ACUに変更
  • データベースの初期化処理や接続確立により、一時的に最大キャパシティ(1 ACU)まで上昇
  • これは Aurora Serverless v2 の自動スケーリングによる挙動

23:45のスケジュール実行結果

スクリーンショット 2025-05-19 0.54.42

結果

  • 23:40頃、キャパシティが徐々に下がり始める
  • 最終的に0ACUまで減少

原因

  • 23:45に設定したスケジュールが実行され、最小キャパシティが0ACUに戻された
  • アクティブな接続がなくなると、キャパシティは徐々に最小値まで下がる

おわりに

AWS CDKとEventBridge Schedulerを組み合わせることで、Aurora Serverless v2のキャパシティを時間帯に応じて自動的に調整するシステムを簡単に構築できました。これにより業務時間外のデータベースコスト削減などが可能になります。Auroraクラスターのキャパシティ戦略を検討されている方にとって少しでも参考になれば幸いです。

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.

OSZAR »