RDSの認証情報を自動ローテーションする ── マネージドローテーションとLambdaローテーション

目次

概要

データベースのパスワードを手で管理していると、「誰かが変えたら誰かが困る」ため、結局変えられなくなります。長期間同じパスワードが使われ続け、退職者の記憶にも残り、設定ファイルにも書かれたままになります。

AWS Secrets Managerの自動ローテーションは、この状態を解消する仕組みです。Secrets Managerがパスワードを生成してデータベース側に反映し、アプリケーションはシークレットを都度取得することで、パスワードを知らないまま接続できるようになります。

ローテーションの実現方法は2つあります。RDSやAuroraのマスターユーザーであれば、Lambda関数を用意しなくて済むマネージドローテーションが使えます。それ以外のユーザーや独自の要件がある場合は、Lambda関数によるローテーションを使い、単一ユーザーか交代ユーザーかの戦略を選びます。

この記事では、両者の違いを整理したうえで、RDSインスタンスのマスターユーザー認証情報をSecrets Managerで管理し、ローテーションを実行してバージョンが切り替わることを確認します。

Secrets Manager によるローテーション ── アプリはパスワードを知らないまま接続する
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 の認証情報を用意する必要があります。また、クローン作成後に元のユーザーの権限を変えたときは、クローン側の権限も変える必要があります。

単一ユーザーローテーションでも、データベース側のパスワードを変えてからシークレットが更新されるまでの間に、古い認証情報を使う呼び出しが拒否される可能性は残ります。どちらの戦略でも、アプリケーション側に再試行の実装があることが前提になります。

2つのローテーション戦略とステージラベル
2つのローテーション戦略とステージラベル
クラウドおさる

交代ユーザーローテーションは、クローンを作るために 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 なら不要)
フリーランス案件
クラウドおさる
クラウドキャリアフリーランス

AWS の実務経験があるなら、単価を上げにいく

AWS に特化したフリーランスエージェントです。以下は取り扱い案件の一例です。設計・SRE・セキュリティ・生成 AI の領域で、専門を掛け合わせるほど単価が上がります。

横にスクロールできます。掲載時点の情報のため、募集が終了している場合があります。条件の近い案件をご紹介しますので、お気軽にご相談ください。

実践

ハンズオンガイド6 ステップ画面 8 枚

コンソールの横に開いて、チェックしながら進めましょう。

ガイドを開く

別タブで開きます。チェックはこのブラウザに保存されます。

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)
RDS作成画面の認証情報管理(Secrets Managerで管理を選択した状態)
RDS作成画面の認証情報管理(Secrets Managerで管理を選択した状態)

続けて以下を設定します。

  • DB インスタンスクラス: バースト可能クラス を選び、db.t4g.micro を選択(既定は db.t3.micro なので、一覧を絞り込んで選びます)
  • ストレージ: 割り当てられたストレージを 20 GiB に変更し、「追加のストレージ設定」で「ストレージの自動スケーリングを有効にする」のチェックを外す
  • 接続 ─ パブリックアクセス: なし
  • モニタリング: 「拡張モニタリングの有効化」のチェックを外す
  • 追加設定 ─ 「自動バックアップを有効にする」のチェックを外す

その他の項目はデフォルトのままにして、「データベースの作成」をクリックします。作成には数分〜十数分かかります。

手順2: 作成されたシークレットを確認する

データベースのステータスが 利用可能 になったら、rotation-lab-db を開きます。「設定」タブの「マスター認証情報 ARN」に、Secrets Manager のシークレットの ARN が表示されています。

上部の検索バーに Secrets Manager と入力し、「Secrets Manager」を選択します。シークレットの一覧で rds!db- と入力して絞り込むと、rds!db- で始まる名前のシークレットが作成されています。

Secrets Managerのシークレット一覧(rds! で始まるシークレットが作成された状態)
Secrets Managerのシークレット一覧(rds! で始まるシークレットが作成された状態)

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

シークレットの値(ユーザー名とパスワードが保存されている状態)
シークレットの値(ユーザー名とパスワードが保存されている状態)

手順3: ローテーションの設定を確認する

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

ローテーションタブ(ローテーションが有効な状態)
ローテーションタブ(ローテーションが有効な状態)

「ローテーションを編集」をクリックします。「ローテーション設定を編集する」ダイアログの「ローテーション関数」欄に、「Amazon RDS (rds) がこのシークレットのローテーションを管理するため、お客様は Lambda ローテーション関数を選択する必要はありません」と表示されていることを確認します。これがマネージドローテーションです。

続けて、ローテーションスケジュールを以下のように設定します。

  • 日: 30(「スケジュール式ビルダー」、時間単位 日 のまま)
  • ウィンドウ期間: 2h
  • 「シークレットを保存するとすぐにローテーションさせます」: チェックを外す(このあと手動で実行するため)
ローテーションスケジュールの編集画面
ローテーションスケジュールの編集画面

「保存」をクリックします。ローテーションスケジュールが rate(30 days) に変わります。

手順4: 手動でローテーションを実行する

「ローテーション」タブの「すぐにシークレットをローテーションさせる」をクリックします。確認ダイアログで「ローテーションさせる」をクリックすると、ローテーションが開始されます。

1 分ほどで、「最終ローテーション実行日」が更新されます。

ローテーションの実行結果(最終ローテーション実行日が更新された状態)
ローテーションの実行結果(最終ローテーション実行日が更新された状態)

手順5: バージョンが切り替わったことを確認する

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

シークレットのバージョン一覧(AWSCURRENTとAWSPREVIOUSが確認できる状態)
シークレットのバージョン一覧(AWSCURRENTとAWSPREVIOUSが確認できる状態)

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 を取得するため、パスワードが変わったことを意識せずに接続できます。

CLIでステージラベルを確認し、パスワードが切り替わったことを確かめた結果
CLIでステージラベルを確認し、パスワードが切り替わったことを確かめた結果
クラウドおさる

マスターユーザーならマネージドローテーション、それ以外はLambda、そして単一ユーザーか交代ユーザーかを要件で選べるかが試験の観点でござるな。「ローテーション中も接続を維持したい」と「一般的な用途」を取り違えないことが肝でござる。

まとめ

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

参照先

フリーランス案件
クラウドおさる
クラウドキャリアフリーランス

AWS の実務経験があるなら、単価を上げにいく

AWS に特化したフリーランスエージェントです。以下は取り扱い案件の一例です。設計・SRE・セキュリティ・生成 AI の領域で、専門を掛け合わせるほど単価が上がります。

横にスクロールできます。掲載時点の情報のため、募集が終了している場合があります。条件の近い案件をご紹介しますので、お気軽にご相談ください。

この記事が気に入ったら
フォローしてね!

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

株式会社ジェニュイン(https://genuine-pt.jp)の代表取締役.

2018年〜インフラエンジニアとしてキャリアをスタートし、オンプレミスのネットワーク・サーバ環境で3年半、クラウド環境で4年半の8年間エンジニアとして従事。
2021年に佐藤氏の創業した株式会社Luxyを引き継ぎ、代表に就任。
その後アガルートグループ内の株式会社ジェニュインと合併。
合併後同社代表に就任。

目次