RDS 証明書ローテーションで再起動される原因と対処
目次
操作した記録がないのに、RDS のイベント履歴に「DB instance restarted」が残っている。運用の現場でよく聞く相談です。アプリ側では一時的な接続エラーが出ていて、原因を特定して報告しないと収まらない。そんなときに最初に疑うのが、サーバー証明書(CA 証明書)の自動ローテーションです。
この記事では、証明書ローテーションが再起動を伴う仕組み、イベント履歴と SupportsCertificateRotationWithoutRestart を使った切り分け、再起動タイミングを自分で選ぶための手動適用を、実務で手を動かす順番に並べます。
🎯 結論:操作していない再起動は「証明書の自動ローテーション」を先に疑う
RDS / Aurora では、使っている認証局(CA)がサーバー証明書の自動ローテーションをサポートしている場合、証明書の有効期限の半減期に達した時点で、次回のメンテナンスウィンドウ内にローテーションが自動でスケジュールされます。そしてエンジンバージョンが「再起動なしのローテーション」に対応していないと、ローテーション処理の一環として DB インスタンスの再起動が実行されます。
利用者が何も操作していなくても、メンテナンスウィンドウの時間帯に再起動が入ることがある、ということです。深夜帯にウィンドウを設定していれば「朝になったらイベント履歴に再起動が残っていた」という見え方になります😇
まず見るべきイベントは2つだけ
切り分けの起点は RDS のイベント履歴です。確認するのは次の2点です。
- 再起動イベントの前後に「server certificate rotation」関連のイベントが記録されていないか。証明書ローテーションが原因なら、再起動イベントと同じタイミング、あるいはその直前に関連イベントが並びます。
- その数日〜数週間前に、ローテーション予告の通知イベントが記録されていないか。「サーバー証明書のローテーションが次回メンテナンスウィンドウで実施される」旨の事前通知は、実際の適用よりかなり前に記録されます。ここを見落としていると「突然の再起動」に見えます。
この2つが揃えば、証明書ローテーションが原因である確度はかなり高くなります。どちらも見つからない場合は、ハードウェアメンテナンス、エンジンのパッチ適用、Multi-AZ のフェイルオーバーなど別の線を追うことになります。RDS / Aurora の障害切り分け全体の流れは RDS・Aurora 運用・トラブル解決ガイド|仕組み・障害切り分け・性能監視の全体像 にまとめているので、原因が証明書でなかった場合はそちらも参照してください。
再起動が避けられるケース/避けられないケース
判定の分かれ目はエンジンバージョンです。再起動なしのローテーションに対応しているバージョンなら、証明書の入れ替えだけが行われ、DB インスタンスの再起動は発生せず、既存の接続も維持されます。未対応のバージョンでは、ローテーションのために再起動が必要です。この場合、再起動そのものを回避する手段はありません。選べるのは「いつ再起動するか」だけです。
対応しているかどうかは推測で判断しなくて済みます。後述する describe-db-engine-versions の SupportsCertificateRotationWithoutRestart を見れば、使っているエンジンとバージョンで機械的に判定できます。再起動が避けられないと分かったら、次は「メンテナンスウィンドウに任せるか、自分で業務影響の小さい時間に寄せるか」の選択です。
🤔 なぜ操作していないのに再起動されるのか
CA の自動ローテーションは証明書の有効期限の半減期で動く
RDS のサーバー証明書には有効期限があります。期限が切れると、sslmode=verify-full(PostgreSQL)や証明書検証を有効にしたクライアントからの SSL/TLS 接続が失敗します。これを防ぐため、自動ローテーションをサポートする CA を使っている場合、マネージドサービス側が期限前に証明書を入れ替えてくれます。
⚠️ 注意したいのは、そのトリガーが「有効期限の直前」ではなく有効期限の半減期だという点です。有効期限までまだ十分な余裕がある時期に、淡々とスケジュールされます。これが「まだ期限切れの話は先のはずなのに、なぜ今動いたのか」という混乱の元になります。期限までの残り期間で当たりをつけると外します。
ローテーションは次回メンテナンスウィンドウ内に自動スケジュールされる
半減期に達すると、ローテーションは保留中のメンテナンスアクションとして登録され、次回のメンテナンスウィンドウ内に実行されます。即時実行ではありません。ここが実務的には救いで、通知に気づいた段階であれば、ウィンドウが来る前に自分の都合のいい時間へ動かす余地があります。
逆に言うと、週次のメンテナンスウィンドウを設定している環境では、通知から実行までの猶予がウィンドウの間隔に依存します。通知を見ていなければ、次のウィンドウで自動的に適用されます。
エンジンバージョンによって再起動を伴うかが変わる
再起動なしの証明書ローテーションは、あとから追加された機能です。そのため、同じエンジンでも古いバージョンでは未対応、新しいバージョンでは対応、という状況が生まれます。エンジンの種類による差もあり、たとえば RDS for SQL Server のように、対応していないバージョンを使っていれば再起動が伴います。
この差は「エンジン名 × エンジンバージョン」の組み合わせで決まるため、同じアカウント内でもインスタンスごとに挙動が違うことがあります。「A の DB は再起動しなかったのに B は再起動した」というのは矛盾ではなく、バージョン差である可能性が高いです。
🔎 原因を確定させる切り分け手順
手順1:イベント履歴で再起動の前後に何が記録されたかを見る
マネジメントコンソールの「イベント」画面でも確認できますが、報告用にテキストで残したい場合は CLI のほうが扱いやすいです。
aws rds describe-events \
--source-identifier <インスタンス名> \
--source-type db-instance \
--duration 20160 \
--output table
--duration は分単位で「何分前まで遡るか」を指定します。RDS のイベント履歴には保持期間があり、古いものは取得できなくなるため、事象に気づいた時点で早めに取得しておくのが安全です(保持期間の正確な値は公式ドキュメントで確認してください)。
見るポイントは次の3点です。
- 再起動イベントのメッセージ本文(
DB instance restartedなど) - その前後に並ぶ証明書ローテーション関連のイベント
- 数日〜数週間前にある事前通知イベント
💡 このイベント列がそのまま原因の根拠になります。上司や顧客への報告では、推測を書かずにイベント履歴をそのまま添付するのが最も説明コストが低い方法です。
手順2:再起動時刻がメンテナンスウィンドウ内かを照合する
次に、再起動の発生時刻がメンテナンスウィンドウに収まっているかを確認します。
aws rds describe-db-instances \
--db-instance-identifier <インスタンス名> \
--query 'DBInstances[*].{Engine:Engine,Version:EngineVersion,Window:PreferredMaintenanceWindow,CA:CACertificateIdentifier,AutoMinor:AutoMinorVersionUpgrade}'
ここで引っかかりやすいのがタイムゾーンです。PreferredMaintenanceWindow は ddd:hh24:mi-ddd:hh24:mi 形式の UTC 表記で返ります。一方、コンソールのイベント履歴はブラウザのローカルタイム(JST)で表示されることがあり、CLI の出力は UTC です。JST と UTC を混ぜて比較すると 9 時間ずれ、「ウィンドウ外で再起動された」という誤った結論に直行します。どちらかに揃えてから照合してください。
✅ 時刻がウィンドウ内に収まっていて、かつ手順1で証明書ローテーション関連のイベントが見つかっていれば、原因はほぼ確定です。
手順3:エンジンバージョンが再起動なしのローテーションに対応しているか調べる
最後に、そのエンジンバージョンが再起動を伴うのかを機械的に確認します。手順2で取得した Engine と EngineVersion をそのまま入れます。
aws rds describe-db-engine-versions \
--engine <エンジン名> \
--engine-version <バージョン> \
--query 'DBEngineVersions[*].SupportsCertificateRotationWithoutRestart'
結果が false なら、そのエンジンバージョンは再起動を伴います。true なら再起動なしでローテーションできるバージョンなので、記録されていた再起動は別の原因(ハードウェアメンテナンス、パッチ適用、フェイルオーバーなど)を疑う流れに切り替えます。
この1行が切り分けの決め手になります。「再起動が必要だったのか、避けられたのか」という最も聞かれやすい質問に、ドキュメントの引用ではなく自環境の実際の値で答えられるからです。
DB エンジンのログだけでは原因を特定できない理由
つい先に見てしまうのが、Oracle の alert.log や SQL Server のエラーログ、PostgreSQL のログといったエンジン側のログです。しかしここには「インスタンスがシャットダウンされ、起動した」という事実しか残りません。なぜシャットダウンされたのか、その指示がどこから来たのかは、エンジンから見れば外部の出来事なので記録されません。
💡 証明書ローテーションもハードウェアメンテナンスも、エンジンログ上の見た目は「正常な停止と起動」で区別がつきません。基盤側の理由は RDS のイベント履歴側にしかないため、エンジンログよりイベント履歴から入ってください。イベント履歴で原因が確定したあとに「再起動後の起動処理でエラーが出ていないか」を確認する用途では、エンジンログが役に立ちます。
この記事のテーマをさらに学べる本
EC2・IAM・RDSの運用やバックアップ/リストアを体系立てて解説しており、RDSの運用判断の土台になります。
楽天ブックスで詳しく見る🛠️ 対処:再起動のタイミングを自分で選ぶ
すでに完了している場合の報告のまとめ方
事象が終わっている場合、技術的な対応は不要です。やることは報告材料を揃えることだけです。次の4点を並べれば、原因と妥当性の説明として成立します。
- 再起動イベントのタイムスタンプとメッセージ
- その前後に記録された証明書ローテーション関連のイベント
- 事前通知イベントの日時(「予告されていた作業である」ことの証拠)
SupportsCertificateRotationWithoutRestartがfalseであること(「再起動が必要な構成だった」ことの証拠)
「証明書ローテーションだと思われます」と書くのではなく、イベント履歴と CLI 出力をそのまま添えてください。あわせて「今後は事前通知を検知して業務時間外に自分で適用する」という再発防止をセットで出せると、報告は一往復で終わります。
保留中の証明書ローテーションを手動で適用して業務時間外に寄せる
まだ適用されていない、つまり事前通知の段階で気づけた場合は、メンテナンスウィンドウの到来を待たずに自分で適用できます。まず保留中のアクションを確認します。
aws rds describe-pending-maintenance-actions \
--resource-identifier <DBインスタンスのARN>
出力の PendingMaintenanceActionDetails に、アクション名(証明書ローテーションの場合は ca-certificate-rotation のような値)、AutoAppliedAfterDate(自動適用される期日)、ForcedApplyDate(強制適用される期日)が含まれます。アクション名は実際の出力から取得してください。
業務影響の小さい時間帯に、この作業時間で実行します。
aws rds apply-pending-maintenance-action \
--resource-identifier <DBインスタンスのARN> \
--apply-action <アクション名> \
--opt-in-type immediate
⚠️ --opt-in-type immediate は「すぐに適用する」という指定です。再起動が伴うバージョンであれば、このコマンドの実行によって再起動が発生します。日中に軽い気持ちで打つコマンドではないので、作業時間を確保し、アプリ側の停止・接続断の許容まで含めて段取りしてから実行してください。
Multi-AZ 構成の場合、単一 AZ と接続断の挙動が異なることがあります。フェイルオーバーを伴う形で適用されるケースもあるため、クラスタ/インスタンスの構成に応じて事前検証しておくのが安全です。Aurora のようにクラスタ内に複数インスタンスがある構成では、インスタンスごとに保留アクションが登録されるため、リーダーとライターを別々の作業時間に分けて適用するといった調整もできます。
検証環境で「再起動を伴うか」を事前に確かめる手順
本番で初めて挙動を見るのは避けたいところです。同じ現象を検証環境で再現するなら、次の手順が取れます。
- 再起動なしのローテーションに未対応のエンジンバージョンで DB インスタンスを作成する
describe-db-engine-versionsでSupportsCertificateRotationWithoutRestartがfalseであることを確認するapply-pending-maintenance-actionで証明書ローテーションを手動適用し、再起動が伴うことを確認する
この検証では、再起動に要した時間、アプリ側にどのエラーが出たか、コネクションプールが自動復旧したかどうかを記録しておくと、本番作業の計画がそのまま書けます。実際の停止時間はインスタンスクラスやエンジン、データ量によって変わるため、一般的な目安を信じるより自環境で測ったほうが確実です。
アプリ側で用意しておきたい再接続・タイムアウト設定の見直し
再起動そのものを避けられないなら、再起動されても壊れないアプリ側の設計に寄せるのが本筋です。証明書ローテーションに限らず、フェイルオーバーやパッチ適用でも同じことが起きるので、投資対効果は高い部分です。
- コネクションプールの死活確認。切断済みのコネクションを掴み続けないよう、貸し出し時の検証や最大生存時間(
maxLifetime相当)を設定しておく。プールのサイズいっぱいに死んだ接続が溜まると、再起動完了後もエラーが続きます。 - 接続タイムアウトとクエリタイムアウトを設定して無限待ちを避ける。再起動中の接続試行が長時間ブロックすると、上流のスレッドプールが枯渇して障害が広がります。
- リトライは冪等な処理に限定して、指数バックオフ付きで行う。
- 上流コンポーネントとのタイムアウト整合。ALB → アプリ → DB のタイムアウト値が逆順(上流が短い)になっていると、DB の一時停止が上流側では別のエラーとして見えます。この整合の考え方は ALB で 502 Bad Gateway が出たときの原因と切り分け手順【AWS】 の内容がそのまま応用できます。
- 証明書バンドルの配置。後述のとおり、クライアント側が信頼する CA バンドルが古いと、サーバー証明書が新しくなった瞬間に検証エラーで接続できなくなります。
🔔 再発防止:保留中メンテナンスを見逃さない仕組み
保留中のメンテナンスを定期チェックする
「通知を見落とした」を仕組みで潰すなら、保留中のメンテナンスアクションを定期的に棚卸しするのが確実です。リージョン内の全リソースをまとめて確認できます。
aws rds describe-pending-maintenance-actions \
--query 'PendingMaintenanceActions[*].{Resource:ResourceIdentifier,Detail:PendingMaintenanceActionDetails[*].[Action,AutoAppliedAfterDate,ForcedApplyDate]}' \
--output json
これを週次のバッチや運用チェックリストに組み込み、出力が空でなければ担当者に上げる、という運用にします。EventBridge Scheduler と Lambda で定期実行し、結果を Slack やメールに流す構成にすれば、確認漏れの余地を減らせます✨
見るべきは AutoAppliedAfterDate と ForcedApplyDate です。前者は「この日以降のメンテナンスウィンドウで自動適用される」、後者は「オプトインしなくても強制的に適用される」期日です。この2つの日付から、自分で適用できる猶予がどれだけ残っているかが逆算できます。
イベントサブスクリプションでメンテナンス通知を受け取る
RDS のイベントサブスクリプションを設定すれば、SNS 経由でメールなどに通知を飛ばせます。事前通知イベントを人が気づける場所に届けるのが目的です。
aws sns create-topic --name rds-maintenance-notify
aws sns subscribe \
--topic-arn <SNSトピックのARN> \
--protocol email \
--notification-endpoint <通知先メールアドレス>
aws rds create-event-subscription \
--subscription-name rds-maintenance-sub \
--sns-topic-arn <SNSトピックのARN> \
--source-type db-instance \
--event-categories maintenance availability \
--enabled
--event-categories に maintenance を含めるのを忘れないでください。あわせて availability(再起動やフェイルオーバー)も入れておくと、「予告」と「実施」の両方が手元に届きます。--source-ids を省略すると、そのソースタイプの全リソースが対象になります。対象を絞りたい場合は --source-ids で指定してください。カテゴリの正確な一覧は aws rds describe-event-categories で確認できます。
通知先が個人メールだけだと退職や異動で切れます。チームのメーリングリストやチャット連携に寄せるほうが長持ちします😇
エンジンバージョンアップを計画に載せる判断基準
SupportsCertificateRotationWithoutRestart が false のまま運用を続けると、証明書のライフサイクルに合わせて将来も再起動が発生します。バージョンアップすれば対応する場合があるため、これはバージョンアップの判断材料のひとつになります。
とはいえ「証明書ローテーションで再起動されるから今すぐ上げる」という優先度にはなりにくいはずです。判断の軸は次のあたりです。
- 再起動の許容度。短時間でも停止が許されないシステムなら、対応バージョンへ上げる価値は大きい
- メンテナンスウィンドウで別の再起動もすでに発生しているか。マイナーバージョン自動アップグレードやハードウェアメンテナンスで元々停止が入るなら、証明書ローテーション単体の影響は相対的に小さい
- EOL とサポート期限。どうせ上げるなら、証明書ローテーションの都合だけでなくエンジンのサポート期限と合わせて計画する
新しいバージョンで SupportsCertificateRotationWithoutRestart が true になるかどうかは、アップグレード先候補のバージョンに対して同じコマンドを実行すれば事前に確認できます。--engine-version を省略すれば、そのエンジンで利用可能なバージョン一覧に対して値を並べて比較できます。
この記事のテーマをさらに学べる本
AWSのネイティブ機能を組み合わせた本番環境の構築・運用設定やノウハウを扱っており、運用面の理解を広げられます。
楽天ブックスで詳しく見る🙅 よくある誤解
「証明書ローテーションは接続に影響しない」は正しくない
証明書の入れ替えは「ファイルを差し替えるだけ」というイメージを持たれやすく、接続に影響しないと思われがちです。しかし実際には、エンジンバージョンによっては DB インスタンスの再起動を伴います。再起動すれば既存の接続はすべて切断され、その間の新規接続も失敗します。
「証明書」という言葉から連想する軽さと、実際に起きること(インスタンス再起動)のギャップが、この誤解の温床です。影響範囲を判断するときは言葉の印象ではなく、SupportsCertificateRotationWithoutRestart の値で機械的に決めてください。
「事前通知が来ていなかった」のではなく見落としていることが多い
「何の連絡もなく再起動された」という認識になっているケースでも、イベント履歴を遡ると事前通知イベントが記録されていることが少なくありません。通知は実際の適用よりかなり前に出るため、届いた時点では「まだ先の話」として流れてしまい、記憶に残らないのです。
対処は「気をつける」ではなく仕組み化です。イベントサブスクリプションで通知をチームの共有先に届け、保留中メンテナンスの定期チェックで期日を可視化する。この2つを入れるだけで「突然の再起動」は「予定された作業」に変わります🎉
「証明書の有効期限切れ直前に動く」わけではない
自動ローテーションのトリガーは有効期限の半減期です。期限まで半分以上の余裕がある段階で動き始めます。「証明書の有効期限はまだ先だから、しばらくは何も起きないだろう」という前提で計画を立てると外れます。
同様に、「有効期限の一覧を作って期限が近いものだけ警戒する」という管理も取りこぼします。管理すべきは有効期限そのものではなく、describe-pending-maintenance-actions に出てくる AutoAppliedAfterDate / ForcedApplyDate、つまり「いつ適用されるか」の側です。
❓ よくある質問
証明書ローテーションによる再起動のダウンタイムはどれくらい?
一般的な目安を書くことはできますが、実際の停止時間はエンジン、インスタンスクラス、データ量、Multi-AZ かどうかで変わります。数字を当てにいくよりも、検証環境で同一構成のインスタンスに対して apply-pending-maintenance-action を実行し、実測しておくのが確実です。その値であれば根拠を持って関係者に説明できます。
測るときは「インスタンスが available に戻るまで」ではなく、「アプリからクエリが成功するまで」を測ってください。コネクションプールの復旧やキャッシュのウォームアップを含めた実効的な復旧時間のほうが、業務影響の判断に使えます。
再起動なしで証明書をローテーションできる?
エンジンバージョンが対応していれば可能です。describe-db-engine-versions の SupportsCertificateRotationWithoutRestart が true なら再起動なし、false なら再起動を伴います。false の環境で再起動を回避する設定は存在しないため、選べるのは「いつ再起動するか」だけです。恒久的に再起動を避けたい場合は、対応バージョンへのアップグレードを検討することになります。
証明書ローテーションを延期・キャンセルできる?
証明書の有効期限があるため、無期限の延期はできません。describe-pending-maintenance-actions の ForcedApplyDate が「オプトインしなくても適用される期日」で、これが実質の上限です。
apply-pending-maintenance-action の --opt-in-type には undo-opt-in もありますが、これは一度行ったオプトイン(即時適用や次回ウィンドウでの適用の申し込み)を取り消すもので、アクション自体を消すものではありません。取り消してもアクションは保留のまま残り、期日が来れば適用されます。現実的な打ち手は、業務影響の小さい時間帯に自分で適用して先に終わらせることです。
クライアント側の証明書バンドルも入れ替えが必要?
サーバー証明書が新しい CA のものに変わる場合、クライアントが信頼する CA バンドルにその CA が含まれていなければ、証明書の検証に失敗して接続できなくなります。sslmode=verify-full / verify-ca(PostgreSQL)や、JDBC の証明書検証を有効にしている構成では特に注意が必要です。
AWS は複数の CA をまとめたバンドルを提供しているため、そちらを使っておけば CA の切り替えに追随しやすくなります。実務でのハマりどころは、アプリのコンテナイメージや AMI に固定で古い証明書ファイルを焼き込んでいるケースです。証明書の配置場所を棚卸しし、更新手順が用意されているかを確認してください。必要なバンドルの入手先やリージョンごとの扱いは公式ドキュメントで確認してください😇
📝 まとめ
- 操作していない再起動は、まずサーバー証明書の自動ローテーションを疑う
- 自動ローテーションは証明書の有効期限の半減期でトリガーされ、次回メンテナンスウィンドウ内にスケジュールされる
- 再起動を伴うかはエンジンバージョン依存。
describe-db-engine-versionsのSupportsCertificateRotationWithoutRestartがfalseなら再起動を伴う - 切り分けは「イベント履歴 → 時刻とメンテナンスウィンドウの照合(UTC/JST に注意)→ エンジンバージョンの対応状況」の順。エンジンのログには基盤側の理由は残らない
- 完了後なら対応は不要。報告はイベント履歴と CLI 出力をそのまま根拠にする
- 予告段階で気づけたら
apply-pending-maintenance-actionで業務時間外に自分で適用する - 再発防止は
describe-pending-maintenance-actionsの定期チェックと、maintenanceカテゴリのイベントサブスクリプション。あわせてコネクションプールとタイムアウトの見直しを
「証明書ローテーション」という言葉の軽さに引っ張られず、再起動を伴う作業として扱ってください。なお、RDS の仕様やサポート状況は変わることがあります。CA の有効期限、対応エンジンバージョン、証明書バンドルの取得方法などは、作業前に AWS の公式ドキュメントで最新の内容を確認してください。