Amazon RDS インスタンスを 7 日以上停止する方法を教えて下さい。

最終更新日: 2021 年 10 月 18 日

Amazon Amazon Relational Database Service (Amazon RDS) を 7 日間以上停止したいと思っています。

簡単な説明

Amazon RDS インスタンスは数分以内に簡単に開始および停止できます。この機能は、常時実行している必要がないデータベースのコスト削減をサポートします。データベースインスタンスは最大 7 日間まで停止できます。7 日後に DB インスタンスを手動で起動しない場合、インスタンスは自動的に起動されます。これは、ハードウェア、基盤となるオペレーティングシステム、またはデータベースエンジンのバージョンに必要なメンテナンス更新でインスタンスが遅れないようにするためです。

必要なメンテナンス更新を逃さず RDS インスタンスを 7 日間以上停止するには、次の手順を実行します。

  1. AWS Identity アクセス管理 (IAM) のアクセス許可をセットアップして、AWS Lambda が次のことを実行できるようにします。インスタンスを起動します。インスタンスを停止します。インスタンスに関する情報を取得します。
  2. 自動的に開始および停止する RDS インスタンスのタグを追加します。
  3. Lambda 関数を作成して DB インスタンスを起動します。
  4. DB インスタンスを停止する Lambda 関数を作成します。
  5. 次のことを実行するスケジュールを作成します。毎週のメンテナンスウィンドウの始めに DB インスタンスを開始します。メンテナンスウィンドウが終了した時点で DB インスタンスを停止します。

解決方法

IAM アクセス許可の設定

IAM ポリシーを作成して、Lambda がインスタンスを開始および停止し、インスタンスに関する情報を取得することを許可します。

1.    [IAM コンソール] を開きます。

2.    ナビゲーションペインで、[Policies] を選択します。

3.    [Create policy] (ポリシーを作成) を選択します。

4.    [JSON] タブを選択します。

5.    次のポリシーをコピーし、[JSON] タブの下にポリシーを貼り付けて、必要な IAM アクセス許可を付与します。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "rds:StartDBCluster",
                "rds:StopDBCluster",
                "rds:ListTagsForResource",
                "rds:DescribeDBInstances",
                "rds:StopDBInstance",
                "rds:DescribeDBClusters",
                "rds:StartDBInstance"
            ],
            "Resource": "*"
        }
    ]
}

6.    [Next: Tags] (次のステップ: タグ) を選択します。

7.    (オプション) タグを追加するには、[Add tag] を選択し、[Key] および [Value - optional] フィールドに適切な値を入力します。

8.    [次へ: レビュー] を選択します。

9.    [ポリシーの確認] ページで、[名前] に ポリシーの名前を入力します。[Summary] セクションで、ポリシーによって付与されているアクセス許可を確認します。

10.    [Create policy] (ポリシーを作成) を選択します。

詳細については、「JSON タブでのポリシーの作成」を参照してください。

IAM ロールを作成し、必要なポリシーをアタッチする

  1. [IAM コンソール] を開きます。
  2. ナビゲーションペインで [ロール] を選択します。
  3. [ロールの作成] を選択します。
  4. [信頼されたエンティティの種類を選択] で、[AWS のサービス] を選択します。
  5. [Or select a service to view its use cases] で、[Lambda] を選択します。
  6. [次へ: アクセス許可] を選択します。
  7. [Filter-Policies] には、前のセクションで作成したポリシーの名前を入力します。作成したポリシーが表示されたら、ポリシーを選択します。[Filter-policies] に、「AWSLambdaBasicExecutionRole」を入力します。作成した管理ポリシー「AWSLambdaBasicExecutionRole」が表示されたら、ポリシーを選択します。
  8. [Next: Tags] (次のステップ: タグ) を選択します。
  9. (オプション) タグを追加するには、[Key] および [Value (optional)] フィールドに適切な値を入力します。
  10. [次へ: レビュー] を選択します。
  11. [ロールの作成] ページの [ロール名] に、作成するロールの名前を入力します。
  12. [ロールの作成] を選択します。

詳細については、「AWS のサービス用ロールの作成 (コンソール)」を参照してください。

DB インスタンスのタグの追加

  1. Amazon RDS コンソールを開きます。
  2. ナビゲーションペインで [データベース] をクリックします。
  3. 自動的に開始および停止する DB インスタンスを選択します。
  4. 詳細セクションで、[Tags] セクションまでスクロールします。
  5. [Tags] タブで、[Add] を選択します。[Tag key] に「autostart」と入力します。[Value] に「yes」と入力します。[Add] を選択して変更を保存します。
  6. [Add] をクリックします。[Tag key] に「autostop」と入力します。[Value] に「yes」と入力します。[Add] を選択して変更を保存します。

詳細については、「タグの追加、一覧表示、および削除」をご参照ください。

Lambda 関数を作成してタグ付けされた DB インスタンスを起動する

1.    Lambda コンソールを開きます。

2.    ナビゲーションペインで [Functions] を選択します。

3.    [Create function] を選択します。

4.    [Author from scratch] を選択します。

5.    [Function-name] に関数の名前を入力します。

6.    [Runtime] で Python 3.7 を選択します。

7.    [アーキテクチャ] は、デフォルトの選択である「x86_64」のままにします。

7.    [Change default execution role] を展開します。

8.    [実行ロール] で [既存のロールを使用する] を選択します。

9.    [Existing role] で、前に作成した IAM ロールを選択します。

10.    [Create function] を選択します。

11.    [Code] タブを選択します。

12.    [Code source] エディタで、サンプルコードを削除し、次のコードを貼り付けます。

import boto3
rds = boto3.client('rds')

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'):
            doNotStart=1
            try:
                GetTags=rds.list_tags_for_resource(ResourceName=db['DBInstanceArn'])['TagList']
                for tags in GetTags:
                #if tag "autostart=yes" is set for instance, start it
                    if(tags['Key'] == 'autostart' and tags['Value'] == 'yes'):
                        result = rds.start_db_instance(DBInstanceIdentifier=db['DBInstanceIdentifier'])
                        print ("Starting instance: {0}.".format(db['DBInstanceIdentifier']))
                if(doNotStart == 1):
                    doNotStart=1
            except Exception as e:
                print ("Cannot start instance {0}.".format(db['DBInstanceIdentifier']))
                print(e)
                

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

13.    [File]、[Save] を選択した後、[Deploy] を選択します。

15.    [Configuration] タブ、[General configuration] を選択し、その後 [Edit] を選択します。

16.    [タイムアウト] で、次の操作を行います。[] に [0] を選択します。[] は [10] を選択します。17.    [保存] を選択します。

Lambda 関数を作成してタグ付けされた DB インスタンスを停止します。

タグ付けされた DB インスタンスを停止する Lambda 関数を作成するには、前のセクション [Create a Lambda function to start the tagged DB instances] の手順を使用して、次の変更を行います。

[Code source] エディタで、サンプルコードを削除し、次のコードを貼り付けます。

import boto3
rds = boto3.client('rds')

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'):
            DoNotStop=1
            try:
                GetTags=rds.list_tags_for_resource(ResourceName=db['DBInstanceArn'])['TagList']
                for tags in GetTags:
                #if tag "autostop=yes" is set for instance, stop it
                    if(tags['Key'] == 'autostop' and tags['Value'] == 'yes'):
                        result = rds.stop_db_instance(DBInstanceIdentifier=db['DBInstanceIdentifier'])
                        print ("Stopping instance: {0}.".format(db['DBInstanceIdentifier']))
                if(DoNotStop == 1):
                    DoNotStop=1
            except Exception as e:
                print ("Cannot stop instance {0}.".format(db['DBInstanceIdentifier']))
                print(e)
                
if __name__ == "__main__":
    lambda_handler(None, None)

関数テストの実行

タグ付けされた DB インスタンスが停止状態であるとします。関数テストを実行するには、次の手順を実行します。

  1. [Lambda 関数] リストを開きます。
  2. DB インスタンスを起動するために作成した関数を選択します
  3. [Actions]、[Test] の順にクリックします。
  4. [Test] タブの [Name] に、イベントの名前を入力します。
  5. [Save changes] を選択し、その後 [Test] を選択します。

スケジュールの作成

タグ付けされた DB インスタンスの毎週のメンテナンスウィンドウが日曜日午後 10:00~午後 10:30 であるとします。スケジュールをセットアップするには、次のルールを 2 つ作成します。

  • メンテナンスウィンドウが開始する 30 分前に DB インスタンスを自動的に起動する
  • メンテナンスウィンドウが終了してから 30 分後に DB インスタンスを自動的に停止する

メンテナンスウィンドウの 30 分前に DB インスタンスを自動的に起動するルールを作成するには、次の操作を行います。

  1. [Lambda 関数] リストを開きます。
  2. DB インスタンスを起動するために作成した関数を選択します。
  3. [Function overview] で、[Add trigger] を選択します。
  4. [EventBridge (CloudWatch Events)] を選択し、[Create a new rule] を選択します。
  5. [Rule name] に、作成するルールの名前を入力します。
  6. [Schedule Expression] で、自動スケジュールの cron 式を追加します (例: cron(30 21 ? * SUN *))。
  7. [追加] を選択します。

同じ手順を使用して、メンテナンスウィンドウの 30 分後に DB インスタンスを自動的に停止する別のルールを作成します。必ず自動スケジュールのルール名と cron 式を適宜変更してください (例: cron(00 23 ? * SUN *))。