0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

[AWS] RDSの自動停止・自動起動の仕組みを作ってみた

Posted at

概要

タイトルにもある通り、AWSのRDSを自動停止・自動起動する仕組みをつくってみました。

背景

最近勉強用にAWSで一つサイトを公開し、請求額を見てみたところRDSのサービスで予想以上に料金が発生してたので、
これはどうにかしないと!と思い色々調べてみました。
image.png
どうやらRDSのDBインスタンスは、恒久的な「停止」が出来なく、7日間経つと自動的にインスタンスが起動してしまうらしい。
なのでしばらく使わないならインスタンスごと「削除」する必要があるっぽい。
でも削除してしまうと再度立ち上げるのに時間がかかるので、あくまでも「停止」の状態にしておきたい。

7日間ごとに手動で停止作業を行うのも面倒なので、自動で停止や起動を制御できないかを調べてみたところ、Lambdaを使えそうな事が分かりました。

LambdaによるRDSの自動起動/停止の手順

簡単に手順をまとめていきます。

① IAMロールの設定

IAM>ロールの画面から、「ロールの作成」をクリックします。
image.png
「信頼されたエンティティタイプ」では「AWSのサービス」を選択。
 「ユースケース」では「Lambda」を選択して「次へ」をクリックします。
image.png
許可ポリシーには以下の二つを選択します。それぞれ検索欄で検索してチェックします。
 - AmazonRDSFullAccess
 - CloudWatchFullAccess
image.png
最後に、ロールの名前を任意に入力し、ロールの作成完了です。

② Lambda関数の作成

RDSインスタンス起動

起動に必要な設定を以下のようにし、Lambda関数を作成します。

項目
関数名 (任意の関数名)
ランタイム Python 3.9
アーキテクチャ x86_64
実行ロール 「既存のロールを使用する」>(①で作成したロールを選択)

image.png
「コードソース」のエディタで次のコードを記載し保存(Ctrl+S)した後、「Deploy」を選択します。

import boto3

region = 'ap-northeast-1'
rds = boto3.client('rds', region_name=region)

def lambda_handler(event, context):

    #Start DB Instances
    dbs = rds.describe_db_instances()
    for db in dbs['DBInstances']:
        #Check if DB instance stopped. Start it if eligible.
        if (db['DBInstanceStatus'] == 'stopped'):
            try:
                result = rds.start_db_instance(DBInstanceIdentifier=db['DBInstanceIdentifier'])
                print ("Starting instance: {0}.".format(db['DBInstanceIdentifier']))
            except Exception as e:
                print ("Cannot start instance {0}.".format(db['DBInstanceIdentifier']))
                print(e)
                

if __name__ == "__main__":
    lambda_handler(None, None)

image.png

続いて、このスクリプトでRDSインスタンスが起動されるかをテストします。
「イベント名」にそれっぽい名前を付けて「保存」し、「テスト」をクリックします。
すると、停止されているRDSのインスタンスが起動されるはずです。(少し時間がかかります)
 image.png
以下は必須ではないですが、スクリプトの実行を失敗させないために「メモリ」を増幅し、「タイムアウト」の時間も延ばしておきます。
・「メモリ」:128MB → 256MB
・「タイムアウト」:3秒 → 10秒
image.png

RDSインスタンス停止

上記の起動の設定と同じように停止用のLambda関数を作成します。
コードは次のものを使用します。

import boto3

region = 'ap-northeast-1'
rds = boto3.client('rds', region_name=region)

def lambda_handler(event, context):

    #Stop DB instances
    dbs = rds.describe_db_instances()
    for db in dbs['DBInstances']:
        #Check if DB instance is not already stopped
        if (db['DBInstanceStatus'] == 'available'):
            try:
                result = rds.stop_db_instance(DBInstanceIdentifier=db['DBInstanceIdentifier'])
                print ("Stopping instance: {0}.".format(db['DBInstanceIdentifier']))
            except Exception as e:
                print ("Cannot stop instance {0}.".format(db['DBInstanceIdentifier']))
                print(e)
                

if __name__ == "__main__":
    lambda_handler(None, None)

③ スケジューリング

②で作成した二つのLambda関数にスケジューリングの設定をし、実行する時間を指定します。
私の場合、毎週日曜日の21:30に自動起動、23:00に自動停止するように設定しました。

Lambda>「トリガーを追加」から設定できます。
ルール名やスケジュール式は起動/停止用に調整して下さい。(cron式の細かい説明などは今回は省きます)
image.png

以上です。

参考文献

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?