Amazon ECS タスクで秘密情報や機密情報をコンテナに安全に渡す方法を教えてください。
最終更新日: 2021 年 1 月 6 日
Amazon Elastic Container Service (Amazon ECS) のタスクで秘密情報や機密情報をコンテナに安全に渡したいと考えています。
簡単な説明
機密性のあるデータをプレーンテキストで渡してしまうと、AWS マネジメントコンソール内や、DescribeTaskDefinition もしくは DescribeTasks などの AWS API を介して参照可能となるため、セキュリティ上の問題が発生する可能性があります。
機密情報は、環境変数としてコンテナに渡すことが、セキュリティ上のベストプラクティスです。Amazon ECS タスク定義内のコンテナ定義にある、AWS Systems Manager Parameter Store または AWS Secrets Manager に格納されている値を参照することで、コンテナにデータを安全に挿入できます。その後、機密情報を環境変数として、またはコンテナのログ設定の中で公開することができます。
AWS は次の場合にのみデータ挿入をサポートします。
- AWS Fargate 起動タイプで AWS Fargate プラットフォームのバージョン 1.3.0 以降を使用するタスク
- Amazon Elastic Compute Cloud (Amazon EC2) 起動タイプで amazon-ecs-agent バージョン 1.22.0 以降を使用するコンテナインスタンス
解決方法
前提条件を満たす
1. 機密情報を AWS Systems Manager Parameter Store または Secrets Manager に保存します。
AWS Systems Manager Parameter Store の場合は、次のコマンドを実行します。
aws ssm put-parameter --type SecureString --name awsExampleParameter --value awsExampleValue
Secrets Manager の場合は、次のコマンドを実行します。
aws secretsmanager create-secret --name awsExampleParameter --secret-string awsExampleValue
注意: Amazon ECS コンテナエージェントはタスク実行 AWS Identity and Access Management (IAM) ロールを使用して、AWS Systems Manager Parameter Store または Secrets Manager から情報を取得します。タスク実行 IAM ロールは、ssm:GetParameters、secretsmanager:GetSecretValue、および kms:Decrypt アクションにアクセス許可を付与する必要があります。
2. IAM コンソールを開き、ecs-tasks.amazonaws.com に対して信頼関係のロールを作成します。以下に例を示します。
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"Service": "ecs-tasks.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
3. IAM コンソールでロールのインラインポリシーを作成するには、[ロール] を選択し、手順 2 で作成したロールを選択してから、[権限] タブで [インラインポリシーの追加] を選択します。[JSON] タブを選択してから、以下のコードでポリシーを作成します。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ssm:GetParameters",
"secretsmanager:GetSecretValue"
],
"Resource": [
"arn:aws:ssm:us-east-1:awsExampleAccountID:parameter/awsExampleParameter",
"arn:aws:secretsmanager:us-east-1:awsExampleAccountID:secret:awsExampleParameter*"
]
}
]
}
注: us-east-1 および awsExampleAccountID を、パラメータが保存されている AWS リージョンとアカウントに置き換えます。awsExampleParameter を手順 1 で作成したパラメータの名前に置き換えます。
注: AWS Systems Manager Parameter Store または Secrets Manager でデータの暗号化に顧客管理の KMS キーを使用する場合は、kms:Decrypt のアクセス許可を取得する必要があります。
4. (オプション) 管理ポリシー AmazonECSTaskExecutionRolePolicy を手順 2 で作成したロールにアタッチします。
重要: Amazon Elastic Container Registry (Amazon ECR) に保存されているイメージを使用するか、Amazon CloudWatch にログを送信するタスクには、管理ポリシーが必要です。
ECS タスク定義内の機密情報の参照
AWS マネジメントコンソールから:
1. Amazon ECS コンソールを開きます。
2. ナビゲーションペインで [タスク定義] を選択し、次に [新規タスク定義の作成] を選択します。
3. 起動タイプを選択してから、[次のステップ] をクリックします。
4. [タスク実行ロール] には、先に作成したタスク実行 IAM ロールを選択します。
5. [コンテナ定義] セクションで、[コンテナの追加] を選択します。
6. [環境] の下の環境変数セクションで、[キー] に、環境変数のキーを入力します。
7. [値] ドロップダウンリストで、[ ValueFrom ] を選択します。
8. キーのテキストボックスに、パラメータストアまたは Secrets Manager リソースの Amazon リソースネーム (ARN) を入力します。
注意: ログドライバー設定で秘密を指定することもできます。
AWS Command Line Interface (AWS CLI) から:
注意: AWS CLI コマンドの実行時にエラーが発生した場合は、AWS CLI の最新バージョンを使用していることを確認してください。
1. タスク定義内の AWS Systems Manager Parameter Store または Secrets Manager リソースを秘密セクションを使用して環境変数として、または secretOptions セクションを使用してログ設定オプションとして参照します。以下に例を示します。
{
"requiresCompatibilities": [
"EC2"
],
"networkMode": "awsvpc",
"containerDefinitions": [
{
"name": "web",
"image": "httpd",
"memory": 128,
"essential": true,
"portMappings": [
{
"containerPort": 80,
"protocol": "tcp"
}
],
"logConfiguration": {
"logDriver": "splunk",
"options": {
"splunk-url": "https://sample.splunk.com:8080"
},
"secretOptions": [
{
"name": "splunk-token",
"valueFrom": "arn:aws:secretsmanager:us-east-1:awsExampleAccountID:secret:awsExampleParameter"
}
]
},
"secrets": [
{
"name": "DATABASE_PASSWORD",
"valueFrom": "arn:aws:ssm:us-east-1:awsExampleAccountID:parameter/awsExampleParameter"
}
]
}
],
"executionRoleArn": "arn:aws:iam::awsExampleAccountID:role/awsExampleRoleName"
}
重要: us-east-1 と awsExampleAccountID は、お客様の AWS リージョンとアカウント ID に置き換えてください。awsExampleParameter を、先に作成済みのパラメータに置き換えます。awsExampleRoleName を、先に作成済みのロールに置き換えます。
2. タスク定義を登録するには、次のコマンドを実行します。
aws ecs register-task-definition --family-name yourTaskDefinitionFamily --cli-input-json file://pathToYourJsonFile
作成したタスク定義を使用してタスクが起動すると、Amazon ECS コンテナエージェントが自動的に秘密を解決し、その値を環境変数としてコンテナに挿入します。
重要: 重要なデータは、コンテナを最初に起動したときにコンテナに挿入されます。秘密または Parameter Store パラメータが更新または回転されても、コンテナは更新された値を自動的には受け取りません。新しいタスクを開始しなければなりません。タスクがサービスの一部である場合は、サービスを更新し、新規デプロイの強制オプションを使用して、サービスに新しいタスクを強制的に開始させます。
新しいデプロイを強制するには:
1. Amazon ECS コンソールを開きます。
2. [Clusters] (クラスター) をクリックし、サービスのクラスターを選択します。
3. [Force New Deployment] (新規デプロイの強制) チェックボックスを選択してから、[Update Service] (サービスの更新) をクリックします。
注意: AWS CLI から新しいデプロイを強制するには、--force-new-deployment フラグを指定して update-service コマンドを実行します。