はじめに
AWSのコンテナオーケストレーションサービスであるAmazon ECS(Fargate)の実務において、データベースの接続情報やAPIキーなどの機密情報をどのように管理するかは、セキュリティ設計における重要なテーマです。コンテナの環境変数に機密情報を直接ハードコードすることは非推奨とされており、AWS Secrets ManagerやSystems Managerパラメータストアとの連携がベストプラクティスとされています。
本記事では、Amazon ECS Fargateにおいて、AWS Secrets Managerに保存した機密情報を安全にコンテナへ注入するための具体的な設定手順と、実務で発生しやすいトラブルを防ぐ設計方法を解説します。
前提知識と必要な理由
ECSにおける2つのIAMロールの違い
ECSで機密情報を安全に扱うためには、Fargateに割り当てる2つのIAMロールの違いを理解する必要があります。
- タスク実行ロール(Task Execution Role):ECSコンテナエージェントが、コンテナの起動前にAWS APIを呼び出すために使用するロールです。Secrets Managerから値を読み取ったり、Amazon ECRからイメージをプルしたりする際に使用します。
- タスクロール(Task Role):コンテナ内で動作するアプリケーションプログラム自体が、AWSの他のリソース(S3やDynamoDBなど)にアクセスするために使用するロールです。
今回の設定では、Fargate起動時にコンテナエージェントがシークレットを読み込んで環境変数に展開するため、「タスク実行ロール」に適切な権限を付与します。コンテナ内のアプリ自体にはSecrets Managerへのアクセス権限を直接与えないため、万が一アプリが脆弱性を突かれても、シークレットの直接参照を奪取されるリスクを低減できます。
具体的な設定手順・設計方法
本手順を実行する前に、AWS CLI(バージョン2以上)のインストールおよび適切なAWSアカウントへの認証が完了していることを確認してください。AWS CLIの導入手順については、公式ドキュメント(AWS Command Line Interfaceのインストール)を参照してください。
ステップ1:AWS Secrets Managerでのシークレット作成
まずは、コンテナに渡したい機密情報をSecrets Managerに登録します。今回は、データベース接続パスワードを想定したシークレットをAWS CLIで作成します。
aws secretsmanager create-secret \
--name "myapp/production/database" \
--description "Production Database Password" \
--secret-string '{"password":"SuperSecurePassword123"}'
作成が成功すると、出力結果にシークレットのARN(Amazon Resource Name)が表示されます。このARNは後の手順で使用するため控えておいてください。
ステップ2:タスク実行ロールのIAMポリシー作成とアタッチ
ECSコンテナエージェントがシークレットを読み取れるよう、タスク実行ロールに権限を付与します。まず、以下の内容で信頼ポリシーファイル(ecs-tasks-trust-policy.json)を作成します。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "ecs-tasks.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
次に、タスク実行ロールを作成します。
aws iam create-role \
--role-name my-ecs-task-execution-role \
--assume-role-policy-document file://ecs-tasks-trust-policy.json
続いて、Secrets Managerから特定のシークレット値のみを取得することを許可するIAMポリシーファイル(ecs-secrets-policy.json)を作成します。シークレットのARN部分はステップ1で取得したものに書き換えてください。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"secretsmanager:GetSecretValue"
],
"Resource": [
"arn:aws:secretsmanager:ap-northeast-1:123456789012:secret:myapp/production/database-XXXXXX"
]
}
]
}
作成したポリシーをIAMに登録し、タスク実行ロールにアタッチします。また、ECSの基本機能に必要なAWS管理ポリシー(AmazonECSTaskExecutionRolePolicy)も併せてアタッチします。
# カスタムポリシーの作成
aws iam create-policy \
--policy-name MyECSSecretsPolicy \
--policy-document file://ecs-secrets-policy.json
# カスタムポリシーのアタッチ(ARNは環境に合わせて置換してください)
aws iam attach-role-policy \
--role-name my-ecs-task-execution-role \
--policy-arn arn:aws:iam::123456789012:policy/MyECSSecretsPolicy
# 管理ポリシーのアタッチ
aws iam attach-role-policy \
--role-name my-ecs-task-execution-role \
--policy-arn arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy
ステップ3:ECSタスク定義での環境変数マッピング
最後に、ECSのタスク定義において、Secrets Managerの値を環境変数としてインジェクションする設定を行います。タスク定義ファイル(task-definition.json)を以下のように構成します。
{
"family": "myapp-task",
"networkMode": "awsvpc",
"requiresCompatibilities": ["FARGATE"],
"cpu": "256",
"memory": "512",
"executionRoleArn": "arn:aws:iam::123456789012:role/my-ecs-task-execution-role",
"containerDefinitions": [
{
"name": "web-app",
"image": "nginx:latest",
"essential": true,
"portMappings": [
{
"containerPort": 80,
"hostPort": 80
}
],
"secrets": [
{
"name": "DB_PASSWORD",
"valueFrom": "arn:aws:secretsmanager:ap-northeast-1:123456789012:secret:myapp/production/database-XXXXXX:password::"
}
]
}
]
}
secretsセクションのvalueFromに、Secrets ManagerのARNを指定します。末尾に「:password::」を付与することで、シークレット内の特定のキー(ここではpassword)のみを抽出し、コンテナ内の環境変数「DB_PASSWORD」として渡すことができます。
このタスク定義を登録してタスクを実行すれば、安全にシークレットがコンテナに渡されます。
実務での注意点
- KMSカスタムキー(CMK)使用時の権限:Secrets Managerの暗号化にデフォルトのAWS管理鍵(
aws/secretsmanager)ではなく、カスタマー管理のKMSキー(CMK)を使用している場合、タスク実行ロールにkms:Decrypt権限を追加する必要があります。この権限が不足していると、ECS起動時に「ResourceInitializationError」が発生して起動に失敗します。 - ネットワークの疎通確認:ECS Fargateをプライベートサブネットにデプロイし、NATゲートウェイを設置していない構成(VPCエンドポイントのみの環境)の場合、Secrets Manager用のVPCエンドポイント(
com.amazonaws.ap-northeast-1.secretsmanager)が正しく構成されているか確認してください。疎通ができない場合、コンテナエージェントがシークレットを取得できずにタスクが「PENDING」のまま停止します。 - タスク定義でのシークレット更新の反映:Secrets Manager側の値を更新しても、すでに起動しているコンテナ内の環境変数は自動更新されません。新しい値を反映させるには、ECSサービスを「サービスの強制デプロイ」によって再起動(タスクの入れ替え)する必要があります。
まとめ
ECS FargateにおけるAWS Secrets Managerとの連携は、アプリケーションコードを修正することなく機密情報を安全に注入できる極めて強力な手法です。「タスク実行ロール」に必要な最小権限を定義し、KMSキーやネットワーク(VPCエンドポイント)の設定に注意を払うことで、セキュリティと運用の利便性を両立した強固なインフラを構築できます。