RDS作業中に半リアルタイムで状況把握したかった(のでスクリプト書きました)

Amazon RDS

ちょっとタイトルにしづらいのですが、

例えばオンプレミスのサーバやネットワーク機器を新しくスイッチに接続する時、
該当のIPアドレスにpingを打ちっぱなしにしておいて、繋がったらすぐ変化がわかるようにしてから作業する… という経験をお持ちのかたは、インフラエンジニアを中心に比較的多いのではないでしょうか。

要は、それをRDSでもやりたい。

RDSの設定変更を行った時、
都度マネジメントコンソール(MC)をリロードしたり、AWSCLIを叩いたりしなくても、
ターミナルで動かしっぱなしにしたら情報が随時更新されるといいなぁと思ったわけです。

定期的に自動実行させるだけなら、watchコマンドでAWSCLIを叩かせるだけでも良いのですけど、
どうせならvmstatsarのように、あとから見ていつ何が変わったかが追跡できるよう、タイムスタンプ付きで表示されていくと素敵ですよね。

結果として、こういう表示が得られるワンライナーを書くことにしました。

[12:26:27] test-rds01 ap-northeast-1c (ap-northeast-1a) db.t2.small available
[12:26:39] test-rds01 ap-northeast-1c (ap-northeast-1a) db.t2.small rebooting
[12:26:52] test-rds01 ap-northeast-1c (ap-northeast-1a) db.t2.small rebooting
 :

左から順に、タイムスタンプ、RDS名、AZとセカンダリAZ、インスタンスのクラス、ステータス。
10秒間隔でAWSCLIを実行して情報を取得、簡単に整形して1行で表示してゆきます。

背景

先日、とあるRDSのインスタンスタイプ(クラス)を変更するという作業を実施しました。

該当のRDSはマルチAZを有効にしてあるので、実際の作業としては、

  1. スナップショットを取得
  2. インスタンスのクラスを変更して即適用:再起動とフェイルオーバーが発生
  3. 使用可能(available)になったら再度再起動(= フェイルバック)

という一連の流れになります。

ただちょっと困るのは、それぞれの作業は分単位で時間がかかることです。

即時〜数秒くらいで終わってすぐ次に進めるなら、その都度マネジメントコンソールの再読込をクリックして確認してもよいのですけど、
上の作業はそれぞれ普通に数分〜10分弱程度の時間がかかるものばかりです。

ずっと張り付いてクリックし続けるのも大変だし、並行して他の作業をしづらくもなるので、
少々目をはなしても、ちょっとターミナルを見るだけで現状が把握できて、かつ後から「いつ変化したか」が追えるような、上述したようなことが出来ないかなと考えました。

やったこと

なんてことはない、この手の用途では鉄板のwhiledosleepdoneの無限ループです。

微妙にワンライナー詐欺だったり改行がはいっていたりしますが、

  • 1行目で環境変数RDS_NAMEにRDS名をセットして
  • 2行目でヘッダの表示
  • 3行目以降のwhileループ内でのAWSCLIを実行と10秒スリープ

という仕組みになっています。

$ RDS_NAME="test-rds01"
$ echo "[Time] DBInstanceIdentifier AvailabilityZone (SecondaryAvailabilityZone) DBInstanceClass DBInstanceStatus"; \
  while :
  do
    printf "[%s] %s %s (%s) %s %s\n" \
        $(date +%T) \
        $(aws rds describe-db-instances --db-instance-identifier ${RDS_NAME} \
          --query DBInstances[].[DBInstanceIdentifier,AvailabilityZone,SecondaryAvailabilityZone,DBInstanceClass,DBInstanceStatus] \
          --output text)
    sleep 10 || exit
  done

実際に使われる際は、
1行目は""に監視したいRDS名を記入して改行、
2行目のecho〜11行目のdoneまでをいちどにコピペしてください。

上述の作業を行うための確認が目的なので、表示項目もそれに即した形になっていますが、
例えばDBサイズの変更作業で使うなら、DBInstanceClassの代わりにAllocatedStorageでも良いかもですね。

項目名に何を指定できるかは、aws rds describe-db-instancesの結果とにらめっこして見つけて下さい。

項目の変更ではなく追加であれば、5行目のprintfのフォーマットもあわせて変更します。

おまけ

そんなに長くないワンライナーですが、かといって毎回これをコピペしてくるのもアレなので、
ついでにシェルスクリプトにしました。自分のGistに貼っています。

簡単なREADMEもつけていますが、
これをダウンロードして実行権限をつけ、AWSCLIが実行できるよう環境変数AWS_DEFAULT_PROFILE等を設定した上で実行して下さい。

簡単なヘルプとエラーチェックもつけています。1

$ ./aws-rdsstat -h
usage: aws-rdsstat <rds name> [<interval>]
  default interval: 10 (sec)

$ ./aws-rdsstat test-rds01
You must specify a region. You can also configure your region by running "aws configure".

$ export AWS_DEFAULT_PROFILE=profile01
$ ./aws-rdsstat test-rds01
[Time] DBInstanceIdentifier AvailabilityZone (SecondaryAvailabilityZone) DBInstanceClass DBInstanceStatus
[14:23:02] test-rds01 ap-northeast-1c (ap-northeast-1a) db.t2.micro available
[14:23:13] test-rds01 ap-northeast-1c (ap-northeast-1a) db.t2.micro available
^C

$ ./aws-rdsstat test-rds01 30
[Time] DBInstanceIdentifier AvailabilityZone (SecondaryAvailabilityZone) DBInstanceClass DBInstanceStatus
[14:23:31] test-rds01 ap-northeast-1c (ap-northeast-1a) db.t2.micro available
[14:24:02] test-rds01 ap-northeast-1c (ap-northeast-1a) db.t2.micro available
[14:24:33] test-rds01 ap-northeast-1c (ap-northeast-1a) db.t2.micro available
^C

監視したいRDSのインスタンス名を指定する第1引数は必須、
第2引数のインターバル秒数はオプション(デフォルトで10秒)です。

今回は必要があったのと、ひとつひとつの待ち時間が長いこともあってRDS用で作りましたが、
いろいろと応用が効く手法だと思うので、よろしければご参考までにお納め下さい。


  1. 実は、helpという名前のRDSインスタンスに対しては実行できないという不具合があるのですが仕様です