Aurora リードレプリカをスケジュールで追加・削除できるように対応してみた

2021.08.23

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

こんにちは、コンサル部@大阪オフィスのTodaです。

Auroraのクラスターにリードレプリカを追加する場合、下記方法があると考えます。
今回、決まった時間に負荷が高くなることを想定して、リードレプリカをスケジュールで追加・削除できる方法を試してみました。

・リードレプリカを追加する方法

  • マネージメントコンソール または CLIによる手動追加
  • AutoScalingポリシーを利用した自動追加
  • EventBridge と Lambda を利用したスケジュールによる自動追加 (今回試します)

注意事項

下記、サンプルプログラムはRDSインスタンスの追加・削除をおこないます。
プログラムの動作保証ができないため必ず評価ならびに検証環境での事前の設定・動作確認をおこなっていただくようにお願いします。

前提条件

下記AWSサービスは既に準備されている状態から開始します。

  • Auroraクラスター (識別子:test-db)

リードレプリカの追加

EventBridgeとLambda処理を利用してAuroraクラスターにリードレプリカを追加します。

Lambda処理の作成

AWSコンソールにログインをおこないます。
サービスから[Lambda] > 左メニューから[関数]をクリックします。
[関数の作成]をクリックして新規Lambda作成をおこないます。
作成時の設定は下記にしています。

入力例

  • 関数名:startAurora-ReadReplica (任意)
  • ランタイム:Python3.9
  • 実行ロール:基本的な Lambda アクセス権限で新しいロールを作成

プログラムの記入

今回、Boto3を利用してAuroraクラスターにリードレプリカを追加します。
ドキュメントを確認したところ、create_db_instanceでインスタンス追加ができるとのことで、利用いたします。
※create_db_instance_read_replicaというメソッドもあるのですがAuroraの場合は、上記を利用します。

■ Boto3 - create_db_instance https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/rds.html#RDS.Client.create_db_instance

■ 引数 (必要な最低限のみ記入)

  • DBInstanceIdentifier:追加するインスタンス識別子
  • DBInstanceClass:追加するインスタンスクラス
  • Engine:エンジン指定
    • MySQL5.6互換の場合:aurora
    • MySQL5.7互換の場合:aurora-mysql
    • PostgreSQL互換の場合:aurora-postgresql
  • DBClusterIdentifier:対象のDBクラスター名
  • PromotionTier:プライマリインスタンス障害時にプロモートされる順序を指定する値になります。
    • 削除する事を想定するため選ばれないように最終番号15を指定します。

■ プログラム例 (値はサンプルになります)

import boto3
from botocore.exceptions import ClientError

client = boto3.client('rds')

def lambda_handler(event, context):
    param = {
        "DBInstanceIdentifier":"test-db-scaling-lambda1",   # 追加するインスタンス識別子
        "DBInstanceClass":"db.t3.small",                    # 追加するインスタンスクラス
        "Engine":"aurora",                                  # エンジン
        "DBClusterIdentifier":"test-db",                    # 対象のDBクラスター名
        "PromotionTier":15
    }

    try:
        response = client.create_db_instance(**param)
        print(response)
    except ClientError as e:
        # print("エラーに関する追加処理など記入")
        # print(e.response)
        raise e
        
    return

IAMロールの権限設定

デフォルト作成されるIAMロールはRDS(Aurora)の設定権限がありません。
IAMロールの編集にて権限を調整します。
今回はAmazonRDSFullAccessをアタッチしています。

Lambda編集画面上の[設定]タブをクリック、左メニューの[アクセス権限]をクリックします。
実行ロールの欄に割り当てられているIAMロールが表示されるためリンクをクリックします。

IAMロールの選択

IAMロールの設定でポリシーを追加します。

IAMロールの変更

RDSの操作用にAmazonRDSFullAccessを選択してアタッチします。

IAMロールへのポリシーアタッチ

IAMロールの権限設定は以上になります。

処理のテスト

Lambdaのテストを利用してAuroraリードレプリカが追加されるか確認します。
テストは引数が必要ないためhello-worldのテンプレートを利用して作成します。

処理のテスト1

処理のテスト2

作成したテストイベントを実行して、動作を確認します。
問題なければ、作成されたAuroraリードレプリカは停止または削除します。

スケジュール設定

EventBridgeを利用して指定した時間にLambda処理が実行されるようにします。
Lambda編集画面上の[トリガーを追加]をクリックします。

EventBridgeのスケジュール指定

トリガーの指定画面で[EventBridge]を選択頂き、ルールの指定とスケジュールの指定をおこないます。
スケジュールの指定はcron式 または rate式がありcron式を利用します。
指定は協定世界時 (UTC) の指定になるため日本時間を指定しないように注意が必要です。

入力例

  • ルール名:cron-startAurora-ReadReplica
  • スケジュール式:cron(0 23 * * ? *)

cronのスケジュール指定の詳細は下記参考ページをご確認ください。
今回は毎日朝8時00に実行されるようにしています。

■ Rate または Cron を使用したスケジュール式 https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/services-cloudwatchevents-expressions.html

上記保存にてEventBridgeの設定は以上になります。

設定の完了

上記でAurora リードレプリカをスケジュールで追加する対応が完了しました。
実際に指定時間で動作をしているかを確認してください。
追加ができていない場合はCloudWatch Logsに「/aws/lambda/[Lambdaファンクション名]」にエラーログが記録されますので確認をおこない改善することが可能でございます。

リードレプリカの削除

上記手順で作成したリードレプリカをスケジュールで削除します。
一部の手順は追加操作と同じになるため割愛しております。

Lambda処理の作成

Lambdaを新規で作成します。

入力例

  • 関数名:endAurora-ReadReplica (任意)
  • ランタイム:Python3.9
  • 実行ロール:基本的な Lambda アクセス権限で新しいロールを作成

プログラムの記入

Auroraクラスターに関連付けされているリードレプリカを削除します。
ドキュメントにて、delete_db_instanceでインスタンス削除をおこないます。

■ Boto3 - delete_db_instance https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/rds.html#RDS.Client.delete_db_instance

■ 引数 (必要な最低限のみ記入)

  • DBInstanceIdentifier:削除するインスタンス識別子
  • SkipFinalSnapshot:スナップショットの作成をスキップするか
    • 今回、リードレプリカの削除のためスキップにします。

■ プログラム例 (値はサンプルになります)

import boto3
from botocore.exceptions import ClientError

client = boto3.client('rds')

def lambda_handler(event, context):
    param = {
        "DBInstanceIdentifier":"test-db-scaling-lambda1",     # 削除するインスタンス識別子
        "SkipFinalSnapshot":True                              # DBスナップショット作成のスキップ
    }

    try:
        response = client.delete_db_instance(**param)
        print(response)
    except ClientError as e:
        # print("エラーに関する追加処理など記入")
        # print(e.response)
        raise e
        
    return

IAMロールの権限設定・テスト

追加の時と同じようにIAMロールにAmazonRDSFullAccessをアタッチをおこない動作テストをおこないます。

スケジュール設定

EventBridgeを利用して指定した時間にLambda処理が実行されるようにします。
設定操作は追加の時のスケジュール設定をご確認ください。
今回は毎日朝17時00に実行されるようにしています。

入力例

  • ルール名:cron-endAurora-ReadReplica
  • スケジュール式:cron(0 8 * * ? *)

設定の完了

上記でAurora リードレプリカをスケジュールで削除する対応が完了しました。
実際に指定時間で動作をしているかを確認してください。

さいごに

今回はEventBridgeとLambdaを利用してAurora リードレプリカをスケジュールで追加・削除する方法を試してみました。
少しでもお客様の参考になればと考えております。