「アプリケーションのDB接続パスワード、どこに保存していますか?」
オンプレミス時代は設定ファイルにパスワードを直書きしたり、Excelの管理台帳で共有したりするのが当たり前でした。しかしクラウド環境では、EC2やLambdaが動的にスケールし、コンテナが使い捨てで起動する世界です。設定ファイルにパスワードを埋め込む方式は、セキュリティリスクが格段に上がります。
この記事では、AWS Secrets Managerを使ったシークレット管理の基本から、オンプレ環境との違い、実際の運用フローまでを解説します。「パスワードをどこに置くか」という現場の悩みを、クラウドネイティブなやり方で解決する方法がわかります。

なぜシークレット管理が必要なのか?オンプレとの違い
オンプレ環境でのパスワード管理を振り返ってみましょう。多くの現場では、こんな運用が一般的でした。
・設定ファイルに直書き: /etc/myapp/config.ini にDB接続パスワードを平文で記載
・環境変数にセット: .bashrcやsystemdのUnitファイルにパスワードを記載
・Excel管理台帳: 共有フォルダにあるパスワード一覧ファイルで管理
・手動ローテーション: 年に1回、運用担当者がパスワードを変更して回る
この方式がクラウドで破綻する理由は明確です。
1. コードリポジトリへの混入リスク
設定ファイルにパスワードを書く文化のまま開発を進めると、GitHubやCodeCommitにパスワードがプッシュされる事故が起きます。GitGuardianの調査によると、パブリックリポジトリで検出されるシークレットの漏洩は年間1,000万件を超えています。
2. オートスケーリング環境での配布問題
EC2 Auto Scalingで新しいインスタンスが自動起動するとき、そのインスタンスにパスワードをどう渡すかという問題が発生します。AMIにパスワードを焼き込むのは論外ですし、UserDataに書くのもCloudTrailに記録されるため危険です。
3. ローテーションの自動化
オンプレでは「年1回のパスワード変更」で済んでいたかもしれません。しかしクラウドのセキュリティベストプラクティスでは、30日〜90日ごとのローテーションが推奨されています。手動では現実的に回りません。
AWS Secrets Managerの基本的な仕組み
AWS Secrets Managerは、パスワード、APIキー、データベース認証情報などのシークレットを暗号化して一元管理するマネージドサービスです。
| 機能 | AWS Secrets Manager | オンプレ相当 |
|---|---|---|
| シークレット保管 | 暗号化されたKVストア | 設定ファイル / 管理台帳 |
| アクセス制御 | IAMポリシー + リソースポリシー | ファイルパーミッション / AD権限 |
| 暗号化 | AWS KMSによる自動暗号化 | 手動でのファイル暗号化 |
| ローテーション | Lambda連携で自動ローテーション | 手動で定期変更 |
| 監査ログ | CloudTrailに自動記録 | 独自のアクセスログ |
ポイントは、アプリケーションが直接パスワードを持たないという設計思想です。アプリはSecrets ManagerのAPIを呼び出してパスワードを取得し、メモリ上でのみ使用します。設定ファイルやコードにパスワードは一切残りません。
料金体系(2026年4月時点)
・シークレット保管: 1シークレットあたり月額$0.40(USD)
・API呼び出し: 10,000回あたり$0.05(USD)
たとえばRDSのパスワード1つを管理し、1日1,000回のAPI呼び出しがある場合、月額コストは$0.40 + $0.15 = 約$0.55です。オンプレでの管理工数を考えれば、十分にコスト効率が良い水準です。

シークレットの作成と取得(コンソール操作 + CLI)
1. マネジメントコンソールでシークレットを作成する
AWSマネジメントコンソールからSecrets Managerを開き、「新しいシークレットを保存する」をクリックします。
シークレットのタイプを選択します。RDS、Redshift、DocumentDBの認証情報であれば専用のテンプレートが用意されています。それ以外のパスワードやAPIキーは「その他のシークレットのタイプ」を選びます。
キーと値のペアでシークレットを入力します。たとえばDB接続情報なら、以下のように設定します。
・username: myapp_user
・password: (自動生成または手動入力)
・host: mydb.cluster-xxxx.ap-northeast-1.rds.amazonaws.com
・port: 3306
暗号化キーはデフォルトの aws/secretsmanager(AWS管理キー)で問題ありません。独自のKMSキーを使う場合は、ここで選択します。
シークレット名を入力します。命名規則は「環境/サービス/用途」のスラッシュ区切りがおすすめです。例: prod/myapp/db-credentials
2. AWS CLIでシークレットを作成する
# AWS CLIでシークレットを作成 aws secretsmanager create-secret \ --name prod/myapp/db-credentials \ --description "本番環境のDB接続情報" \ --secret-string '{"username":"myapp_user","password":"MyStr0ngP@ss!","host":"mydb.cluster-xxxx.ap-northeast-1.rds.amazonaws.com","port":"3306"}' \ --region ap-northeast-1
3. アプリケーションからシークレットを取得する
Python(boto3)での取得例です。
# Python boto3でシークレットを取得 import boto3 import json def get_db_credentials(): client = boto3.client('secretsmanager', region_name='ap-northeast-1') response = client.get_secret_value(SecretId='prod/myapp/db-credentials') secret = json.loads(response['SecretString']) return secret # 使用例 creds = get_db_credentials() print(f"Host: {creds['host']}, User: {creds['username']}")
AWS CLIでの取得はこちらです。
# AWS CLIでシークレットを取得 aws secretsmanager get-secret-value \ --secret-id prod/myapp/db-credentials \ --region ap-northeast-1 \ --query SecretString \ --output text | jq .
自動ローテーションの設定
Secrets Managerの最大の強みは、パスワードの自動ローテーションです。RDS、Redshift、DocumentDBについてはAWSが用意したLambda関数を使って、ほぼ設定するだけでローテーションが動きます。
RDSパスワードの自動ローテーション設定
コンソールでシークレットの詳細画面を開き、「ローテーション」セクションの「編集」をクリックします。
ローテーションスケジュールを設定します。一般的な運用では30日ごとが推奨です。コンプライアンス要件に応じて7日〜365日の範囲で設定できます。
ローテーションの仕組みは、裏側でLambda関数が以下のステップを実行しています。
・createSecret: 新しいパスワードを生成し、Secrets Managerに「AWSPENDING」ステージとして保存
・setSecret: RDSのマスターユーザーを使って、DBのパスワードを新しいものに変更
・testSecret: 新しいパスワードでDBに接続できるかテスト
・finishSecret: テスト成功後、「AWSPENDING」を「AWSCURRENT」に昇格
ローテーション時のダウンタイムを防ぐ設計
自動ローテーションで一番心配なのが「パスワード変更の瞬間にアプリが接続エラーを起こさないか」です。
これを防ぐには、シングルユーザーローテーションではなく、マルチユーザーローテーション戦略を使います。
・シングルユーザー: 1つのDBユーザーのパスワードを直接更新する。ローテーション中の数秒間、旧パスワードでの接続が失敗する可能性がある
・マルチユーザー: 2つのDBユーザーを交互に使う。一方のパスワードを更新中も、もう一方で接続できるため、ダウンタイムが発生しない
本番環境では、マルチユーザー戦略の採用を強く推奨します。
実務で使えるSecrets Managerの設計パターン
パターン1: マルチ環境でのシークレット管理
開発・ステージング・本番の各環境でシークレットを分離するには、命名規則とIAMポリシーを組み合わせます。
# 命名規則の例 dev/myapp/db-credentials stg/myapp/db-credentials prod/myapp/db-credentials # IAMポリシーで環境ごとにアクセスを制限 # 開発チームには dev/* のみ、本番運用チームには prod/* のみを許可
IAMポリシーの設定例です。
# 本番環境のシークレットのみ取得可能なIAMポリシー { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "secretsmanager:GetSecretValue" ], "Resource": "arn:aws:secretsmanager:ap-northeast-1:123456789012:secret:prod/*" } ] }
パターン2: LambdaからSecrets Managerを使う
Lambda関数でDB接続する際は、コールドスタートのたびにSecrets ManagerのAPIを呼ぶとレイテンシが増えます。AWS提供のLambda Extensionを使えば、シークレットをローカルキャッシュして呼び出し回数を削減できます。
# Lambda ExtensionのARN(東京リージョン(ap-northeast-1)、2026年4月時点) # AWS公式ドキュメントで最新のARNを確認してください arn:aws:lambda:ap-northeast-1:133490413xxx:layer:AWS-Parameters-and-Secrets-Lambda-Extension:XX
この拡張機能を使うと、シークレットはLambda実行環境のメモリにキャッシュされ、TTL(デフォルト300秒)の間はAPIを呼ばずにキャッシュから返されます。
パターン3: ECS/Fargateコンテナへの注入
ECSタスク定義でSecrets Managerのシークレットを環境変数として注入できます。コンテナイメージにパスワードを含める必要がなくなります。
# ECSタスク定義(JSON抜粋) { "containerDefinitions": [ { "name": "myapp", "secrets": [ { "name": "DB_PASSWORD", "valueFrom": "arn:aws:secretsmanager:ap-northeast-1:123456789012:secret:prod/myapp/db-credentials:password::" } ] } ] }
valueFromのARNの末尾に「:password::」とキー名を指定すると、JSON形式のシークレットから特定のキーだけを取り出して環境変数にセットできます。
よくあるトラブルと対処法
トラブル1: AccessDeniedExceptionが出る
シークレットの取得時にAccessDeniedExceptionが発生する場合、以下を確認します。
・IAMポリシー: secretsmanager:GetSecretValue のアクションが許可されているか
・KMSキー: シークレットの暗号化にカスタムKMSキーを使っている場合、kms:Decrypt の権限も必要
・リソースARN: ポリシーのResourceに指定したARNが正しいか。Secrets ManagerのARNにはランダムな6文字のサフィックスが付く
トラブル2: ローテーション後にアプリが接続エラーになる
ローテーション直後に接続エラーが発生する場合、アプリ側でシークレットをキャッシュしていることが原因です。
対処法は2つあります。
・キャッシュTTLを短くする: Secrets Manager SDKのキャッシュTTLを300秒以下に設定
・接続エラー時にリトライ: 接続失敗時にシークレットを再取得してリトライするロジックを実装
# リトライ付きDB接続(Python例) import time def connect_with_retry(max_retries=3): for attempt in range(max_retries): try: creds = get_db_credentials() # 毎回最新を取得 connection = mysql.connector.connect( host=creds['host'], user=creds['username'], password=creds['password'] ) return connection except mysql.connector.Error: if attempt < max_retries - 1: time.sleep(2) raise Exception("DB接続に失敗しました")
トラブル3: シークレットを誤って削除してしまった
Secrets Managerでシークレットを削除すると、デフォルトで7日間の猶予期間が設定されます。この期間中は復元が可能です。
# 削除予定のシークレットを復元 aws secretsmanager restore-secret \ --secret-id prod/myapp/db-credentials \ --region ap-northeast-1
本番環境のシークレットには、IAMポリシーで secretsmanager:DeleteSecret を制限しておくのが安全です。
Secrets Manager vs Systems Manager Parameter Store
AWSにはシークレット管理できるサービスがもう1つあります。Systems Manager Parameter Store(SSM Parameter Store)です。どちらを使うか迷う場面は多いので、違いを整理しておきます。
| 比較項目 | Secrets Manager | SSM Parameter Store |
|---|---|---|
| 料金 | $0.40/シークレット/月 | Standard無料 / Advanced $0.05/月 |
| 自動ローテーション | 組み込みサポートあり | 自分でLambdaを実装する必要あり |
| 暗号化 | デフォルトで暗号化 | SecureString型で暗号化 |
| クロスアカウント共有 | リソースポリシーで対応 | 非対応 |
| 最大サイズ | 64KB | Standard 4KB / Advanced 8KB |
| 向いている用途 | DB認証・APIキーなどの機密情報 | 設定値・フラグなど非機密情報も含む |
判断基準はシンプルです。自動ローテーションが必要なDB認証情報やAPIキーはSecrets Manager、アプリケーションの設定値や機密性の低いパラメータはSSM Parameter Storeを使います。コスト重視でローテーションが不要なら、SSM Parameter StoreのSecureStringでも十分です。

本記事のまとめ
AWS Secrets Managerを使ったシークレット管理の基本を解説しました。
| やりたいこと | Secrets Managerの機能 | オンプレ相当 |
|---|---|---|
| パスワードを安全に保管 | KMSで暗号化して一元管理 | 設定ファイル / Excel管理台帳 |
| アプリからパスワードを取得 | API呼び出し(SDK/CLI) | 設定ファイル読み込み |
| パスワードを定期変更 | Lambda連携の自動ローテーション | 手動で年1回変更 |
| 誰がいつ触ったか記録 | CloudTrailに自動記録 | 独自のアクセスログ |
| 環境ごとにアクセス制限 | IAMポリシー + 命名規則 | ファイルパーミッション |
オンプレ時代の「設定ファイルにパスワードを書く」運用から脱却し、クラウドネイティブなシークレット管理に移行することで、セキュリティレベルが大幅に向上します。まずは新規プロジェクトから導入して、既存システムの移行は段階的に進めるのが現実的です。
Linuxサーバー上でのAWS CLI設定やIAMの基礎については、姉妹サイトLinuxMaster.JPで詳しく解説しています。セキュリティの基本的な考え方を体系的に学びたい方は、セキュリティマスターズ.TOKYOもあわせてご覧ください。
パスワード管理、まだ設定ファイルに直書きしていませんか?
クラウド移行で見落とされがちなシークレット管理。Secrets Managerの導入は、セキュリティ強化の第一歩です。
オンプレの経験を活かしながら、現場で使えるクラウドスキルを体系的に身につけたい方へ、メルマガで実践的なクラウド活用ノウハウをお届けしています。


コメント