[Dd]enzow(ill)? with DB and Python

DBとか資格とかPythonとかの話をつらつらと

boto3でAWSのRDSインスタンスを再作成する

2018年もはじまって1週間、そろそろ社会復帰しないといけないですね。昨年末にRDSやらboto3やら触っていたのでそこら辺まとめておきます。

解決すべき課題

  • RDSはいずれもMySQL
  • 本番のRDSがある(本番RDS)
  • 開発用環境のRDSがある(開発RDS)
  • 開発RDSのデータは本番RDSから不定期に同期させている
  • 同期にはmysqldumpしたデータを流し込む方法を使用している

結構データ量があるので、mysqldumpでの取得と流し込みがかなり時間がかかっており、あまり気軽にデータの同期ができていませんでした。これをどうしたかという話です。

どうしたのか

RDSはデフォルトでも自動でスナップショットが取られており、これを用いてRDSインスタンスを復元することが可能です。そのため、以下のような形にしました。

  • 本番RDSの最新のスナップショットをもとに新規RDSを作成
  • 既存の開発RDSをリネーム(旧開発RDS)
  • 新規RDSを開発RDSへリネーム
  • 旧開発RDSを削除

mysqldumpの流し込みのようにSQLを発行しているわけではないので、20分もかからずに完了します。この一連のオペレーションをboto3で処理を書いてスクリプト化しました。

もうちょい

今回はスクリプト化しましたが、一般的な処理部分を切り出してrds makerというライブラリにしてみました。もちろんboto3さえあれば必要なRDSへの操作は全部できますが、基本的にすべて非同期で行われます。バッチ系の処理では完了まで待機(同期的)してほしい場合も多いです。そこで、処理の完了を待機したりといった細かい部分を都度書かずに済むように薄いラッパーとして作成しています。

rds_makerRdsMakerというクラスを提供しており、こんな感じで利用できます。

from rds_maker import RdsMaker

# create instance
rds_maker = RdsMaker(
    region_name=REGION_NAME,
    az_name=AZ_NAME,
    aws_access_key=AWS_ACCESS_KEY,
    aws_rds_secret_key=AWS_RDS_SECRET_KEY,
)

# 最新のスナップショット名を取得
snapshot_identifier = rds_maker.get_latest_snapshot('複製元のインスタンス名')

# スナップショットからDBインスタンスを作成
rds_maker.create_db_instance_sync(
    db_identifier='新しいインスタンス名',
    snapshot_identifier=snapshot_identifier,
    instance_class='db.t2.micro',
)

# VPC等一部のパラメータは作成後にしか変更できないので、それらを指定
rds_maker.change_db_instance_attributes_sync(db_identifier='新しいインスタンス名', attributes={
    'DBParameterGroupName': DB_PARAMETER_GROUP,
    'BackupRetentionPeriod': 7,
    'VpcSecurityGroupIds': [VPC_SECURITY_GROUP_ID],
})

# RDSの名前(エンドポイント)を変更する
rds_maker.rename_db_instance_sync(from_identifier='新しいインスタンス名', to_identifier='元のインスタンス名')

とりあえず自分で使う部分だけですが、できるだけわかりやすい形になるよう実装しています。ソースのメソッドをみればほぼ使い方はわかるかと思います。

インストール

PyPIに登録してありますのでインストールは以下でできます。

$ pip install rdsmaker

example

GitHub上のexample/rdsmaker_cli.pyには、rdsmakerを使ってRDSを作成・再作成するためのCLIツールのサンプルを配置しているので、これを確認すればもう少し使い方がわかるかと思いますし、そのままrdsmaker_cli.py自体も実用に堪えるものだと思います。

(boto3) denzownoMacBook-Pro:example denzow$ python rdsmaker_cli.py --help
usage: rdsmaker_cli.py [-h] -s SOURCE_INSTANCE_NAME -t TARGET_INSTANCE_NAME
                       [--only-create] [-c INSTANCE_CLASS]

remake_rds.py
=================
指定したスナップショットをもとに任意のRDSを(再)作成します。
usage example:

### 再作成モード
> python rdsmaker_cli.py -s source-db-identifier -t target-db-identifier -c db.t2.small

* source-db-identifierの最新のスナップショットから
* 既存のtarget-db-identifierを削除し
* 新しくtarget-db-identifierとして
* db.t2.smallで作成する

### 作成モード
> python rdsmaker_cli.py --only-create -s source-db-identifier -t target-db-identifier -c db.t2.small

* source-db-identifierの最新のスナップショットから
* 新しくtarget-db-identifierとして
* db.t2.smallで作成する

optional arguments:
  -h, --help            show this help message and exit
  -s SOURCE_INSTANCE_NAME, --source-instance-name SOURCE_INSTANCE_NAME
                        source instance name. this command use snapshot of source instance.
  -t TARGET_INSTANCE_NAME, --target-instance-name TARGET_INSTANCE_NAME
                        target recreate instance name.
  --only-create         not recreate, but create.
  -c INSTANCE_CLASS, --instance-class INSTANCE_CLASS
                        ex). db.t2.micro(default), db.t2.small,db.t2.medium,db.t2.large...

DjangoみたいなWEBアプリもいいですが、こういったCLIツールやそれ関連のライブラリを書くのもやはりPythonだと楽しいですね。