RDSの認証情報を自動ローテーションする ── マネージドローテーションとLambdaローテーション
記事の「実践」を 1 項目ずつ進めるためのページです。AWS マネジメントコンソールで操作したら、右の一覧にチェックを入れてください。チェックはこのブラウザに保存されます。
前提条件
- リージョン:
ap-northeast-1(東京) - RDS・Secrets Managerの操作権限を持つIAMユーザーまたはロールでコンソールにログイン済みであること
- デフォルト VPC が利用できること
このハンズオンで作成するリソースは以下のとおりです。
| リソース種別 | リソース名 | 用途 |
|---|---|---|
| RDS DBインスタンス | rotation-lab-db(MySQL・db.t4g.micro・シングル AZ) | ローテーション対象 |
| Secrets Managerのシークレット | rds!db-<自動生成> | マスターユーザー認証情報 |
> [!WARNING] > 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 を取得するため、パスワードが変わったことを意識せずに接続できます。