概要
データベースのパスワードを手で管理していると、「誰かが変えたら誰かが困る」ため、結局変えられなくなります。長期間同じパスワードが使われ続け、退職者の記憶にも残り、設定ファイルにも書かれたままになります。
AWS Secrets Managerの自動ローテーションは、この状態を解消する仕組みです。Secrets Managerがパスワードを生成してデータベース側に反映し、アプリケーションはシークレットを都度取得することで、パスワードを知らないまま接続できるようになります。
ローテーションの実現方法は2つあります。RDSやAuroraのマスターユーザーであれば、Lambda関数を用意しなくて済むマネージドローテーションが使えます。それ以外のユーザーや独自の要件がある場合は、Lambda関数によるローテーションを使い、単一ユーザーか交代ユーザーかの戦略を選びます。
この記事では、両者の違いを整理したうえで、RDSインスタンスのマスターユーザー認証情報をSecrets Managerで管理し、ローテーションを実行してバージョンが切り替わることを確認します。

クラウドおさるRDSのマスターユーザー認証情報をSecrets Managerに預け、ローテーションを回してバージョンが切り替わるところまで確かめるでござる。Lambda関数を用意しなくてよいマネージドローテーションが、今日の主役でござるな。
この記事のメリット
- マネージドローテーションとLambdaローテーションの使い分けを判断できるようになる
- 単一ユーザーローテーションと交代ユーザーローテーションの違いを説明できるようになる
- ステージラベル(
AWSCURRENT/AWSPENDING/AWSPREVIOUS)の役割が分かるようになる - ローテーションのスケジュール指定(
rate()/cron()・ウィンドウ)を設定できるようになる - SCS試験で認証情報の管理・ローテーションを問う設問に答えられるようになる
執筆者とキャラクター紹介
執筆者:土肥(とひ)
株式会社ジェニュインの代表であり元エンジニア。これまでオンプレミスと AWS 環境のインフラ業務を担当。AWS 認定資格の学習で得た知識を、ハンズオンとともに解説するのが得意。直近では新人の教育も行っており、これから技術を学ぶ方が納得できる解説を心がけています。基礎編・Cloud Practitioner の記事では、解説役としても登場します。


クラウドおさる



はじめましてでござる。弊猿はクラウドおさる。IT インフラが異常に発達した猿山から、雲に乗って地上の AWS を学びに降りてきたのでござる。



基礎編や Cloud Practitioner の記事では、とひさんに素朴な疑問をぶつける役でござるな。Security - Specialty などの記事では、要所でワンポイントや注意点をひとこと添えるでござる。



猿山にもデータセンターや監視当番があって、地上で起きることはだいたい猿山にも同じ仕組みがあるのでござる。例え話がつい猿山に寄るのは、弊猿の癖でござる。
技術解説
2つのローテーション方式
| 方式 | Lambda関数 | 対象 |
|---|---|---|
| マネージドローテーション | 不要。Secrets Managerが設定と管理を代行する | Amazon RDS / Aurora / DocumentDB のマスターユーザー認証情報、Amazon Redshift の管理者パスワード、Amazon ECS Service Connect の TLS 証明書、マネージド外部シークレット |
| Lambda関数によるローテーション | 必要。AWS提供のテンプレートか自作の関数を使う | 上記以外のデータベースユーザー、サードパーティのAPIキーなど |
マスターユーザーの認証情報を回すだけなら、マネージドローテーションを選ぶのが最も手数が少なくなります。「アプリケーション用の一般ユーザーを回したい」「MySQL以外の独自システムの認証情報を回したい」といった場合にLambda関数の出番になります。
Lambdaローテーションの2つの戦略
Lambda関数によるローテーションでは、戦略を2つから選びます。この違いはSCS試験で問われます。
| 戦略 | 仕組み | 向いているケース |
|---|---|---|
| 単一ユーザーローテーション | 1つのシークレットの中で、1人のユーザーの認証情報を更新する | ほとんどのユースケース。特にアドホックユーザーや対話的に使うユーザー |
| 交代ユーザーローテーション | 最初のローテーションでユーザーのクローンを作り、以降はパスワードを更新するユーザーを交互に切り替える | 高可用性が要るアプリケーション。ローテーション中も有効な認証情報を取り続けたい場合 |
交代ユーザーローテーションには前提があります。クローンを作る権限が要るため、別のシークレットに superuser の認証情報を用意する必要があります。また、クローン作成後に元のユーザーの権限を変えたときは、クローン側の権限も変える必要があります。
単一ユーザーローテーションでも、データベース側のパスワードを変えてからシークレットが更新されるまでの間に、古い認証情報を使う呼び出しが拒否される可能性は残ります。どちらの戦略でも、アプリケーション側に再試行の実装があることが前提になります。





交代ユーザーローテーションは、クローンを作るために superuser の認証情報を別のシークレットに用意する必要があるのでござる。そしてどちらの戦略でも、アプリケーション側に再試行の実装があることが前提でござるぞ。
ステージラベル
Secrets Managerは、シークレットのバージョンにラベルを付けて管理します。
| ラベル | 意味 |
|---|---|
AWSCURRENT | 現在有効なバージョン。GetSecretValue でラベルを指定しないとこれが返る |
AWSPENDING | ローテーション中の新しいバージョン。テストが通ると AWSCURRENT に昇格する |
AWSPREVIOUS | 直前まで有効だったバージョン。切り戻しの余地を残すために保持される |
ローテーションが失敗しても、AWSCURRENT が古いバージョンのままなので、アプリケーションは動き続けます。ローテーションの失敗が即座に障害にならないのは、この仕組みのためです。



ローテーションが失敗しても、AWSCURRENT は古いバージョンのままなのでアプリケーションは動き続けるでござる。猿山の門番交代も、新しい当番(AWSPENDING)が引き継ぎの確認に通るまでは今の当番が門に立ち、前の当番(AWSPREVIOUS)も控えに残るのでござるな。
スケジュールの指定
ローテーションのスケジュールは rate() または cron() の式で指定します。コンソールにはスケジュール式のビルダーもあります。時刻はUTCで扱われます。
aws secretsmanager rotate-secret \
--secret-id MySecret \
--rotation-rules "{\"ScheduleExpression\": \"cron(0 16 1,15 * ? *)\", \"Duration\": \"2h\"}"この例は「毎月1日と15日の16:00〜18:00(UTC)の間にローテーションする」という指定です。
| 項目 | 内容 |
|---|---|
| 開始時刻 | 指定しない場合は午前0時に開始 |
ウィンドウ期間(Duration) | ローテーションを実行する時間帯の長さ(例: 3h) |
| 最小の頻度 | 4時間ごとまで指定できる |
ウィンドウを指定しておくと、負荷の低い時間帯にローテーションを寄せられます。
アプリケーション側の作り
ローテーションを入れる以上、アプリケーションは接続のたびにシークレットを取得するか、少なくとも認証エラー時に取得し直す作りにしておく必要があります。起動時に一度だけ読んで保持する作りだと、ローテーション後に接続できなくなります。
| やること | 理由 |
|---|---|
| シークレットをキャッシュしつつ、認証エラーで取り直す | ローテーション直後の失敗を自動で回復できる |
| 再試行を実装する | パスワード変更の反映に時間差があるため |
| シークレットの取得権限をIAMで絞る | secretsmanager:GetSecretValue が要る。カスタマー管理キーで暗号化している場合は、そのキーの kms:Decrypt も要る(既定の aws/secretsmanager なら不要) |
実践
RDSインスタンスをマスター認証情報のマネージドローテーション付きで作成し、スケジュールを設定して手動でローテーションを実行し、バージョンが切り替わることを確認します。
前提条件
- リージョン:
ap-northeast-1(東京) - RDS・Secrets Managerの操作権限を持つIAMユーザーまたはロールでコンソールにログイン済みであること
- デフォルト VPC が利用できること
このハンズオンで作成するリソースは以下のとおりです。
| リソース種別 | リソース名 | 用途 |
|---|---|---|
| RDS DBインスタンス | rotation-lab-db(MySQL・db.t4g.micro・シングル AZ) | ローテーション対象 |
| Secrets Managerのシークレット | rds!db-<自動生成> | マスターユーザー認証情報 |
RDSインスタンスは起動している間ずっと課金されます。検証が終わったら必ず削除してください。この手順では最小構成(db.t4g.micro・20 GiB・シングル AZ・自動バックアップ無効)で作成します。作成画面の既定値(ストレージ 200 GiB、自動スケーリング、拡張モニタリングなど)はそのままだと費用が増えるため、手順どおりに変更します。
手順1: マスター認証情報の管理を有効にしてRDSを作成する
AWSマネジメントコンソールにログインし、リージョンが ap-northeast-1(東京)であることを確認します。
上部の検索バーに RDS と入力し、「Aurora and RDS」を選択します。左側ナビゲーションの「データベース」から「データベースの作成」をクリックし、以下を設定します。
- データベース作成方法:
フル設定 - エンジンのオプション:
MySQL(エディション・バージョンは既定のまま) - テンプレート:
開発/テスト - 可用性と耐久性:
シングル AZ DB インスタンスデプロイ (1 インスタンス) - DB インスタンス識別子:
rotation-lab-db - マスターユーザー名:
admin(既定のまま) - 認証情報管理:
AWS Secrets Manager で管理(暗号化キーは既定のaws/secretsmanager)


続けて以下を設定します。
- DB インスタンスクラス:
バースト可能クラスを選び、db.t4g.microを選択(既定は db.t3.micro なので、一覧を絞り込んで選びます) - ストレージ: 割り当てられたストレージを
20GiB に変更し、「追加のストレージ設定」で「ストレージの自動スケーリングを有効にする」のチェックを外す - 接続 ─ パブリックアクセス:
なし - モニタリング: 「拡張モニタリングの有効化」のチェックを外す
- 追加設定 ─ 「自動バックアップを有効にする」のチェックを外す
その他の項目はデフォルトのままにして、「データベースの作成」をクリックします。作成には数分〜十数分かかります。
手順2: 作成されたシークレットを確認する
データベースのステータスが 利用可能 になったら、rotation-lab-db を開きます。「設定」タブの「マスター認証情報 ARN」に、Secrets Manager のシークレットの ARN が表示されています。
上部の検索バーに Secrets Manager と入力し、「Secrets Manager」を選択します。シークレットの一覧で rds!db- と入力して絞り込むと、rds!db- で始まる名前のシークレットが作成されています。


シークレットを開き、「シークレットの値」の「シークレットの値を取得する」をクリックします。「キー/値」タブに username と password が保存されていることを確認します。


手順3: ローテーションの設定を確認する
同じ画面の「ローテーション」タブを開きます。ローテーションのステータスが「有効」で、スケジュールが 7 日になっています。RDS が管理するシークレットは作成時点でローテーションが有効になっており、作成直後に 1 回目のローテーションも実行されています。


「ローテーションを編集」をクリックします。「ローテーション設定を編集する」ダイアログの「ローテーション関数」欄に、「Amazon RDS (rds) がこのシークレットのローテーションを管理するため、お客様は Lambda ローテーション関数を選択する必要はありません」と表示されていることを確認します。これがマネージドローテーションです。
続けて、ローテーションスケジュールを以下のように設定します。
- 日:
30(「スケジュール式ビルダー」、時間単位日のまま) - ウィンドウ期間:
2h - 「シークレットを保存するとすぐにローテーションさせます」: チェックを外す(このあと手動で実行するため)


「保存」をクリックします。ローテーションスケジュールが rate(30 days) に変わります。
手順4: 手動でローテーションを実行する
「ローテーション」タブの「すぐにシークレットをローテーションさせる」をクリックします。確認ダイアログで「ローテーションさせる」をクリックすると、ローテーションが開始されます。
1 分ほどで、「最終ローテーション実行日」が更新されます。


手順5: バージョンが切り替わったことを確認する
「バージョン」タブを開きます。「シークレットバージョン」の一覧で、新しいバージョンに AWSCURRENT、直前のバージョンに AWSPREVIOUS のステージングラベルが付いていることを確認します。新しいバージョンには、ローテーションの途中で使われる AWSPENDING も残って表示されることがあります。


CLIからも確認できます。コンソール上部の CloudShell アイコンから CloudShell を開き、次のコマンドを実行します。パスワードそのものは画面に表示せず、バージョンのステージラベルと、2つのパスワードが異なるかどうかだけを確認します。
SECRET_ID=$(aws secretsmanager list-secrets \
--filters Key=name,Values='rds!db-' --query 'SecretList[0].ARN' --output text)
# バージョンごとのステージラベル
aws secretsmanager list-secret-version-ids --secret-id "$SECRET_ID" \
--query "Versions[].[VersionId, join(',', VersionStages)]" --output table
# 現在のパスワードと直前のパスワードを、表示せずに比較する
CURRENT=$(aws secretsmanager get-secret-value --secret-id "$SECRET_ID" \
--query SecretString --output text | jq -r .password)
PREVIOUS=$(aws secretsmanager get-secret-value --secret-id "$SECRET_ID" \
--version-stage AWSPREVIOUS --query SecretString --output text | jq -r .password)
[ "$CURRENT" != "$PREVIOUS" ] && echo "パスワードは切り替わっています"シークレット名の ! は、ダブルクォートの中に書くと bash の履歴展開と解釈されてエラーになるため、シングルクォートで囲んでいます。
AWSCURRENT と AWSPREVIOUS が別のバージョンに付いていて、「パスワードは切り替わっています」と表示されることを確認します。アプリケーションは常に AWSCURRENT を取得するため、パスワードが変わったことを意識せずに接続できます。





マスターユーザーならマネージドローテーション、それ以外はLambda、そして単一ユーザーか交代ユーザーかを要件で選べるかが試験の観点でござるな。「ローテーション中も接続を維持したい」と「一般的な用途」を取り違えないことが肝でござる。
まとめ
| 要件 | 選ぶもの |
|---|---|
| RDS・Auroraのマスターユーザーを回したい | マネージドローテーション(Lambda不要) |
| アプリ用の一般ユーザーやAPIキーを回したい | Lambda関数によるローテーション |
| ローテーション中も確実に接続を維持したい | 交代ユーザーローテーション(superuser のシークレットが別途必要) |
| 一般的な用途 | 単一ユーザーローテーション |
- ローテーションの実体は「新しいパスワードを作り、データベースに反映し、シークレットを更新する」流れ
- ステージラベルにより、ローテーションが失敗しても
AWSCURRENTは古いまま保たれる - スケジュールは
rate()/cron()で指定し、ウィンドウを指定して負荷の低い時間帯に寄せられる。最小は4時間ごと - アプリケーションはシークレットを都度取得し、認証エラー時に取り直す作りにしておく
- シークレットの取得には
secretsmanager:GetSecretValueが要る。カスタマー管理キーで暗号化している場合は、そのキーのkms:Decryptも要る
参照先
- AWS Secrets Manager のマネージドローテーション – AWS Secrets Manager
- Lambda 関数のローテーション戦略 – AWS Secrets Manager
- AWS Secrets Manager でのシークレットのローテーション – AWS Secrets Manager
- シークレットのバージョン – AWS Secrets Manager
- Amazon RDS と AWS Secrets Manager の統合 – Amazon RDS
- AWS Secrets Manager のアイデンティティベースのポリシーの例 – AWS Secrets Manager











