Secrets ManagerによるECSコンテナの認証情報管理と自動ローテーション

目次

概要

アプリケーションのソースコードやコンテナイメージにデータベースの認証情報をハードコードしていると、認証情報の漏洩リスクが高まるだけでなく、パスワード変更のたびにアプリケーションの再デプロイが必要になります。AWS Secrets Managerを使えば、認証情報をアプリケーションの外部で安全に管理し、自動ローテーションによってパスワードの定期更新を運用負荷なく実現できます。

本記事では、RDSの認証情報をSecrets Managerに移行し、ECSタスクからセキュアに参照する方法を解説します。Secrets Managerの自動ローテーション機能の仕組みや、Systems Manager Parameter Storeとの違いも整理します。

Secrets Manager がRDS認証情報を保管し、ECSタスクが起動時に取得、Lambdaが定期的にローテーションする全体像の図解
Secrets Manager がRDS認証情報を保管し、ECSタスクが起動時に取得、Lambdaが定期的にローテーションする全体像の図解

この記事のメリット

  • Secrets ManagerとSystems Manager Parameter Storeの機能差・使い分けを理解できる
  • Secrets Managerの自動ローテーション機能の仕組み(Lambda関数による4ステップ)を把握できる
  • ECSタスクロールとタスク実行ロールの違いを明確に区別できる
  • ECSタスク定義でシークレットを安全に参照する設定方法を学べる
  • SCS試験で「認証情報の安全な管理と自動ローテーション」を問われた際に正確に判断できるようになる

執筆者とキャラクター紹介

執筆者:土肥(とひ)

株式会社ジェニュインの代表であり元エンジニア。これまでオンプレミスと AWS 環境のインフラ業務を担当。AWS 認定資格の学習で得た知識を、ハンズオンとともに解説するのが得意。直近では新人の教育も行っており、これから技術を学ぶ方が納得できる解説を心がけています。基礎編・Cloud Practitioner の記事では、解説役としても登場します。

土肥

クラウドおさる

クラウドおさる

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

クラウドおさる

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

クラウドおさる

猿山にもデータセンターや監視当番があって、地上で起きることはだいたい猿山にも同じ仕組みがあるのでござる。例え話がつい猿山に寄るのは、弊猿の癖でござる。

技術解説

Secrets Manager vs Systems Manager Parameter Store

認証情報やAPIキーといった機密情報の管理には、Secrets ManagerとSystems Manager Parameter Storeの2つのサービスが候補になります。それぞれの特徴を整理します。

機能Secrets ManagerParameter Store
自動ローテーションあり(Lambda関数による自動ローテーション)なし(自前でLambdaを実装すれば可能だが、ネイティブ機能ではない)
RDS/Aurora/Redshift統合あり(専用のローテーション関数テンプレートが用意されている)なし
暗号化必須(AWS KMSで自動暗号化)オプション(SecureStringパラメータのみKMS暗号化)
クロスアカウントアクセスあり(リソースベースポリシーで実現)なし
コストシークレット1件あたり月額$0.40 + APIコール$0.05/10,000件Standard パラメータは無料(Advanced パラメータは有料)
バージョニングあり(ステージングラベルで管理)あり(バージョンIDで管理)

自動ローテーション機能はSecrets Manager固有の機能です。Parameter Storeにはネイティブの自動ローテーション機能がないため、RDSの認証情報を定期的に自動更新する要件ではSecrets Managerが適しています。

自動ローテーションの仕組み

Secrets Managerの自動ローテーションは、Lambda関数が4つのステップを順番に実行することで、アプリケーションのダウンタイムなくパスワードを更新します。

ステップ名前処理内容
1createSecret新しいパスワードを生成し、AWSPENDING ラベルでSecrets Managerに保存する
2setSecret生成した新しいパスワードをデータベース側に設定する
3testSecret新しいパスワードでデータベースへの接続をテストする
4finishSecretAWSPENDING ラベルを AWSCURRENT に移動し、ローテーションを完了する
Secrets Managerの自動ローテーション4ステップのフロー図(createSecret → setSecret → testSecret → finishSecret)
Secrets Managerの自動ローテーション4ステップのフロー図(createSecret → setSecret → testSecret → finishSecret)

この4ステップの仕組みにより、新しいパスワードが正常に動作することを確認してから切り替えが行われるため、安全にローテーションを実行できます。

ローテーション戦略

Secrets Managerは、データベースの種類や要件に応じて2つのローテーション戦略を提供しています。

戦略説明ユースケース
単一ユーザーローテーション同一ユーザーのパスワードを直接更新するシンプルな構成、管理オーバーヘッドを最小化したい場合
交代ユーザーローテーション2つのユーザーを交互に使用し、片方のパスワードを更新する高可用性が求められる場合(更新中も旧パスワードで接続可能)

RDSの場合、Secrets Managerが提供するマネージドのローテーション関数テンプレートを使用できるため、Lambda関数を一から実装する必要はありません。

ECSタスクロールとタスク実行ロール

ECSでは、コンテナに関連する2種類のIAMロールがあります。それぞれの役割を明確に区別することが重要です。

ロール用途設定するIAMポリシーの例
タスク実行ロールECSエージェントがコンテナを起動するために使用する。ECRからのイメージプル、CloudWatch Logsへのログ送信、Secrets Managerからのシークレット取得などsecretsmanager:GetSecretValue, ecr:GetDownloadUrlForLayer, logs:CreateLogStream
タスクロールコンテナ内で実行されるアプリケーションがAWSサービスにアクセスするために使用する。S3、DynamoDB、SQSなどへのアクセスs3:GetObject, dynamodb:PutItem, sqs:SendMessage

Secrets Managerのシークレットをタスク定義の secrets セクションで環境変数として注入する場合、タスク実行ロールに secretsmanager:GetSecretValue の権限が必要です。これはECSエージェントがコンテナ起動時にシークレットの値を取得して環境変数に設定するためです。

一方、アプリケーションコード内でSecrets Manager APIを直接呼び出してシークレットを取得する場合は、タスクロールに権限が必要です。

ECSタスク定義でのシークレット参照

ECSタスク定義の containerDefinitions 内の secrets セクションを使用することで、Secrets Managerのシークレットをコンテナの環境変数として安全に注入できます。

{
  "containerDefinitions": [
    {
      "name": "app-container",
      "image": "123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/my-app:latest",
      "secrets": [
        {
          "name": "DB_USERNAME",
          "valueFrom": "arn:aws:secretsmanager:ap-northeast-1:123456789012:secret:prod/myapp/rds-AbCdEf:username::"
        },
        {
          "name": "DB_PASSWORD",
          "valueFrom": "arn:aws:secretsmanager:ap-northeast-1:123456789012:secret:prod/myapp/rds-AbCdEf:password::"
        }
      ]
    }
  ]
}

valueFrom にはシークレットのARNを指定します。シークレットの値がJSON形式の場合、ARN:JSONキー:: の形式で特定のキーの値だけを取得できます。

この方法では、シークレットの値はタスク定義やコンテナイメージに含まれず、コンテナの起動時にECSエージェントがSecrets Managerから動的に取得します。

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

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

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

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

実践

ここでは、Secrets Managerでシークレットを作成し、自動ローテーションの設定を確認した上で、手動ローテーションのテストを行います。最後に、ECSタスク定義でシークレットを参照する設定例を確認します。

前提条件

  • リージョン: ap-northeast-1(東京)
  • Secrets Managerの操作権限を持つIAMユーザーでログインしていること
リソース種別リソース名用途
シークレットprod/myapp/rdsRDS認証情報の管理用

本手順ではシークレットの作成と自動ローテーション設定の確認を行います。実際のRDSインスタンスへの接続は行いません。

手順1: Secrets Managerでシークレットを作成する

  • AWSマネジメントコンソールにログインし、右上のリージョンが「アジアパシフィック(東京) ap-northeast-1」であることを確認します。
  • 上部の検索バーに Secrets Manager と入力し、表示された「Secrets Manager」を選択します。
  • 「新しいシークレットを保存する」をクリックします。シークレットの保存は4ステップのウィザードで進みます。
  • 「ステップ 1: シークレットのタイプを選択」の「シークレットのタイプ」で「その他のシークレットのタイプ」を選択します。

実際にRDSと連携する場合は「Amazon RDS データベースの認証情報」を選択しますが、本手順ではRDSインスタンスを用意していないため「その他のシークレットのタイプ」を使用します。

  • 「キー/値のペア」セクションで以下の2つのキーと値を入力します。2行目は「+ 行を追加」で追加します。
  • キー: username / 値: admin
  • キー: password / 値: MySecurePassword123!
  • 暗号化キーは aws/secretsmanager(デフォルト)のままにします。
シークレットのタイプ選択とキー/値ペアの入力状態
シークレットのタイプ選択とキー/値ペアの入力状態
  • 「次」をクリックします。
  • 「ステップ 2: シークレットを設定」の「シークレットの名前」に prod/myapp/rds と入力します。
  • 「説明」に RDS認証情報(ハンズオン用) と入力します。
  • その他の項目はデフォルトのままにします。
  • 「次」をクリックします。

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

「ステップ 3: ローテーションを設定する – オプション」が表示されます。

  • 「自動ローテーションを設定する」セクションの「自動ローテーション」トグルを確認します。デフォルトではオフで、その下の「ローテーションスケジュール」「ローテーション関数」はグレーアウトしています。
ローテーション設定画面 ── 自動ローテーションがオフで、スケジュールと関数がグレーアウトしている状態
ローテーション設定画面 ── 自動ローテーションがオフで、スケジュールと関数がグレーアウトしている状態

「自動ローテーション」を有効にすると、ローテーション間隔(日数)とローテーション関数(Lambda)を設定できます。RDSの認証情報を選択した場合は、Secrets Managerが提供するマネージドのローテーション関数テンプレートを選択できます。

自動ローテーションの設定項目を確認します。

設定項目説明
自動ローテーション有効/無効の切り替え
ローテーションスケジュールローテーション間隔(日数、時間、cron式)を指定
ローテーション関数ローテーションを実行するLambda関数を選択または新規作成
  • 本手順ではローテーションを有効にせず、デフォルトのまま「次」をクリックします。
  • 「ステップ 4: レビュー」で設定内容を確認し、「保存」をクリックします。

シークレット一覧に戻り、「シークレットは正常に保存されました prod/myapp/rds。」と表示されます。一覧から prod/myapp/rds をクリックすると詳細画面が開きます。

作成されたシークレットの詳細画面 ── 名前・説明・ARN・暗号化キーが表示されている状態
作成されたシークレットの詳細画面 ── 名前・説明・ARN・暗号化キーが表示されている状態

手順3: シークレットの値を確認する

シークレットの詳細画面で、保存された値を確認します。

  • 「シークレットの値」セクションで「シークレットの値を取得する」をクリックします。
  • 入力した username と password の値が表示されることを確認します。
シークレットの値セクション ── 「シークレットの値を取得する」でキー/値ペアが表示された状態
シークレットの値セクション ── 「シークレットの値を取得する」でキー/値ペアが表示された状態

手順4: 手動ローテーションをテストする

自動ローテーションを設定していなくても、手動でローテーションを実行できます。ここでは、シークレットの値を手動で更新し、新しい値に切り替わることを確認します。

  • シークレット詳細画面の「シークレットの値」セクションで「編集する」をクリックします。
  • password の値を NewPassword456! に変更します。
  • 「保存」をクリックします。「シークレット値が更新されました。」と表示されます。
シークレットの値の編集 ── password の値を変更した状態
シークレットの値の編集 ── password の値を変更した状態
  • 再度「シークレットの値を取得する」をクリックし、パスワードが NewPassword456! に更新されていることを確認します。

自動ローテーションが有効な場合は、Lambda関数が4ステップのプロセスを自動的に実行するため、手動でのパスワード変更は不要です。ローテーション間隔に応じてパスワードが自動的に更新されます。

手順5: ECSタスク定義でのシークレット参照設定を確認する

実際のECSタスク定義で、Secrets Managerのシークレットを環境変数として注入する設定例を確認します。

  • シークレット詳細画面で「シークレットの ARN」をコピーします(例: arn:aws:secretsmanager:ap-northeast-1:123456789012:secret:prod/myapp/rds-AbCdEf)。

ECSタスク定義のJSON形式では、以下のように secrets セクションでシークレットを参照します。

{
  "family": "my-app-task",
  "taskRoleArn": "arn:aws:iam::123456789012:role/ecsTaskRole",
  "executionRoleArn": "arn:aws:iam::123456789012:role/ecsTaskExecutionRole",
  "containerDefinitions": [
    {
      "name": "app",
      "image": "123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/my-app:latest",
      "secrets": [
        {
          "name": "DB_USERNAME",
          "valueFrom": "arn:aws:secretsmanager:ap-northeast-1:123456789012:secret:prod/myapp/rds-AbCdEf:username::"
        },
        {
          "name": "DB_PASSWORD",
          "valueFrom": "arn:aws:secretsmanager:ap-northeast-1:123456789012:secret:prod/myapp/rds-AbCdEf:password::"
        }
      ],
      "essential": true
    }
  ],
  "requiresCompatibilities": ["FARGATE"],
  "networkMode": "awsvpc",
  "cpu": "256",
  "memory": "512"
}

タスク実行ロール(ecsTaskExecutionRole)には、以下のポリシーを含める必要があります。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "secretsmanager:GetSecretValue"
      ],
      "Resource": "arn:aws:secretsmanager:ap-northeast-1:123456789012:secret:prod/myapp/rds-*"
    }
  ]
}

Resource にはシークレットのARNを指定します。末尾の -* は、Secrets Managerが自動付与するランダムな6文字のサフィックスに対応するワイルドカードです。

まとめ

  • Secrets Managerはデータベース認証情報やAPIキーの管理に特化しており、自動ローテーション機能がネイティブで提供されている
  • Parameter Storeは設定値やパラメータの管理に適しているが、自動ローテーション機能はネイティブでは提供されていない
  • Secrets Managerの自動ローテーションは、Lambda関数がcreateSecret → setSecret → testSecret → finishSecretの4ステップを実行する
  • ECSでシークレットを参照するには、タスク定義の secrets セクションを使用し、タスク実行ロールに secretsmanager:GetSecretValue の権限を付与する
  • タスク実行ロール(ECSエージェントが使用)とタスクロール(アプリケーションが使用)の違いを正しく理解することが重要

参照先

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

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

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

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

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

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

この記事を書いた人

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

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

目次