RDS の自動停止

2020年5月14日

はじめに

一時的にしか使わない RDS インスタンスの停止忘れを避けるため、RDS インスタンスを自動的に停止させる。

Lambda による RDS インスタンスの停止

AWS SDK for JavaScript を用いる。

const AWS = require("aws-sdk");
AWS.config.update({ region: process.env.AWS_REGION });


exports.handler = async (event) => {
    const rds = new AWS.RDS({apiVersion: '2014-10-31'});

    const params = {
        DBInstanceIdentifier: process.env.DB_INSTANCE_NAME
    };

    await rds.describeDBInstances(params).promise().then(async data => {
        const instance = data.DBInstances[0];
        if (instance.DBInstanceStatus === "available") {
            console.log(`Stopping ${process.env.DB_INSTANCE_NAME} ...`);

            await rds.stopDBInstance(params).promise().then(result => {
                //console.log(result);
            })
            .catch(err => {
                console.log(err);
            });
        }
    })
    .catch(err => {
        console.log(err);
    });

    const response = {
        statusCode: 200,
        body: JSON.stringify(""),
    };

    return response;
};

環境変数 DB_INSTANCE_NAME に RDS のインスタンス名を設定しておく。インスタンスのステータスが利用可能 ("available") であれば、インスタンスを停止する。ロールには RDS のアクセス権限を与えておく。RDS の操作を行うからといって、VPC に入れる必要はない (入れてはいけない) ので注意。

定期呼び出し

CloudWatch のイベントで Lambda 関数を呼び出す。たとえば、毎日日本時間の 22:00 に呼び出すなら、cron 形式で次のようにする (GMT なので日本時間の 9 時間前に設定する)。

0 13 * * ? *

Lambda でインスタンスの停止と起動を実装して、CloudWatch で停止イベントと起動イベントを設定すれば、土日だけ停止する (金曜日夜に停止して月曜朝に起動する) ということもできる。

上記の指定は、"分 時 日 月 曜日 年" となっている。"?" は、曜日と日を同時に指定できないためのものらしい。どちらかを指定 ("*" も含む) している場合は、もう一方は "?" にする。たとえば、日本時間の月曜日から金曜日の夜 22:00 に実行するには、次のようにする。

0 13 ? * MON-FRI *

日本時間の月曜日から金曜日の朝 7:00 に実行といった指定が少しややこしくて、9 時間前なので曜日が前日の曜日になる。

0 22 ? * SUN-THU *

JSON による入力で停止・起動を切り替えるには、たとえば次のようにする。

exports.handler = async (event) => {
    const action = event.action;

    ...
    if (action === "stop") {
        ...

入力は次のようにする。

{"action": "stop"}

継続的停止

RDS のインスタンスは停止後 7 日後に自動起動する。インスタンスをしばらく止めておきたいが削除するほどでもない、というときに困る。そこで、継続的停止の方法として、6 日ごとに自分でちょっと起動してすぐ止める、という方法が考えられる。たとえば、6 日ごとに日本時間 22:00〜22:30 の間だけ起動するなら、次のようにする。

起動

0 13 */6 * ? *

停止

30 13 */6 * ? *