Amazon ECS タスクに環境変数を渡す際の問題をトラブルシューティングするにはどうすればよいですか?
最終更新日: 2022 年 4 月 14 日
Amazon Elastic Container Service (Amazon ECS) タスクに環境変数を渡す際の問題をトラブルシューティングしたいと考えています。
簡単な説明
Amazon ECS タスク内で環境変数を渡すには、次のいずれかの方法を使用します。
- Amazon Simple Storage Service (Amazon S3) バケット内で environmentFiles オブジェクトとして変数を渡します。
- AWS Systems Manager Parameter Store 内に変数を格納します。
- ECS タスク定義に変数を格納します。
- AWS Secrets Manager 内に変数を格納します。
注: 機密データを環境変数として保存するには、Parameter Store または Secrets Manager を使用するのがセキュリティのベストプラクティスです。
前述のいずれかの方法で環境変数を渡すと、次のエラーが発生する場合があります。
Parameter Store:
Fetching secret data from SSM Parameter Store in region: AccessDeniedException: User: arn:aws:sts::123456789:assumed-role/ecsExecutionRole/f512996041234a63ac354214 is not authorized to perform: ssm:GetParameters on resource: arn:aws:ssm:ap-south-1:12345678:parameter/status code: 400, request id: e46b40ee-0a38-46da-aedd-05f23a41e861 (リージョンの SSM Parameter Store からシークレットデータを取得しています: AccessDeniedException: ユーザー: arn:aws:sts::123456789:assumed-role/ecsExecutionRole/f512996041234a63ac354214 には、リソース: arn:aws:ssm:ap-south-1:12345678:parameter/status code: 400, request id: e46b40ee-0a38-46da-aedd-05f23a41e861 で ssm:GetParameters を実行する権限がありません)
- または -
ResourceInitializationError: unable to pull secrets or registry auth: execution resource retrieval failed: unable to retrieve secrets from ssm: service call has been retried 5 time(s): RequestCanceled (ResourceInitializationError: シークレットまたはレジストリ認証をプルできません: 実行リソースの取得に失敗しました: ssm からシークレットを取得できません: サービスコールが 5 回再試行されました: RequestCanceled)
Secrets Manager:
ResourceInitializationError エラー
- または -
Amazon Elastic Compute Cloud (Amazon EC2) での AccessDenied エラー
これらのエラーを解決するには、「Amazon ECS の AWS Secrets Manager シークレットに関連する問題のトラブルシューティングを行うにはどうすればよいですか?」を参照してください。
Amazon S3:
ResourceInitializationError: failed to download env files: file download command: non empty error stream (ResourceInitializationError: env ファイルのダウンロードに失敗しました: ファイルダウンロードコマンド: 空でないエラーストリーム)
Amazon ECS タスクに環境変数を渡すと、次の理由により問題が発生する可能性があります。
- Amazon ECS タスク実行ロールに必要な AWS Identity and Management (IAM) 許可がない。
- ネットワーク構成に問題がある。
- アプリケーションは環境変数を読み取ることができない。
- コンテナの定義内の変数の形式が正しくない。
- 環境変数が自動的に更新されない。
解決方法
Amazon ECS タスク実行ロールに必要な AWS Identity and Management (IAM) 許可がなお
Parameter Store または Secrets Manager 内で環境変数を使用している場合は、次のいずれかの API コールがないかを AWS CloudTrail イベントで確認します。
Parameter Store の GetParameters
- または -
Secrets Manager の GetSecretValue
CloudTrail イベントでタスク実行ロールの AccessDenied エラーに気付いた場合は、必要な許可をインラインポリシーとして ECS タスク実行 IAM ロールに手動で追加します。また、カスタマーマネージドポリシーを作成して、ECS タスク実行ロールにそのポリシーを追加することもできます。
Secrets Manager を使用している場合は、タスク実行ロールに次の許可を含めます。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"secretsmanager:GetSecretValue",
"kms:Decrypt"
],
"Resource": [
"arn:aws:secretsmanager:example-region:11112222333344445555:secret:example-secret",
"arn:aws:kms:example-region:1111222233334444:key/example-key-id"
]
}
]
}
Parameter Store を使用している場合は、タスク実行ロールに次の許可を含めます。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ssm:GetParameters",
"secretsmanager:GetSecretValue",
"kms:Decrypt"
],
"Resource": [
"arn:aws:ssm:example-region:1111222233334444:parameter/example-parameter",
"arn:aws:secretsmanager:example-region:1111222233334444:secret:example-secret",
"arn:aws:kms:example-region:1111222233334444:key/example-key-id"
]
}
]
}
S3 バケットを使用して環境変数を .env ファイルとして保存するには、次の許可をインラインポリシーとしてタスク実行ロールに手動で追加します。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:GetObject"
],
"Resource": [
"arn:aws:s3:::example-bucket/example-folder/example-env-file"
]
},
{
"Effect": "Allow",
"Action": [
"s3:GetBucketLocation"
],
"Resource": [
"arn:aws:s3:::example-bucket"
]
}
]
}
ネットワーク構成に問題がある
ECS タスクがプライベートサブネットにある場合は、次を確認します。
- タスクまたはサービスのセキュリティグループが、ポート 443 でエグレストラフィックを許可していることを確認します。
- VPC エンドポイントを使用している場合は、ネットワーク ACL がポート 443 でエグレストラフィックを許可していることを確認します。
- telnet コマンドを使用して、Systems Manager / Secrets Manager と Amazon S3 エンドポイントへの接続を確認します。
- NAT ゲートウェイを使用している場合は、タスクに NAT ゲートウェイへのデフォルトルートがあることを確認します。
- タスク用に VPC エンドポイントが定義されていることを確認します。VPC エンドポイントを定義した場合は、Secrets Manager / Systems Manager Parameter Store と S3 に必要な VPC エンドポイントがあることを確認します。
- VPC エンドポイントを使用している場合は、次の点を確認します。
- VPC エンドポイントのセキュリティグループが、ポート 443 でタスクまたはサービスからのエグレストラフィックを許可していること。
- VPC エンドポイントが正しい VPC に関連付けられていること。
- VPC 属性の enableDnsHostnames と enableDnsSupport がオンになっていること。
ECS タスクがパブリックサブネットにある場合は、次を確認します。
- タスクでパブリック IP アドレスが有効になっていることを確認します。
- VPC のセキュリティグループが、ポート 443 でインターネットへのアウトバウンドアクセスを持っていることを確認します。
- すべてのトラフィックがサブネットとインターネット間でフロー (IN/OUT) することをネットワーク ACL の設定が許可していることを確認します。
アプリケーションは環境変数を読み取ることができない
タスクコンテナ内に正しい環境変数が入力されているかどうかを確認するには、次の手順を実行します。
- コンテナ内に公開されているすべての環境変数をリストアップします。
- このリストに、S3 のタスク定義または .env ファイルで定義した環境変数が含まれていることを確認します。
Amazon EC2 または AWS Fargate 起動タイプを使用している場合は、ECS Exec 機能を使用するのがベストプラクティスです。この機能を使用して、Amazon EC2 インスタンスまたは Fargate で実行されているコンテナでコマンドを実行したり、当該コンテナにシェルを取得したりできます。この機能を有効にしたら、次のコマンドを実行してコンテナを操作します。
aws ecs execute-command --cluster example-cluster \
--task example-task-id \
--container example-container \
--interactive \
--command "/bin/sh"
Amazon EC2 起動タイプを使用している場合は、Docker exec コマンドを使用してコンテナを操作することもできます。この場合は、次の操作を実行します。
タスクが実行されているコンテナインスタンスに接続します。その後、次の Docker コマンドを実行して、タスクコンテナのコンテナ ID を見つけます。
docker container ps
次のコマンドを実行してコンテナを操作します。
docker exec -it example-container-id bash
注: コンテナのデフォルトシェルに従ってシェルを選択します。
コンテナとの接続が確立されたら、コンテナで env コマンドを実行して、環境変数の完全なリストを取得します。このリストを確認して、タスク定義または .env ファイルで定義した環境変数が存在することを確認します。
コンテナの定義内の変数の形式が正しくない
コンテナの定義内で環境変数を定義する場合は、次のように KeyValuePair オブジェクトとして環境変数を定義してください。
"environment": [{
"name": "foo",
"value": "bar"
}]
.env ファイルで環境変数を定義するときも、この形式を使用してください。
環境変数が自動的に更新されない
.env ファイル内の環境変数を更新しても、実行中のコンテナでは変数が自動的に更新されません。
更新された環境変数の値をタスクに挿入するには、次のコマンドを実行してサービスを更新します。
aws ecs update-service --cluster example-cluster --service example-service --force-new-deployment
コンテナの定義で環境変数を使用している場合は、新しいタスク定義を作成して、更新された環境変数を更新する必要があります。この新しいタスク定義では、新しいタスクを作成したり、ECS サービスを更新したりできます。
aws ecs update-service --cluster example-cluster --service example-service --task-definition <family:revision>
注:
環境変数をタスクに渡すときは、次の点に注意してください。
- コンテナの定義で environment パラメータを使用して指定された環境変数がある場合、環境ファイルに含まれる変数よりも優先されます。
- 複数の環境ファイルが指定され、同じ変数が含まれている場合は、入力順に処理されます。変数の最初の値が使用され、重複する変数の後続の値は無視されます。一意の変数名を使用するのがベストプラクティスです。
- 環境ファイルをコンテナオーバーライドとして指定すると、そのファイルが使用されます。コンテナの定義で指定されているその他の環境ファイルは無視されます。
- 環境変数は、コンテナ内の PID 1 プロセスで /proc/1/envion ファイルから利用できます。コンテナで複数のプロセスまたは init プロセス (ラッパースクリプト、start スクリプト、supervisord など) を実行している場合、この環境変数を非 PID 1 プロセスで使用することはできません。