AWS SAM で RDS のシャットダウン状態を維持する方法
デフォルトでは、 RDS は永続的にシャットダウンできず、7日後に再起動されます。
You can stop a DB instance for up to seven days. If you don’t manually start your DB instance after seven days, your DB instance is automatically started so that it doesn’t fall behind any required maintenance updates.
不要な RDS インスタンスを実行するとコストがかかるため、 AWS SAM で RDS のシャットダウン状態を維持すると有用かもしれません。
前提条件
以下のソフトウェアをインストールしてください。
- AWS SAM
- Python 3.x
SAM アプリケーション作成
ディレクトリ構成
/
|-- rds_shutdown/
| |-- app.py
| `-- requirements.txt
|-- samconfig.toml
`-- template.yaml
AWS SAM テンプレート
以下の例では Lambda トリガーとして cron 式(24行目)を使用していますが、 EventBridge の RDS イベントがより適切な選択肢です。
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: Using a CloudWatch Events rule, RdsShutdown keeps an RDS instance shutdown after 1 week.
Parameters:
RdsDbInstance:
Type: String
Resources:
RdsShutdownFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: rds_shutdown/
Environment:
Variables:
DB_INSTANCE: !Ref RdsDbInstance
Events:
# CloudWatch Events Rule
ScheduleEvent:
Type: Schedule
Properties:
Description: An event rule for RdsShutdownFunction
Enabled: True
Schedule: 'cron(* */1 * * ? *)' # every hour
FunctionName: rds_shutdown
Handler: app.lambda_handler
MemorySize: 128
Role: !GetAtt IamRole.Arn
Runtime: python3.8
Timeout: 10
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/service-role/AWSLambdaBasicExecutionRole
Policies:
- PolicyName: policy1
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- rds:DescribeDBInstances
- rds:StopDBInstance
Resource: !Sub arn:aws:rds:*:${AWS::AccountId}:db:${RdsDbInstance}
RoleName: rds-shutdown
LogsLogGroup:
Type: AWS::Logs::LogGroup
Properties:
LogGroupName: !Sub /aws/lambda/${RdsShutdownFunction}
RetentionInDays: 30
Python スクリプト
requirements.txt
空のままにしてください。
AWS Lambda ランタイム環境には、デフォルトで boto3
がインストールされているため、 requirements.txt
に含める必要はありません。
app.py
次のスクリプトは、 RDS インスタンスのステータスが available
の場合にのみ停止します。
import logging
import os
import boto3
# Environment Variables
DB_INSTANCE = os.environ.get('DB_INSTANCE')
logger = logging.getLogger()
logger.setLevel(logging.INFO)
client = boto3.client('rds')
def lambda_handler(event, context):
if not DB_INSTANCE:
# Exit when a DB Instance is not specified.
logger.error('DB_INSTANCE environment variable is not specified.')
return
# Get the DB Instance status.
status = get_db_instance_status(DB_INSTANCE)
if status == 'available':
# Stop when the status is available.
client.stop_db_instance(DBInstanceIdentifier=DB_INSTANCE)
logger.info(f'DB instance - {DB_INSTANCE} - has been stopped.')
def get_db_instance_status(db_instance: str) -> str:
# See https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Overview.DBInstance.Status.html
response = client.describe_db_instances(DBInstanceIdentifier=db_instance)
return response['DBInstances'][0]['DBInstanceStatus']
samconfig.toml
実際の値で <YOUR_S3_BUCKET>
および <YOUR_RDS_INSTANCE_NAME>
を置き換えてください。
version = 0.1
[default]
[default.deploy]
[default.deploy.parameters]
stack_name = "rds-shutdown"
s3_bucket = "<YOUR_S3_BUCKET>"
s3_prefix = "rds-shutdown"
region = "ap-northeast-1"
capabilities = "CAPABILITY_IAM CAPABILITY_NAMED_IAM"
parameter_overrides = "RdsDbInstance=\"<YOUR_RDS_INSTANCE_NAME>\""
ビルドとデプロイ
以下のコマンドでビルドおよびデプロイしてください。
sam build
sam deploy
テスト
RDS インスタンスを停止して、7日間放置し、 Lambda ログを確認してください。 以下のレコードが含まれているはずです。
DB instance - database-1 - has been stopped.
以下のコマンドで RDS インスタンスのステータスが stopped
であることを確認してください。
$ aws rds describe-db-instances --db-instance-identifier <YOUR_RDS_INSTANCE_NAME> | grep DBInstanceStatus
"DBInstanceStatus": "stopped",
まとめ
RDS は永続的にシャットダウンできないことを覚えておくと良さそうです。
この投稿が、お役に立てば幸いです。