RDSは起動しっぱなしだとお金がかかる。
しかし、停止しても7日後に再度起動してしまう。
特に検証用とかで使用しない間が多い場合、いちいち起動したら停止するという運用はかなり面倒。
そのため、検証時以外は、起動したらすぐ停止するというスクリプトを作成して、無駄なコストがかからないようにする。
そこで使用するのが、AWSのLambdaを使う。
Lambdaとは何?
Lambdaと聞いてもわからないので調べた。
AWSの「サーバレスコンピューティングとアプリケーション」と言われる。
これまではPHPやPythonをうごかすためのwebサーバーが必要だったが、Lambdaならサーバーレスのため、サーバーを準備しなくても環境が揃っていると言うことである。
LambdaはJava、Node.js、C#、Pythonのプログラミング言語に対応しているので、各種「機能」(プログラム)はこの言語で開発すればOK、ということのようです。
「S3にアップされた画像のサムネイル化」で考えると、S3に画像ファイルがアップされるのを監視するためのサーバを用意して、監視し続けるプログラムを用意して、ファイルがアップされたことを検知したら、リサイズする処理を行う必要があったのが、Lambdaならこの「リサイズする処理」だけを作ればOKということ。
今回はこのLambdaを利用し、指定された時間に関数を実行すると言うことを実装し、RDSの起動停止を自動で実施する。
流れ
IAMによるロール(権限)作成
IAMページでロールの作成を実施。
「信用されたエンティティの種類を選択」については、「AWS サービス」を選択。「このロールを使用するサービスを選択」は「Lambda」を選択します。
Attach(アタッチ)する権限ポリシーは、
・CloudWatchFullAccess
・AmazonRDSFullAccess
Lambdaの設定でStartとStopの関数を作成
Lambdaで関数を作成する。関数はStartとStopの二つ。
スクリプトは下記を登録する。
import boto3
region = 'ap-northeast-1'
instance = 'RDSインスタンス名'
def lambda_handler(event, context):
rds = boto3.client('rds', region_name=region)
rds.start_db_instance(DBInstanceIdentifier=instance)
print('started instance: ' + instance)
import boto3
region = 'ap-northeast-1'
instance = 'RDSインスタンス名'
def lambda_handler(event, context):
rds = boto3.client('rds', region_name=region)
rds.stop_db_instance(DBInstanceIdentifier=instance)
print('stoped instance: ' + instance)
また、関数起動を自動でやるため、cronで動かすようにも設定する。
cronによる起動はトリガーの追加で「CloudWatch Events」を選択する。
〇RDS の起動時間
cron(15 23 */6 * ? *)
〇RDS の停止時間
cron(45 23 0/6 * ? *)
テスト
起動が大丈夫かをテストできる。
失敗したらスクリプトをチェックする。
RDS 自動停止を実装する際の実行時間の考え方
設定に関して少し蛇足になりますが、RDS インスタンスが7日後に再起動する仕様について。
コストを下げる基本的な考え方として、AWS 側のシステムで再起動を発生させないことが良いと思います。
そのため一定時間ごとに RDS を起動して1時間以内に停止命令を送る実装をすれば良いです。
※aws は1時間以内の起動時間は1時間の使用としてコストが計上されるため
そこで今回は6日間隔で1時間以内の起動と停止を繰り返す設定を行っています。
つまり毎月1日、7日、13日、19日、25日、29日にスクリプトを実行します。
参考記事