はじめに
この記事は DENSO アドベントカレンダー 2025 の17日目の記事です。
社内ナレッジ向けチャットボットを開発しています。ユーザーに使い始めてもらって約2週間、順調に稼働していたある日のこと。
「今使えないのかな?」
ユーザーからこんなメッセージが届きました。
まさか、と思いながらアクセスしてみると……
There is an issue connecting to your database with your username/password, username: db_user.
Please check your database configuration to ensure the username/password are valid.
DBに接続できない?何もいじってないのに?
ここから調査が始まりました。
アーキテクチャ(抜粋)
問題を理解するために必要な部分だけ抜粋して説明します。
ECS Fargateで動くRailsアプリケーションが、Aurora MySQLに接続する構成です。DB認証情報はSecrets Managerで管理しています。
なぜSecrets Managerを使っていたか
DBのパスワード管理にSecrets Managerを選んだのは、できるだけマネージドな世界でシステムを構築したかったからです。
自分たちでパスワードを決めて管理するより、AWSに任せた方が安全。しかも自動ローテーションがあるから、定期的にパスワードが更新されてセキュリティも向上する。良いことづくめだと思っていました……このときまでは。
RDSのマスターパスワードをSecrets Managerで管理すると、自動ローテーションがデフォルトで有効になります。
調査開始:aws loginとClaude Codeで原因を探る
最近リリースされたaws loginコマンドを使って、Claude Codeと一緒に調査しました。
aws loginは2025年11月にリリースされた新機能で、ブラウザ認証だけでAWS CLIが使えるようになります。詳しくは以下の記事が参考になります。
# ブラウザが開いて認証、すぐにCLIが使える
$ aws login
RDSイベントを確認
まずRDSのイベントログを確認しました。
$ aws rds describe-events \
--source-identifier your-app-dev-db \
--source-type db-cluster \
--duration 1440
{
"Date": "2025-12-09T11:09:01+09:00",
"Message": "Reset master credentials"
}
「Reset master credentials」……パスワードがリセットされている?
CloudTrailでSecrets Managerのイベントを確認
次にCloudTrailでSecrets Managerの操作履歴を調べました。
$ aws cloudtrail lookup-events \
--lookup-attributes AttributeKey=EventSource,AttributeValue=secretsmanager.amazonaws.com \
--start-time "2025-12-09T00:00:00Z" \
--end-time "2025-12-09T12:00:00Z"
すると、こんなイベントが見つかりました。
| 時刻 (JST) | イベント | 実行者 |
|---|---|---|
| 11:07:45 | RotationStarted | (自動) |
| 11:08:00 | GetRandomPassword | SLRSession |
| 11:08:00 | PutSecretValue | SLRSession |
| 11:09:01 | UpdateSecretVersionStage | SLRSession |
| 11:09:01 | RotationSucceeded | (自動) |
Secrets Managerが自動的にパスワードをローテーションしていました。
Secrets Managerの設定を確認
$ aws secretsmanager describe-secret \
--secret-id "rds!cluster-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
{
"RotationEnabled": true,
"RotationRules": {
"AutomaticallyAfterDays": 7
},
"LastRotatedDate": "2025-12-09T11:09:01+09:00"
}
デフォルトで7日ごとに自動ローテーションが設定されていました。
なぜ今まで気づかなかったのか
実は、パスワードがローテーションされること自体は認識していました。
開発中は頻繁にデプロイしていたため、ローテーションが発生してもすぐに新しいタスクが起動し、最新の認証情報を取得していたのです。つまり、デプロイのたびに自然と問題が解消されていたので、この仕様に気づいていませんでした。
ユーザーの利用を開始し、リリース頻度を落としたタイミングで、ついにこの問題が露呈したというわけです。
根本原因
改めて原因を整理します。
- 11:07 - Secrets Managerがパスワードの自動ローテーションを開始
- 11:09 - RDSのmaster credentialsが更新される
- ECSタスクは古いパスワードをメモリにキャッシュしたまま稼働継続
ECSタスクは起動時にSecrets Managerから認証情報を取得しますが、その後は再取得しません。パスワードがローテーションされても、タスクは古いパスワードを使い続けます。
既存のDB接続はしばらく動作し続けますが、コネクションプールが新しい接続を確立しようとしたタイミングで認証エラーが発生しました。ローテーションから障害発生までにタイムラグがあるため、原因の特定に時間がかかることもあります。
対策オプション
この問題への対策として、以下のアプローチが考えられます。
1. EventBridge + Lambdaでローテーション検知→ECS再デプロイ(推奨)
Secrets Managerのローテーション完了イベントをEventBridgeで検知し、LambdaでECSサービスを再デプロイします。アプリケーションコードの変更が不要なのがメリットです。
2. アプリケーションで動的に認証情報を再取得
DB接続時に毎回Secrets Managerから認証情報を取得する方法です。Secrets Managerへのアクセス頻度が増えるため、キャッシュ戦略の検討が必要です。
3. IAM認証への移行
Secrets Managerではなく、RDSのIAM認証を使う方法です。IAMロールベースで認証するため、パスワードのローテーション問題自体が発生しません。ただし、アプリケーション側の認証方式の変更が必要です。
4. ローテーション間隔の延長(暫定対応)
ローテーション間隔を7日から長くすることで、発生頻度を下げる方法です。根本解決ではありませんが、対策を検討する時間を稼げます。
まとめ
ECSタスクは認証情報をメモリにキャッシュする
今回の問題の本質は、ECSタスクが起動時に取得した認証情報をメモリにキャッシュし続けることです。
ECSタスク定義でSecrets Managerを参照していても、それはタスク起動時に一度だけ解決されます。その後Secrets Manager側でパスワードが変わっても、実行中のタスクには反映されません。RDS Managed Secretsはデフォルトで7日ごとに自動ローテーションが有効なので、長期間デプロイしないと今回のような問題に遭遇します。
Secrets Managerを使う場合は、ローテーション後にタスクを再起動する仕組みをセットで設計しましょう。
aws login + Claude Codeは便利
今回の調査ではaws loginでCLI認証し、Claude Codeと一緒にCloudTrailやRDSイベントを調べました。対話しながらコマンドを実行して原因を特定できるので、障害調査がとても捗ります。
現在は暫定対応を行っており、本格的な対策は別途検討中です。