AWS RDSの自動停止機能を作成してみた【EventBrige Scheduler + Lambda】

AWS

AWS学習者がまとめたAWSリソースリスト 【随時追記】

RDSを本番環境で使用している場合は、停止することがまずないと思うので、気にする必要はないですが、開発環境では無駄な課金を避けるために停止しておくこともあるかと思います。

しかし、AWSの仕様上、RDSのクラスターやインスタンスは7日後に自動起動されます。今回はこの自動起動したRDS(Aurora)をEventSchedule と Lambda を使用して自動停止する方法について紹介します。

そもそも7日後に自動起動される理由は?

RDSインスタンスやAuroraクラスターは、ハードウェア、基盤となるオペレーティングシステム、データベースエンジンのアップデートやパッチ適用など、AWSによる定期的なメンテナンスが必要であり、長期間停止していると、これらのメンテナンスが適用できず、セキュリティや安定性に影響がでる可能性がある。

そのためAWSはRDSインスタンスやAuroraクラスターを「最大7日間」しか停止できない仕様としており、7日経過後、自動的にインスタンスを起動し、必要なメンテナンス作業を実施できる状態にするということです。

構成図

今回の構成は以下となります。

EventBrige Scheduler → Lambda → RDS(Aurora)の停止

Lambdaの作成

まずはLambda関数を作成していきます。

このLambdaでは、起動したRDSを停止させるための関数(Function)を作成していきます。
実行ロール(execution role)は、Lambda作成時に合わせて作成 + 一部修正していきます。

・Function Name は 「StopAuroraClusterFunc」
・Runtime は 「Python 3.13」
・Architecture は 「x86_64」(インテル製のCPUアーキテクチャ)
・実行ロール(execution role) は 「Create a new role with basic Lambda permissions」
※デフォルトではCloudWatch Logの実行ロールが付与されています。

これらの設定項目を入力後、「Create Function」でLambda関数を作成します。

作成された関数へ付与された実行ロールに、RDSへのアクション(Action)を追加していきます。

作成した関数設定画面内にある「Configuration → Permissions → Role Name」からロールを追加していきます。選択後、ロールの設定画面に遷移します。

既存のポリシー名を選択

「Permissions defined in this policy」の「Edit」を選択

設定画面ではデフォルトのCloudWatch Logsのポリシーが記載されています。そこにRDSへのポリシー(rds:DescribeDBClusters および rds:StopDBCluster)のアクションを追加します。アカウントIDはご自身のものを適用してください。

{
	"Version": "2012-10-17",
	"Statement": [
		{
			"Effect": "Allow",
			"Action": [
				"logs:CreateLogGroup"
			],
			"Resource": "arn:aws:logs:ap-northeast-1:アカウントID:*"
		},
		{
			"Effect": "Allow",
			"Action": [
				"logs:CreateLogStream",
				"logs:PutLogEvents"
			],
			"Resource": [
				"arn:aws:logs:ap-northeast-1:アカウントID:log-group:/aws/lambda/StopAuroraClusterFunc:*"
			]
		},
		{
			"Effect": "Allow",
			"Action": [
				"rds:DescribeDBClusters",
				"rds:StopDBCluster"
			],
			"Resource": [
				"arn:aws:rds:ap-northeast-1:アカウントID:cluster:awsmaster-prod-rds"
			]
		}
	]
}

ロールの追加後、再びLambda関数の画面に戻り、実行する関数のロジックを作成していきます。「Code」を選択します。

以下の実行用のプログラムを記述し、「Deploy」を実施します。
※プログラムの内容についてはご自身で確認をお願いします。

import boto3
import time

rds = boto3.client('rds')

def lambda_handler(event, context):
    cluster_id = 'RDSのクラスタ名'
    
    for _ in range(10):  # 最大10回リトライ(10分想定)
        response = rds.describe_db_clusters(DBClusterIdentifier=cluster_id)
        status = response['DBClusters'][0]['Status']
        
        if status == 'available':
            rds.stop_db_cluster(DBClusterIdentifier=cluster_id)
            print("Stopped DB cluster.")
            return
        else:
            print(f"Current status: {status}. Retrying in 60s.")
            time.sleep(60)
    
    raise Exception("DB cluster did not become available in time.")

これでLambda関数の設定は完了です。

EventBrige Schedulerの作成

続いてEventBrige Schedulerです。

Scheduleの設定は以下の通りです。
今回は毎週土曜日の13時00分にスケジュール(Lambda関数)を実行する設定となります。

・「Schedule name」と「Description」 は 「StopAuroraCluster」
・「Schedule group」 は 「default」
・「Schedule pattern」 は 画像を確認ください
・「Flexible time window」 は 「Off」
※「Cron expression」の指定値についてはこちら

Select targetではEventBrigeからLambdaを呼び出すための設定を行います。

・「Target API」 は 「Templated targets」
・「Target detail」 は 「AWS Lambda – Invoke 」
・「Invoke – Lambda function」 は 先ほど作成したLambda関数を選択

Settings – optionalでは以下を設定を行います。

・「Schedule state」 は 「Enable」
・「Action after schedule completion」 は 「NONE」
・「Permissions – Execution role」 は 「Create new role for this schedule」

EventBrige SchedulerからLambdaへのアクション実行はAWS公式のAPIである「lambda:InvokeFunction」アクション(非同期)で行われているようです。これは今設定した実行ロール(今回で言えば、Amazon_EventBridge_Scheduler_LAMBDA_8771a5421b)から確認できます。ちなみに、Invoke:呼び出す です。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "lambda:InvokeFunction"
            ],
            "Resource": [
                "arn:aws:lambda:ap-northeast-1:アカウントID:function:AuroraClustorStopFunc:*",
                "arn:aws:lambda:ap-northeast-1:アカウントID:function:AuroraClustorStopFunc"
            ]
        }
    ]
}

設定確認画面を確認後、「Create Schedule」でEventBrige Scheduleの設定が完了です

設定は以上となります。

検証確認

EventBrige Scheduleで設定した時間にLambda関数が実行され、RDSが停止するかを確認します。

既存のRDSが起動していることを確認

EventSchedulerで設定した時間に再度RDSの確認

RDSが止まっているのが確認できました。また実行結果は「CloudTrail – Event history」より詳細に確認することもできます。

コメント

タイトルとURLをコピーしました