システムズのマイグレーションコラム
Vol.25 AWS DBマイグレーション時のコスト削減アプローチ
2020.04.16
AWSで実践!DBマイグレーション時のRDS利用コスト削減
レガシーシステムのマイグレーションでは、移行先の本番環境の準備はもちろんのこと、開発環境用に、例えばオンプレミスの場合など、新たにサーバーを購入する場合があります。マイグレーションが完了した後、オンプレミスの場合は、開発環境用に購入したサーバーへの投資コストが、マイグレーション費用の中にかかってきています。
クラウド環境へのマイグレーションの場合も、本番環境と開発環境の準備までは同じですが、マイグレーションが完了した後、開発環境用に準備したクラウド基盤は利用契約を解除することで、オンプレミスのような、サーバーの保有コストによる圧迫から脱却することが可能となります。
さらに、AWSが提供するクラウドサービスでは、移行先の開発環境の利用中においても、従量課金型サービスであれば、使用しない時間帯を設定することで、コスト削減につなげることができるようになります。
今回の記事では、AWSのサービス「CloudWatch Events(イベントのスケジュール)」と、AWS Lambda(起動・停止処理)を組み合わせた、自動起動・停止の設定方法をご紹介します。
目次
はじめに
AWSへのDBマイグレーションの際には、
本番環境以外にも、ステージング環境などに検証・テスト用のRDSインスタンスを構築する場合が多いので、利用コストがその分多くかかります。
EC2やRDSなどの従量課金のサービスでは、
開発環境や検証環境など、24時間稼働する必要がないインスタンスは、
夜間は自動的に停止する事で大幅にコストカット出来ます。
本記事では、RDSインスタンスの自動起動・停止の設定方法についてご紹介します。
概要
AWSでRDSインスタンスの起動・停止スケジュールを行うには、
以下のサービスを組み合わせて実現します。
・CloudWatch Events(イベントのスケジュール)
・Lambda(起動・停止処理)
CloudWatch Eventsは、cronのようにスケジュールしたタイミングでイベントを発生させて、
Lambdaなど他のAWSサービスを任意のタイミングで呼び出す事ができます。
RDSインスタンスを「平日の8時に起動するイベント」と「起動用のLambda」、
「20時に停止するイベント」と「停止用のLambda」をそれぞれ作成します。
Lambdaは、JavaやPython、GO、NodeJSなどの言語で処理を記述できますが、
今回は、Pythonで作成していきます。
準備
LambdaがRDSを操作する権限を付与するために、IAMロールが必要になりますので、
先にそちらを準備していきます。
IAMポリシーの作成
まずは、IAMのポリシーを作成します。
IAMロールとIAMポリシーの用語の違いは以下です。
- ・IAMポリシー(Policy)
- 「AWSリソースにアクセスするための権限設定」で、ユーザやロールにアタッチされて使用される。
- ・IAMロール(Role)
- 「AWSリソースに付与するもの」で、いくつかのIAMポリシーをグルーピングできる。
ポリシーに「インスタンスの参照」「インスタンスの起動」「インスタンスの停止」という権限だけを
設定しておくことで、誤って他の操作(削除など)を行ったり、意図しない事故を防ぐ事ができます。
IAMの画面から、「ポリシー」を選択して、「ポリシーの作成」を押します。
「JSON」タブを選択して、直接ポリシーをJSONで入力します。
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditorStartStopDB",
"Effect": "Allow",
"Action": [
"rds:DescribeDBInstances",
"rds:StopDBInstance",
"rds:StartDBInstance"
],
"Resource": "arn:aws:rds:*:*:db:*"
}
]
}
名前と説明を入力して、「ポリシーの作成」を押します。
IAMロールの作成
次は、作成したポリシーをロールと関連づけます。
ロールのメニューから「ロールの作成」を押します。
AWSサービスから、「Lambda」を選択して「次のステップ:アクセス権限」を押します。
先ほど作成したポリシーを探してチェックし、次に進みます。
タグは任意です。そのまま進めても大丈夫です。
ロール名と説明を入力して、「ロールの作成」を押します。
Lambdaとイベントの作成
次は、Lambdaの作成と、
同じ画面からCloudWatch Eventsも作成と関連づけを同時に行っていきます。
Lambdaのメニューから、「関数の作成」を押します。
停止設定
関数作成
Lambdaを作成する際、ブループリントから雛形を作成できますが、
今回は事前にソースを用意しているので「一から作成」を選択します。
Runtimeは「Python 3.x」、「実行ロールの選択または作成」から、
このLambdaに付与するロールを選択します。
「既存のロールを使用する」で、先ほど作成したロールを選択して、
「関数の作成」を押して進みます。
関数コードの中に、下記ソースをコピーして上書きます。
import boto3
# RDSインスタンスDB識別子のリスト
rds_ids = [
'instanceA',
'instanceB'
]
def lambda_handler(event, context):
rds = boto3.client('rds')
# リストの要素が0の場合は何もしない
if len(rds_ids) == 0:
print('対象インスタンスがありません。')
else:
for i in rds_ids:
response = rds.describe_db_instances(DBInstanceIdentifier=i)
rds_status = response["DBInstances"][0]["DBInstanceStatus"]
print(rds_status)
# ステータスが「stopped」の場合
if rds_status == "stopped":
print('既にインスタンスが停止しています。:' + str(i))
elif rds_status == "available":
rds.stop_db_instance(DBInstanceIdentifier=i)
print('インスタンスを停止しました。:' + str(i))
else:
# それ以外の場合
print('ステータスが変更途中です。:' + str(i))
return 'インスタンスの停止処理を終了します。'
例えば、下図のRDSインスタンスを停止したい場合。
ソース上部のリストに、
停止したいインスタンスのDB識別子をカンマ区切りで入力します。
関数のテスト
画面右上の「保存」を押してから、隣の「テスト」でファンクションを動かしてみます。
イベント名を適当に入力して、「作成」を押します。
その後、再度「テスト」を押します。
正常に実行できれば、下図のように緑色の画面で「実行結果:成功」と表示されます。
RDSの画面で確認すると、2つとも停止中のステータスになっていました。
実行のスケジューリング
次は、平日20時に実行してくれるようにスケジューリングの設定を行います。
Lambdaの画面で「トリガーを追加」を押します。
「CloudWatch Events/EventsBridge」を選択します。
「新規ルールの作成」を選択して、次のように入力します。
※平日 月₋金 20時に停止する場合
cron(0 11 ? * MON-FRI *)
CloudWatch Eventsのcron式は、協定世界時(UTC)で入力するため、
日本標準時(JST)との差は +9時間 になるため注意が必要です。
Eventをトリガーする時間は、適宜変更して利用してください。
全て入力したら「追加」を押します。
一番下の「CloudWatch Events/EventBridge」が
「有効」になっている事を確認して設定は完了です。
起動設定
起動設定も停止の時と基本的には同じ流れで作成していきます。
Lambdaのソースコードと、cron設定の2点が異なります。
関数作成
import boto3
# RDSインスタンスDB識別子のリスト
rds_ids = [
'oracle11g',
'postgres11'
]
def lambda_handler(event, context):
rds = boto3.client('rds')
# リストの要素が0の場合は何もしない
if len(rds_ids) == 0:
print('対象インスタンスがありません。')
else:
for i in rds_ids:
response = rds.describe_db_instances(DBInstanceIdentifier=i)
rds_status = response["DBInstances"][0]["DBInstanceStatus"]
print(rds_status)
# ステータスが「available」の場合
if rds_status == "available":
print('既にインスタンスが起動しています。:' + str(i))
elif rds_status == "stopped":
# string 形式で RDS 受け取る
rds.start_db_instance(DBInstanceIdentifier=i)
print('インスタンスを起動しました。:' + str(i))
else:
# available や stopped 以外の場合
print('ステータスが変更途中です。:' + str(i))
return 'インスタンスの起動処理を終了します。'
関数のテスト
テストしていきます。
インスタンスが「起動中」になりました。
実行のスケジューリング
トリガーを追加していきます。
※平日 月₋金 8時に起動する場合
日本標準時(JST)の月曜日 8:00 – 金曜日 8:00 は、
協定世界時(UTC)では、日曜日 23:00 – 木曜日 23:00 となるので、以下のように設定します。
cron(0 23 ? * SUN-THU *)
以上で、起動設定も完了です。
最後に
今回は、RDS利用コスト削減のため、自動起動・停止の設定を行いました。
DBマイグレーション時だけでなく、普段の開発・運用にもすぐに使えて便利です。
弊社では、EC2、RDS、Auroraなどのサービスは、社内環境は自動的に停止しています。
遅くまで作業していても、時間がきて開発環境が落ちたら「今日はもう切り上げよう」となるので、
仕事のメリハリもつきますし、環境の落とし忘れもなくなるのでコストにも優しいです。
今の設定では、平日か土日かしか判断していませんが、
祝日や会社の特別休暇もインスタンスを起動しないなど、
Lambdaに実装を追加することで、利用シーンにあった使い方が簡単にできます。
ぜひ、実際にお試しください。
AWSで実践!OracleデータベースのDBマイグレーション 連載一覧
- Vol.25
- AWSで実践!DBマイグレーション時のRDS利用コスト削減
~ AWSのサービス 自動起動・停止を活用し使わない時間の料金を削減する ~ - Vol.24
- AWSで実践!異種間DBマイグレーション(Oracle to PostgreSQL編)
~ DMSでレコードを移行する ~ - Vol.23
- AWSで実践!異種間DBマイグレーション(Oracle to PostgreSQL編)
~ SCTでメタデータを移行する ~ - Vol.22
- AWSで実践!RDSへのDBマイグレーション(Oracle to Oracle編)
~ Data Pumpで移行する ~ - Vol.21
- AWSで実践!RDSへのDBマイグレーション(Oracle to Oracle編)
~ SQL Developerで移行する ~
↓↓ システムズのAWS DBマイグレーションに関する、Webページはこちらをご覧ください。 ↓↓