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

# 概要
タイトルにもある通り、AWSのRDSを自動停止・自動起動する仕組みをつくってみました。
# 背景
最近勉強用にAWSで一つサイトを公開し、請求額を見てみたところRDSのサービスで予想以上に料金が発生してたので、
これはどうにかしないと！と思い色々調べてみました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710430/3000cd5e-2bf2-7e77-e8d8-060f98344701.png)
どうやらRDSのDBインスタンスは、恒久的な「**停止**」が出来なく、7日間経つと自動的にインスタンスが起動してしまうらしい。
なのでしばらく使わないならインスタンスごと「**削除**」する必要があるっぽい。
でも削除してしまうと再度立ち上げるのに時間がかかるので、あくまでも「**停止**」の状態にしておきたい。

7日間ごとに手動で停止作業を行うのも面倒なので、自動で停止や起動を制御できないかを調べてみたところ、Lambdaを使えそうな事が分かりました。
# LambdaによるRDSの自動起動/停止の手順
簡単に手順をまとめていきます。
## ① IAMロールの設定
IAM＞ロールの画面から、「ロールの作成」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710430/687f79a5-89d5-3e97-9380-3e9853ac3760.png)
「信頼されたエンティティタイプ」では「AWSのサービス」を選択。
　「ユースケース」では「Lambda」を選択して「次へ」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710430/0736b773-623a-bc2b-13ac-28ac23e9b68e.png)
許可ポリシーには以下の二つを選択します。それぞれ検索欄で検索してチェックします。
　- AmazonRDSFullAccess
　- CloudWatchFullAccess
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710430/b13b0bbd-93fa-12f7-28b8-317b64e014ce.png)
最後に、ロールの名前を任意に入力し、ロールの作成完了です。
## ② Lambda関数の作成
### RDSインスタンス起動
起動に必要な設定を以下のようにし、Lambda関数を作成します。
<table>
  <thead>
    <tr>
      <th>項目</th> <th>値</th>
    </tr>
  </thead>
  <tr>
    <td> 関数名 </td> <td>（任意の関数名）</td>
  </tr>
  <tr>
    <td> ランタイム </td> <td>Python 3.9</td>
  </tr>
  <tr>
    <td> アーキテクチャ </td> <td>x86_64</td>
  </tr>
  <tr>
    <td> 実行ロール </td> <td>「既存のロールを使用する」＞（①で作成したロールを選択）</td>
  </tr>
</table>

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710430/161e63a2-242e-d555-c30b-97355574170f.png)
「コードソース」のエディタで次のコードを記載し保存(Ctrl+S)した後、「Deploy」を選択します。
```python
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](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710430/a1533254-1bad-b0c7-f080-a10183b08406.png)


続いて、このスクリプトでRDSインスタンスが起動されるかをテストします。
「イベント名」にそれっぽい名前を付けて「保存」し、「テスト」をクリックします。
すると、停止されているRDSのインスタンスが起動されるはずです。（少し時間がかかります）
　![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710430/83043fe0-5332-ea5d-9997-689fbafd7c98.png)
以下は必須ではないですが、スクリプトの実行を失敗させないために「メモリ」を増幅し、「タイムアウト」の時間も延ばしておきます。
・「メモリ」：128MB　→　256MB
・「タイムアウト」：3秒　→　10秒
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710430/15c486db-5e7b-b64f-bd7c-75ed4eb90e33.png)
### RDSインスタンス停止
上記の起動の設定と同じように停止用のLambda関数を作成します。
コードは次のものを使用します。
```python
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](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710430/e2552a58-4420-7dd1-471b-d279761cdcdf.png)


以上です。
# 参考文献
https://aws.amazon.com/jp/premiumsupport/knowledge-center/rds-stop-seven-days/

https://www.t3a.jp/blog/infrastructure/rds-auto-start-stop/