はじめに
AWSのコンテナサービスであるAmazon ECS(Fargate)を運用する際、データベースのパスワードやAPIキーなどの「機密情報」をどのようにコンテナへ渡すかは、セキュリティ設計における極めて重要なテーマです。
本記事では、AWSのシークレット管理サービスである「AWS Secrets Manager」とECSを連携させ、安全にコンテナの環境変数へ機密情報を注入する具体的な設定手順をステップバイステップで解説します。
前提知識/必要な理由
コンテナに機密情報を渡す際、タスク定義の環境変数(environment)にプレーンテキストで直接記述することは推奨されません。タスク定義を閲覧できるすべてのユーザーに機密情報が露出してしまうためです。
AWS Secrets Managerを利用してECSと連携させることで、以下のようなメリットが得られます。
- 強力なセキュリティ:機密情報はAWS KMS(Key Management Service)によって暗号化されて保管されます。
- アクセス制御の容易さ:IAMポリシーを使用して、特定のコンテナタスクのみに値の取得権限を制限できます。
- 監査と追跡:CloudTrailと連携することで、「誰がいつシークレットにアクセスしたか」をログとして記録できます。
具体的な設定手順・設計方法
ECSからAWS Secrets Managerの値を安全に取得するための設定手順を説明します。事前に、お手元の端末にAWS CLIがインストールおよびセットアップされていることを前提とします(未インストールの場合は、公式ドキュメントを参照して、OSに応じたインストーラーからAWS CLIを導入してください)。
ステップ1:Secrets Managerでシークレットを作成する
まずは、コンテナに渡したい機密情報をSecrets Managerに登録します。ここでは、AWS CLIを使用してシークレットを作成する例を紹介します。
aws secretsmanager create-secret \
--name my-app/db-password \
--description "Database password for ECS application" \
--secret-string '{"password":"SuperSecurePassword123"}' \
--region ap-northeast-1
※作成が成功すると、シークレットのARN(Amazon Resource Name)が返却されます。このARNは後の設定で使用するため、メモしておいてください。
ステップ2:ECSタスク実行ロールにIAM権限を付与する
ECSがSecrets Managerから値を読み取るには、ECSタスクを起動するエージェントに対して権限を付与する必要があります。これには「タスクロール」ではなく、「タスク実行ロール(Task Execution Role)」を使用します。
タスク実行ロールに紐づくIAMポリシーに、以下のステートメントを追加してください。
{
"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タスク定義を設定する
タスク定義のJSONファイル内で、環境変数を注入する設定を行います。secretsパラメータを使用し、環境変数名と取得元のSecrets ManagerのARNを指定します。
{
"containerDefinitions": [
{
"name": "web-app",
"image": "nginx:latest",
"essential": true,
"secrets": [
{
"name": "DB_PASSWORD",
"valueFrom": "arn:aws:secretsmanager:ap-northeast-1:123456789012:secret:my-app/db-password-XXXXXX:password::"
}
]
}
],
"executionRoleArn": "arn:aws:iam::123456789012:role/ecsTaskExecutionRole"
}
上記のように設定することで、シークレットのJSON内にあるキーpasswordの値のみを、コンテナ内の環境変数DB_PASSWORDとして安全に展開できます。
実務での注意点
- タスクロールとタスク実行ロールの間違い:もっとも多いエラーの1つです。コンテナ「内部のアプリケーション」がAWSリソースにアクセスする場合は「タスクロール(Task Role)」を使いますが、ECSエージェントがコンテナ「起動時」にSecrets Managerから値を引き出して環境変数にセットする場合は「タスク実行ロール(Task Execution Role)」に権限が必要です。
- VPCエンドポイントの設定:ECSタスクをプライベートサブネットでFargateとして実行し、インターネットへのルート(NAT Gatewayなど)がない場合、Secrets Managerへの名前解決や通信が失敗します。この場合は、VPC内にSecrets Manager用の「インターフェース型VPCエンドポイント(AWS PrivateLink)」を必ず配置してください。
まとめ
AWS Secrets ManagerとAmazon ECSを連携させることで、コンテナイメージやタスク定義に機密情報を一切残さずに、安全なアプリケーション実行環境を構築できます。
インフラのセキュリティ向上は、実務において最も評価されるポイントの1つです。本記事の手順を参考に、セキュアなコンテナ設計をぜひ実践してみてください。