例えば、開発環境などは夜中や休日は使っていないことが多いと思います。
その時間DBを常に動かしているとお金の無駄になります。
Amazon Auroraでは、最大7日間DBインスタンスを停止することができます。
RDS(Aurora)を止めるとどのくらい節約できるのか
https://blog.manabusakai.com/2017/06/stopping-rds/
1 週間のうち、土日と平日深夜から早朝(0 〜 8 時)に停止させると仮定すると、
削減時間は (24 時間 * 2 日) + (8 時間 * 5 日) = 88 時間
削減率は 88 時間 / (24 時間 * 7 日) = 0.5238 (52 %)
この記事によれば、平日深夜と休日に止めるだけで料金の半分を節約することができると書いてあります。
どうやって止めるのか
今回はBoto3(Python)/CloudWatch/Lambda
を使ってRDSを止めていきます。
止める対象のDBは1リージョンにあるDBすべてとなります。
実装はCloudFormationを使って作ります。
実装
前準備
事前にlambda-function-stop-start-rds-<リージョン>-<アカウントID>
という名前でS3バケットを作成します。
※ ここで指定したリージョンのRDSをすべて止めることになります。
aws s3 mb \
s3://lambda-function-stop-start-rds-<リージョン>-<アカウントID> \
--profile <プロファイル> --region <リージョン>
次に、以下のコードをZIPに圧縮してstop-start-rds.zip
という名前で上記のS3へ置きます。
import boto3
import json
client = boto3.client('rds')
def lambda_handler(event, context):
print(event)
cloudWatchEventsArn = event['resources'][0]
if 'start-rds-events' in cloudWatchEventsArn:
start_db_cluster()
elif 'stop-rds-events' in cloudWatchEventsArn:
stop_db_cluster()
def stop_db_cluster():
for DBClusterIdentifier in describe_db_clusters() :
response = client.stop_db_cluster(
DBClusterIdentifier = DBClusterIdentifier
)
def start_db_cluster():
for DBClusterIdentifier in describe_db_clusters() :
response = client.start_db_cluster(
DBClusterIdentifier = DBClusterIdentifier
)
def describe_db_clusters():
clusters = []
response = client.describe_db_clusters()
for DBCluster in response['DBClusters']:
clusters.append(DBCluster['DBClusterIdentifier'])
return clusters
CloudFormationの実行
以下のymlファイルを作成します。
---
AWSTemplateFormatVersion: '2010-09-09'
Description: 'CloudWatch Events -> Lambda -> RDS(Aurora)'
Parameters:
FunctionName:
Type: String
Description: "Lambda Fuction Name"
Default: "lambda-function-stop-start-rds"
SourceFileName:
Type: String
Description: "Lambda Source FileName"
Default: "stop-start-rds.zip"
Resources:
IAMRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service: lambda.amazonaws.com
Action: sts:AssumeRole
ManagedPolicyArns:
- arn:aws:iam::aws:policy/AmazonRDSFullAccess
- arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess
- arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
Path: /
RoleName:
Fn::Join:
- '-'
- - !Ref FunctionName
- !Ref 'AWS::Region'
LambdaFunction:
DependsOn:
- IAMRole
Type: AWS::Lambda::Function
Properties:
Code:
S3Bucket:
Fn::Join:
- '-'
- - !Ref FunctionName
- !Ref 'AWS::Region'
- !Ref 'AWS::AccountId'
S3Key: !Ref SourceFileName
FunctionName: !Ref FunctionName
Handler: lambda_function.lambda_handler
MemorySize: 1024
Role: !GetAtt IAMRole.Arn
Runtime: python3.7
Timeout: 60
StopRdsEventRule:
DependsOn:
- LambdaFunction
Type: "AWS::Events::Rule"
Properties:
Name: "stop-rds-events"
Description: !Ref FunctionName
ScheduleExpression: "cron(0 16 ? * MON-FRI *)"
State: "ENABLED"
Targets:
- Arn: !GetAtt LambdaFunction.Arn
Id: LambdaFunction
StartRdsEventRule:
DependsOn:
- LambdaFunction
Type: "AWS::Events::Rule"
Properties:
Name: "start-rds-events"
Description: !Ref FunctionName
ScheduleExpression: "cron(0 22 ? * SUN-THU *)"
State: "ENABLED"
Targets:
- Arn: !GetAtt LambdaFunction.Arn
Id: LambdaFunction
CloudFormationでスタックを作成します。
※ 最初に作成したS3と同じリージョンに作成してください。
※ stop-start-rds.ymlがあるディレクトリで実行してください。
aws --profile "<プロファイル>" --region "<リージョン>" \
cloudformation create-stack \
--stack-name stop-start-rds \
--template-body file://stop-start-rds.yml \
--capabilities CAPABILITY_NAMED_IAM
CloudFormationのコンソールでスタックが作成されれば完了です。
所感
実際にいくら安くなっているのかは一ヶ月経たないとわかりませんが、
RDSのインスタンス自体はCloudWatchメトリクスを見ると止まっているのが確認できました。
意外と簡単に作れるのでおすすめです。
どうでもいいこと
最近のおすすめの曲:https://www.youtube.com/watch?v=BuP1R6MKyns
皆さん、良いお年を〜