テックメモ

技術的に気になったことをメモしていきます

RDSの証明書更新が無停止で出来ると聞いたので試した

はじめに

RDSのTLS証明書の更新が無停止で出来ると聞いたので、調べた結果のメモです。
ソースはこちらのドキュメントです。 aws.amazon.com

--no-certificate-rotation-restart オプションについて以下のように言及がなされています。

I don’t use SSL/TLS, can I rotate the certificate without restarting my database?
If you do not want to restart your database, you can use a new CLI option for the modify-db-instance CLI command (--no-certificate-rotation-restart) specifically to rotate and stage the new certificates on the database host to avoid a restart. However, new certificates will be picked up by the database only when a planned or unplanned database restart happens.

結果

結論からいうと、TLS証明書の更新が不要な場合に限り無停止でメンテナンスを行う事が可能でした。
以下、検証結果を記します。

検証結果

まずは更新前のRDSの証明書を確認します。確認したところ、有効期限が2020/3/5の状態でした。

openssl s_client -connect ${RDS_ENDPOINT}:${RDS_PORT} -starttls mysql | openssl x509 -noout -enddate

depth=1 C = US, ST = Washington, L = Seattle, O = "Amazon Web Services, Inc.", OU = Amazon RDS, CN = Amazon RDS ap-northeast-1 CA
depth=0 CN = xxxxx.ap-northeast-1.rds.amazonaws.com, OU = RDS, O = Amazon.com, L = Seattle, ST = Washington, C = US
verify return:1
notAfter=Mar  5 22:03:06 2020 GMT

次に、このRDSに対して以下のようにヘルスチェックを行うスクリプトを作成しました。

#!/bin/bash
while true;
do
  d=$(date)
  if mysql -e 'show databases' > /dev/null 2>&1 ; then
    echo "${d}: connect success"
  else
    echo "${d}: connect failed"
  fi
  sleep 1
done

上記のスクリプトを実行した状態で、以下のように変更を実施しました。

aws rds modify-db-instance --db-instance-identifier ${RDS_IDENTIFIER} --no-certificate-rotation-restart --ca-certificate-identifier rds-ca-2019

# レスポンスから抜粋
"PendingModifiedValues": {
   "CACertificateIdentifier": "rds-ca-2019"
},

PendingModifiedValuesがCACertificateIdentifierだけでしたので、即時反映をしてみます。

aws rds modify-db-instance --db-instance-identifier ${RDS_IDENTIFIER} --no-certificate-rotation-restart --ca-certificate-identifier rds-ca-2019 --apply-immediately

無事に完了し、このRDSインスタンスaws rds describe-pending-maintenance-actions の対象から除外されたことも確認できました。もちろんこの間にmysqlのヘルスチェックは失敗しませんでした。

最後に証明書の状態を確認してみたところ、ドキュメントの通り証明書は更新されていませんでした。

openssl s_client -connect ${RDS_ENDPOINT}:${RDS_PORT} -starttls mysql | openssl x509 -noout -enddate

depth=1 C = US, ST = Washington, L = Seattle, O = "Amazon Web Services, Inc.", OU = Amazon RDS, CN = Amazon RDS ap-northeast-1 CA
depth=0 CN = xxxxx.ap-northeast-1.rds.amazonaws.com, OU = RDS, O = Amazon.com, L = Seattle, ST = Washington, C = US
verify return:1
notAfter=Mar  5 22:03:06 2020 GMT

証明書を更新する方法

CLIのリファレンスを確認したところ --no-certificate-rotation-restart を指定した場合でも、RDSインスタンスを再起動すれば証明書が更新されるようなので試してみました。 docs.aws.amazon.com

さきほどの検証に用いたRDSインスタンスを再起動します。

aws rds reboot-db-instance --db-instance-identifier ${RDS_IDENTIFIER}

再起動後、TLS証明書の状態を確認した結果がこちらです。無事にTLS証明書が更新されていますね。

openssl s_client -connect ${RDS_ENDPOINT}:${RDS_PORT} -starttls mysql | openssl x509 -noout -enddate

depth=1 C = US, ST = Washington, L = Seattle, O = "Amazon Web Services, Inc.", OU = Amazon RDS, CN = Amazon RDS ap-northeast-1 2019 CA
depth=0 CN = xxxxx.ap-northeast-1.rds.amazonaws.com, OU = RDS, O = Amazon.com, L = Seattle, ST = Washington, C = US
verify return:1
notAfter=Aug 22 17:08:50 2024 GMT