14Room

みんな泣きながらオトナになったんだ。

LambdaでRDSを定期的にスケールアップ・ダウンさせてみた

概要

普段はmicroインスタンスで十分だけど、重いSQLを実行するときだけsmallにしたいという要件を満たすために、 Lambdaを使ってサーバレスでRDSを定期的にスケールアップさせてみました。

ここではスケールアップする方法のみ記述してますが、業務時間終了後またmicroに戻す処理も実装してコストの上昇を最小限に止めてみました。

設定

Lambda

AWS-Services-Lambdaで「Create a Lambda Function」をクリック。 f:id:naked123:20160211213910j:plain

ひな形になる「hello-world-python」を選択。 「Name」をScaleUpReadDBとし、「Runtime」にはpython 2.7を選択。

肝心の「Lambda function code」はEdit code inlineで直接下記のコードを入力しました。

import boto3
 
def lambda_handler(event, context):
    client = boto3.client('rds')
    response = client.modify_db_instance(
        DBInstanceIdentifier='readonlyrds',
        DBInstanceClass='db.t2.small',
        ApplyImmediately=True
    )
    print response

readonlyrdsは実際にスケールアップさせたいRDSの名前です。ちなみにApplyImmediately=Trueを指定しないとコマンドは成功しても変更が即時反映されないため気を付けましょう。

f:id:naked123:20160211220249j:plain

「Role」では「Basic execution role」を新規で作ります。詳細については次のIAM roleで述べます。

また「Timeout」はデフォルトで3sとなってますが、時々3秒以内に処理が終わらずエラーとなるので10sを設定しました。

IAM role

Lambda Function作成時にBasic execution roleを新規作成すると下記の画面に移りますので「Hide Policy Document」をeditして適切な権限を付与します。

f:id:naked123:20160211220906j:plain

今回は下記のような感じにしてみました。

 {
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "rds:*",
                "cloudwatch:DescribeAlarms",
                "cloudwatch:GetMetricStatistics",
                "ec2:DescribeAccountAttributes",
                "ec2:DescribeAvailabilityZones",
                "ec2:DescribeSecurityGroups",
                "ec2:DescribeSubnets",
                "ec2:DescribeVpcs",
                "sns:ListSubscriptions",
                "sns:ListTopics",
                "logs:DescribeLogStreams",
                "logs:CreateLogGroup",
                "logs:CreateLogStream",
                "logs:PutLogEvents",
                "logs:GetLogEvents"
            ],
            "Resource": "arn:aws:rds:ap-northeast-1:xxxxxx123456789:db:readonlyrds"
        }
    ]
}

IAM roleを作成するとLambda作成画面に戻るので、そのままnextをクリック、詳細確認して作成。

Lambdaのcron実行指定

Lambdaは作成しただけでは実行されないので、cronで実行時刻を指定します。 作成したLambdaの「Event Sources」で「Add event source」をクリック。 「Event source type」で「CloudWatch Events - Schedule」を選択すると下記のようなダイアログが出現するので設定して「Submit」して終了。

f:id:naked123:20160211234256j:plain

上の例では月曜日から金曜日の日本時間の朝9時1分(UTC 0:01)にLambda Functionが実行されます。

あとがき

やってみると意外と簡単だなというのが正直な感想です。普段コードを書かないインフラエンジニアでもワンパス通せば雰囲気も掴めて、いろんな事に応用できそうだと思ってもらえるはずです。