LambdaでRDSを定期的にスケールアップ・ダウンさせてみた
概要
普段はmicroインスタンスで十分だけど、重いSQLを実行するときだけsmallにしたいという要件を満たすために、 Lambdaを使ってサーバレスでRDSを定期的にスケールアップさせてみました。
ここではスケールアップする方法のみ記述してますが、業務時間終了後またmicroに戻す処理も実装してコストの上昇を最小限に止めてみました。
設定
Lambda
AWS-Services-Lambdaで「Create a Lambda Function」をクリック。
ひな形になる「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
を指定しないとコマンドは成功しても変更が即時反映されないため気を付けましょう。
「Role」では「Basic execution role」を新規で作ります。詳細については次のIAM roleで述べます。
また「Timeout」はデフォルトで3sとなってますが、時々3秒以内に処理が終わらずエラーとなるので10s
を設定しました。
IAM role
Lambda Function作成時にBasic execution roleを新規作成すると下記の画面に移りますので「Hide Policy Document」をeditして適切な権限を付与します。
今回は下記のような感じにしてみました。
{ "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」して終了。
上の例では月曜日から金曜日の日本時間の朝9時1分(UTC 0:01)にLambda Functionが実行されます。
あとがき
やってみると意外と簡単だなというのが正直な感想です。普段コードを書かないインフラエンジニアでもワンパス通せば雰囲気も掴めて、いろんな事に応用できそうだと思ってもらえるはずです。