Edited at
ReluxDay 22

Aurora ClusterのReplica作成をスクリプト化する

More than 1 year has passed since last update.

Relux Advent Calendar 22日目の記事です。

ReluxではRDBMSとしてRDS Auroraを使用しています。

サイトへのアクセス増が見込まれる時など、Read Replicaの追加やサイズ変更を行なうのですが、Webのコンソールでは、ブラウザでログイン・ポチポチと操作・利用可能になるまで待つといったことが面倒です。

そこで、必要なパラメータを指定してReplicaを生成し、利用できるまで待つスクリプトを作りました。


スクリプトの中で使用するコマンド

jq

コマンドラインやシェルスクリプトでjsonを扱う際の必須コマンドです。mac os であればbrewでインストールできます。たいていのLinuxディストリビューションでは、OS標準のパッケージリポジトリに用意されていると思います。

AWS CLI

コマンドラインでawsの操作をする際の必須コマンド群です。pipなどでインストールします。


AWS CLIでAurora ClusterのReplicaを作成する際の注意

AWS CLIには create-db-instance-read-replica という非常にそれっぽいrdsのサブコマンドがあるのですが、これではAurora ClusterのReplicaは作成できません。

マニュアルにこのような注意書きがあります。


Amazon Aurora does not support this action. You must call the create-db-instance action to create a DB instance for an Aurora DB cluster.


AuroraのReplicaを作成する際には、インスタンスを作成するためのコマンドである create-db-instance を使用します。

例えば、 db-cluster-name というクラスタに new-replica-instance という名前のRead Replicaを r4.xlarge で作成する際には、下記のようなコマンドを発行します。

aws rds create-db-instance \

--engine aurora \
--db-cluster-identifier 'db-cluster-name' \
--db-instance-identifier 'new-replica-instance' \
--db-instance-class 'db.r4.xlarge' \
--availability-zone 'ap-northeast-1a'


作成したスクリプト

#!/bin/bash

while getopts c:n:p:s:z: OPT
do
case
$OPT in
c) clusterIdentifier=$OPTARG
;;
n) newReplicaIdentifier=$OPTARG
;;
p) parameterGroupName=$OPTARG
;;
s) newReplicaInstanceClass=$OPTARG
;;
z) replicaAvailabilityZone=$OPTARG
;;
esac
done

function main() {
createNewReadReplica

waitForReadyToUseNewReplica

showNewReplicaEndpoint
}

function createNewReadReplica() {
aws rds create-db-instance \
--engine aurora \
--db-cluster-identifier $clusterIdentifier \
--db-instance-identifier $newReplicaIdentifier \
--db-instance-class $newReplicaInstanceClass \
--availability-zone $replicaAvailabilityZone \
--db-parameter-group-name $parameterGroupName \
--promotion-tier 0 \
--no-publicly-accessible
}

function waitForReadyToUseNewReplica() {
echo -n 'waiting for ready to use new replica instance'
while :
do
echo -n '.'
local instanceStatus=`aws rds describe-db-instances --filters "Name=db-instance-id,Values="${newReplicaIdentifier} | jq -r '.DBInstances[0].DBInstanceStatus'`
if test $instanceStatus = 'available'; then
break
elif test $instanceStatus = ''; then
echo 'Error: could not create new replica instance!' >&2
exit 1
fi
sleep 10
done

echo 'New instance '$newReplicaIdentifier' has been available!'
}

function showNewReplicaEndpoint() {
aws rds describe-db-instances --filters "Name=db-instance-id,Values="${newReplicaIdentifier} | jq -r '.DBInstances[0].Endpoint.Address'
}

main


解説・使用方法

クラスタ名・作成するインスタンス名・インスタンスタイプ・AZ・パラメータグループ名を引数で指定し、スクリプトを実行します。

まず、ReadReplicaを作成するコマンドが発行され、statusがavailableになるまで待つ処理が入り、availableになると新しいReplicaのエンドポイントを出力して終了します。

実行例

$ bash create-relux-db-replica.bash -c cluster-name -n new-replica-instance-name -p parameter-group-name -s db.r3.4xlarge -z ap-northeast-1c

waiting for ready to use new replica instance............................New instance new-replica-instance-name has been available!
new-replica-instance-name.*******.ap-northeast-1.rds.amazonaws.com

availableになるまで待つので、 利用可能になったインスタンスを使うための処理を && で続けて書くことができます。


これをAnsible化したい

現在、いろいろなオペレーションのAnsible化を進めています。

これもAnsibleで書きたいのですが、AWS CLIでの --db-cluster-identifier に当たるオプションがなかったり、AuroraのReplicaでは必要のないディスクサイズの指定やユーザ名の指定が必須だったりと、なんだかうまくいかず試行錯誤しているところです。

うまくできたら、Ansibleでの実装方法も記事にしようと思います。