Fargateで機密情報を安全に渡すSecrets Manager連携

はじめに

AWSのコンテナ実行環境であるECS Fargateにおいて、データベースの接続パスワードやAPIキーなどの機密情報をどのように管理・展開するかは、セキュリティ設計における重要なテーマです。本記事では、AWS Secrets ManagerとECS Fargateを連携させ、タスク定義に直接パスワードを書き込むことなく、安全に環境変数としてコンテナへ注入する設定手順を分かりやすく解説します。

前提知識/必要な理由

なぜSecrets Manager連携が必要なのか?

ECSのタスク定義にプレーンテキストでパスワードなどの機密情報を記述してしまうと、IAM権限を持つ開発者全員に機密情報が露出するリスクが生じます。また、Gitなどのバージョン管理システムに誤ってコミットしてしまう危険性もあります。

AWS Secrets Managerを使用することで、以下のメリットが得られます。

  • 機密情報の中央管理と暗号化(AWS KMSによる保護)
  • タスク起動時のみ、コンテナの環境変数に機密情報を安全に注入
  • 最小特権の原則に基づいたIAM制御

具体的な設定手順・設計方法

FargateタスクからSecrets Managerの値を参照するための具体的な設定手順を3つのステップで解説します。

ステップ1:Secrets Managerでのシークレット作成

まずはAWS CLIからシークレットを作成します。事前にAWS CLIがインストールされ、適切な管理者権限が設定されていることをご確認ください。AWS CLIが未インストールの場合は、公式のAWS CLIインストーラーを使用してセットアップを完了させておきます。

aws secretsmanager create-secret \
    --name "my-app/db-password" \
    --description "Database password for ECS application" \
    --secret-string "SuperSecurePassword123!"

作成が完了すると、シークレットのARN(Amazon Resource Name)が発行されます。後の手順で使用するため控えておきます。

ステップ2:タスク実行ロール(Task Execution Role)のIAMポリシー設定

ECS Fargateがタスク起動時にSecrets Managerから値を読み取るには、タスク実行ロール(Task Execution Role)に適切な権限を付与する必要があります。※「タスクロール」ではない点に注意してください。

以下のIAMポリシーを、タスク実行ロール(通常は ecsTaskExecutionRole)のアタッチされたポリシーに追加、またはインラインポリシーとして定義します。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "secretsmanager:GetSecretValue"
            ],
            "Resource": [
                "arn:aws:secretsmanager:ap-northeast-1:123456789012:secret:my-app/db-password-XXXXXX"
            ]
        }
    ]
}

Resource にはステップ1で作成したシークレットのフルARNを指定してください。

ステップ3:ECSタスク定義での環境変数参照設定

タスク定義のコンテナ定義セクションにおいて、環境変数の取得元としてSecrets Managerを指定します。以下はJSON形式でのタスク定義(コンテナ定義部分)の設定例です。

{
    "containerDefinitions": [
        {
            "name": "my-app-container",
            "image": "123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/my-app:latest",
            "essential": true,
            "secrets": [
                {
                    "name": "DB_PASSWORD",
                    "valueFrom": "arn:aws:secretsmanager:ap-northeast-1:123456789012:secret:my-app/db-password-XXXXXX"
                }
            ],
            "portMappings": [
                {
                    "containerPort": 80,
                    "hostPort": 80
                }
            ]
        }
    ],
    "executionRoleArn": "arn:aws:iam::123456789012:role/ecsTaskExecutionRole",
    "family": "my-app-task"
}

secrets 配列の中で、コンテナ内で利用したい環境変数名(name)と、Secrets ManagerのARN(valueFrom)をマッピングします。これにより、コンテナ起動時に自動的に DB_PASSWORD という環境変数に値が注入されます。

実務での注意点

1. タスクロールとタスク実行ロールの混同に注意

ECSには2種類のIAMロールが存在します。Secrets Managerからの値の取得(コンテナ起動フェーズ)に必要なのはタスク実行ロール(Execution Role)です。アプリケーション実行中にAWS SDK等から別のAWSリソース(S3やDynamoDBなど)にアクセスするために必要なのはタスクロール(Task Role)です。設定するロールを間違えないようにしましょう。

2. カスタムKMSキーを使用する場合の追加権限

Secrets Managerの暗号化にデフォルトのキー(aws/secretsmanager)ではなく、カスタマー管理型のKMSキーを使用している場合、タスク実行ロールに kms:Decrypt 権限を追加で付与する必要があります。権限が不足していると、タスク起動時に ResourceInitializationError でコンテナの起動が失敗します。

3. シークレット更新時のコンテナ再起動

Secrets Manager側で値を更新しても、すでに起動しているFargateコンテナの環境変数は自動的には更新されません。新しい値を反映させるには、ECSサービスの「新しいデプロイの強制」を実行し、タスクを再起動(再作成)する必要があります。

まとめ

ECS FargateとSecrets Managerを連携させることで、安全かつ容易に機密情報をコンテナ環境変数へ展開できます。設定のポイントは「タスク実行ロールに必要な権限を付与すること」と「タスク定義のsecretsセクションで参照を指定すること」の2点です。セキュリティベストプラクティスに則った堅牢なインフラ構築にぜひ役立ててください。

上部へスクロール