Amazon ECS タスクにおいて、シークレットや機密情報をコンテナに安全に渡す方法を教えてください。
Amazon Elastic Container Service (Amazon ECS) のタスクにおいて、シークレットや機密情報をコンテナに安全に渡したいと思っています。
簡単な説明
機密データをプレーンテキストで渡した場合、セキュリティ上の問題が発生する可能性があります。そのようなデータは、AWS マネジメントコンソール または DescribeTaskDefinition AWS API 経由で検出される可能性があります。
セキュリティの観点から、機密情報を環境変数としてコンテナに渡すことが推奨されます。コンテナにデータを安全に注入するには、AWS Systems Manager の機能である Parameter Store に格納した値を参照します。Amazon ECS タスク定義で AWS Secrets Manager を使用してもかまいません。この方法では、機密情報を環境変数として公開したり、コンテナのログ設定で公開したりできます。
解決策
**注:**AWS コマンドラインインターフェイス (AWS CLI) コマンドの実行中にエラーが発生した場合は、「AWS CLI エラーのトラブルシューティング」を参照してください。また、AWS CLI の最新バージョンを使用しているようにしてください。
前提条件:
- タスクでは、AWS Fargate プラットフォーム 1.3.0 以降の AWS Fargate 起動タイプを使用する必要があります。
- コンテナインスタンスでは、Amazon Elastic Compute Cloud (Amazon EC2) 起動タイプに amazon-ecs-agent バージョン 1.22.0 以降を使用する必要があります。詳細については、GitHub のウェブサイトで「変更履歴」を参照してください。
- JSON キーを挿入するには、Fargate プラットフォームバージョン 1.4.0 以降 (Linux)、バージョン 1.0.0 (Windows) が必要です。
- 特定バージョンの JSON キーまたはシークレットを使用する場合、コンテナインスタンスの ECS コンテナエージェントでは、シークレットの挿入にはバージョン 1.37.0 以降を実行する必要があります。
- シークレットの全コンテンツをログ設定または環境変数に挿入するには、コンテナインスタンスの ECS コンテナエージェントでは、バージョン 1.22.0 以降を実行する必要があります。
IAM ロールとポリシーを作成する
次の手順を実行します。
-
機密情報を Parameter Store または Secrets Manager に格納します。
Parameter Store では、次の AWS CLI コマンド put-parameter を実行します。
aws ssm put-parameter --type SecureString --name awsExampleParameter --value awsExampleValue注: awsExampleParameter を使用するパラメータに置き換えてください。awsExampleValue を実際のシークレット値に置き換えてください。
Secrets Manager では、次の AWS CLI コマンド create-secret を実行します。
aws secretsmanager create-secret --name awsExampleParameter --secret-string awsExampleValue注: awsExampleParameter を使用するパラメータに置き換えてください。awsExampleValue を実際のシークレット値に置き換えてください。ECS コンテナエージェントは、タスク実行ロールを使用して Parameter Store または Secrets Manager から情報を取得します。タスク実行ロールでは、次のアクションへのアクセス許可を付与する必要があります: ssm:GetParameters、secretsmanager:GetSecretValue、kms:Decrypt
-
ecs-tasks.amazonaws.com に対する信頼関係を含むロールを作成します。
ロールの信頼ポリシー例:{ "Version": "2012-10-17", "Statement": [ { "Sid": "", "Effect": "Allow", "Principal": { "Service": "ecs-tasks.amazonaws.com" }, "Action": "sts:AssumeRole" } ] } -
[ロール] を選択し、作成したロールを選択します。
-
[アクセス許可] タブで [アクセス許可の追加] ドロップダウンリストを選択します。
-
[インラインポリシーの作成] を選択し、[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 を作成したパラメータ名に置き換えてください。Parameter Store または Secrets Manager 内のデータを暗号化するには、AWS Key Management Service (AWS KMS) カスタマーマネージドキーを使用できます。カスタマーマネージドキーを使用するには、kms:Decrypt へのアクセス許可を取得します。
-
(オプション) マネージドポリシー AmazonECSTaskExecutionRolePolicy を作成したロールにアタッチします。
重要: タスクが Amazon CloudWatch にログを送信したり、Amazon Elastic Container レジストリ (Amazon ECR) に格納されたイメージを使用したりする場合、マネージドポリシーが必要です。
ECS タスク定義内の機密情報を参照する
ECS タスク定義の機密情報を参照するには、Amazon ECS コンソールまたは AWS CLI を使用します。
Amazon ECS コンソールを使用する
次の手順を実行します。
- Amazon ECS コンソールを開きます。
- ナビゲーションペインで [タスク定義] を選択し、[新しいタスク定義の作成] を選択します。
[タスク定義ファミリー] に名前を入力します。
[起動タイプ] で [AWS Fargate] または [Amazon EC2 インスタンス] を起動タイプとして選択します。 - [タスク実行ロール] に作成したタスク実行 IAM ロールを選択します。
- [コンテナ定義] セクションの [環境変数] セクションで [環境変数を追加] を選択します。
- [キー] に環境変数のキーを入力します。
- [ValueType] ドロップダウンリストで [ValueFrom] を選択します。
- キーのテキストボックスには、Parameter Store または Secrets Manager リソースの Amazon リソースネーム (ARN) を入力します。
注: ログドライバー構成でシークレットを指定することもできます。
AWS CLI を使用する
secrets セクションを指定し、タスク定義内の Parameter Store または Secrets Manager リソースを環境変数として参照します。または、secretOptions セクションを指定し、Parameter Store または Secrets Manager をログ構成オプションとして参照することもできます。
タスク定義の例:
{ "requiresCompatibilities": [ "EC2" ], "family": "Web", "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 をそれぞれ、実際のリージョンとアカウント ID に置き換えてください。awsExampleParameter を作成したパラメータに置き換えてください。awsExampleRoleName を作成したロールに置き換えてください。
次に、以下の AWS CLI コマンド register-task-definition を実行してタスク定義を登録します。
aws ecs register-task-definition --family-name yourTaskDefinitionFamily --cli-input-json file://pathToYourJsonFile
注: yourTaskDefinitionFamily をタスク定義ファミリー名に置き換えてください。
この定義を使用してタスクを起動すると、ECS コンテナエージェントは自動的にシークレットを解決します。次に、コンテナエージェントは、その値を環境変数としてコンテナに挿入します。
シークレットを更新し、変更をデプロイする
ECS コンテナの起動時に、コンテナは機密データをコンテナに挿入します。シークレットまたは Parameter Store パラメータを更新またはローテーションした場合、コンテナは更新された値を自動的には取得しないため、新しいタスクを起動する必要があります。タスクがサービスに属している場合は、そのサービスを更新します。サービスで新規タスクの起動を強制するには、[新しいデプロイの強制] オプションを指定します。
新規デプロイを強制するには、次の手順を実行します。
- Amazon ECS コンソールを開きます。
- [クラスター] を選択し、サービスを含むクラスターを選択します。
- [更新] ドロップダウンリストで [新しいデプロイの強制] を選択します。
注: AWS CLI で新しいデプロイを強制するには、--force-new-deployment フラグを指定して update-service コマンドを実行します。
関連情報
- トピック
- Containers
- 言語
- 日本語

関連するコンテンツ
- 質問済み 1年前
