Amazon ECS@AWSリソース¶
はじめに¶
本サイトにつきまして、以下をご認識のほど宜しくお願いいたします。
01. Amazon ECS:Elastic Container Service¶
コントロールプレーン¶
▼ コントロールプレーンとは¶
コンテナオーケストレーションを実行する環境を提供する。
データプレーンのVPC外に存在している。
▼ コントロールプレーンの仕組み¶
Amazon ECSのコントロールプレーンは、開発者や他のAWSリソースからのリクエストを待ち受けるAPI、データプレーンを管理するコンポーネント、からなる。

データプレーン¶
単一のホスト (Amazon EC2、AWS Fargate) のOS上でコンテナオーケストレーションを実行する。
『on EC2』『on Fargate』という呼び方は、データプレーンがAmazon ECSの実行環境 (on environment) の意味合いを持つからである。
Amazon EKSとの機能比較¶
| Amazon ECSの機能 | EKSで相当する機能 |
|---|---|
| Amazon ECSサービス + Amazon ECSタスク | Deployment |
| Daemon型のAmazon ECSサービス | DaemonSet |
| Replica型のAmazon ECSサービス | ReplicaSet |
| なし | StatefulSet |
| Amazon ECSタスク | Pod |
| ELB | Ingress + Service |
| Amazon ECSタスクの環境変数 | ConfigMap |
| AWS Secrets Manager | Secret |
| Taskスケーリング | HorizontalPodAutoscaler、VerticalPodAutoscaler |
| キャパシティプロバイダー + AWS AutoScaling | CusterAutoscaler、Karpenter |
| Minimum/Maximum Healthy Percent | PodDisruptionBudget |
| Amazon VPC Lattice、Amazon ECS Service Connect | Istio |
02. コントロールプレーンのコンポーネント¶
記入中...
03. データプレーンのコンポーネント¶
Amazon ECSクラスター¶
Amazon ECSサービスの管理グループ単位のこと。

Amazon ECSサービス¶
Amazon ECSタスクの管理グループ単位のこと。
Amazon ECSタスクへのロードバランシング、タスクの数の維持管理や、リリースの成否を管理する。
マイクロサービスは、Amazon ECSサービスを単位として作成する。
Amazon ECSタスク¶
▼ Amazon ECSタスク¶
コンテナインスタンスの管理グループ単位のこと。
Amazon ECSタスク定義を基に作成される。

▼ Amazon ECSコンテナエージェント¶
Amazon ECSタスク実行ロールを使用して、Amazon ECSタスクのライフサイクルを管理する。
Fargateの場合、Amazon ECSコンテナエージェントがプリインストールされている。

▼ Amazon ECSタスク定義¶
Amazon ECSタスクをどのような設定値を基に作成するかを設定できる。
Amazon ECSタスク定義は、バージョンを示す『リビジョンナンバー』で番号づけされる。
Amazon ECSタスク定義を削除するには、全てのリビジョンのAmazon ECSタスク定義を登録解除する必要がある。
▼ Amazon ECSタスクのライフサイクルフェーズ¶

Amazon ECSタスクのライフサイクルにはフェーズがある。
Amazon ECSタスクは、必須コンテナ異常停止時、デプロイ、オートスケーリング、手動操作、の時にフェーズを持つ。
| フェーズ名 | 説明 | 補足 |
|---|---|---|
| Provisioning | Amazon ECSタスクの起動前に必要な準備 (例:ENIの紐付け) があり、これが完了していない。 | |
| Pending | Amazon ECSタスク内のコンテナの起動がまだ完了していない。 | |
| Activating | Amazon ECSタスク内の全てのコンテナの起動が完了したが、Amazon ECSタスク全体のセットアップは完了していない。 | |
| Running | Amazon ECSタスク内の全てのコンテナの起動とAmazon ECSタスク全体の準備が完了し、実行中である。 | コンテナの起動が完了すれば Running フェーズになるが、コンテナ内でビルトインサーバーを起動するようなアプリケーション (例:フレームワークのビルトインサーバー機能) の場合は、Running フェーズであっても使用できないことに注意する。 |
| De-activating | Amazon ECSタスク内のコンテナを停止する前に必要な処理があり、これが完了していない。 | |
| Stopping | Amazon ECSタスク内のコンテナが正常/異常に停止しようとしている途中である。 | |
| De-provisioning | Amazon ECSタスク全体を停止する前に必要な準備 (例:ENIの解除) があり、これが完了していない。 | |
| Stopped | Amazon ECSタスク全体が停止した。 | 正常停止と異常停止に関わらず、停止理由を確認できる。 https://docs.aws.amazon.com/AmazonECS/latest/developerguide/stopped-task-errors.html |
03-02. ネットワーク¶
Amazon ECSタスク内のコンテナ間通信¶
▼ noneモード¶
外部ネットワークが無く、タスクと外と通信できない。
▼ hostモード¶
EC2のみで使用できる。
Dockerのhostネットワークに相当する。

▼ bridgeモード¶
EC2のみで使用できる。
Dockerのbridgeネットワークに相当する。

▼ awsvpcモード¶
FargateとEC2の両方で使用できるawsの独自ネットワークモード。
タスクはElastic Networkインターフェースと紐付けられ、コンテナではなくタスク単位でプライベートIPアドレスが割り当てられる。
Fargateの場合、同じタスクに属するコンテナ間は、localhostインターフェイスというENI経由で通信できるようになる (推測ではあるが、FargateとしてのEC2にlocalhostインターフェースが紐付けられる) 。
これにより、コンテナ間でパケットを送受信するとき (例:NginxコンテナからPHP-FPMコンテナへのルーティング) は、通信元コンテナにて、通信先のアドレスを『localhost (127.0.0.1) 』で指定すれば良い。
また、awsvpcモードの独自の仕組みとして、同じAmazon ECSタスク内であれば、互いにコンテナポートを開放せずともパケットを送受信できる。通信を待ち受けるポートを指定するだけでよい。
例えば、NginxコンテナからPHP-FPMコンテナにリクエストをルーティングするためには、PHP-FPMプロセスが 9000 番ポートでリクエストを受信し、加えてコンテナが 9000 番ポートを開放する必要がある。
しかし、awsvpcモードではコンテナポートを開放する必要はない。

Amazon ECSサービス間の通信¶
Amazon ECS Service Connectを使用する。
Amazon ECSタスクからのアウトバウンド¶
▼ プライベートサブネット内のデータプレーンの配置¶
プライベートサブネット内にデータプレーンを配置した場合、パブリックネットワークやVCP外のAWSリソースにリクエストを送信するために、AWS NAT GatewayやVPCエンドポイントが必要になる。
パブリックサブネットに配置すればこれらは不要となるが、パブリックサブネットよりもプライベートサブネットにデータプレーンを配置するほうが望ましい。
▼ パブリックネットワークに対する通信¶
データプレーンをプライベートサブネットに配置した場合、パブリックネットワークに対してリクエストを送信するためには、AWS NAT Gatewayを配置する必要がある。
▼ Amazon VPC外のAWSリソースに対する通信¶
データプレーンをプライベートサブネットに配置した場合、VPC外にあるAWSリソース (例:コントロールプレーン、Amazon ECR、Amazon S3、AWS Systems Manager、Amazon CloudWatch Logs、DynamoDBなど) に対してリクエストを送信するためには、AWS NAT GatewayあるいはVPCエンドポイントを配置する必要がある。
もしAWS NAT Gatewayを配置したとする。
この場合、VPCエンドポイントよりもAWS NAT Gatewayのほうが高く、AWSリソースに対する通信でもAWS NAT Gatewayを通過するため、高額料金を請求されてしまう。

代わりに、VPCエンドポイントを配置する。
より低額でデータプレーンがVPC外のAWSリソースのリクエストできるようになる。

03-03. セキュリティ¶
ロール¶
▼ サービスロール¶
Amazon ECSサービスがAmazon ECSタスクを操作するために必要なロールである。
サービスリンクロールに含まれ、Amazon ECSの作成時に自動的に紐付けられる。
▼ コンテナインスタンスロール¶
コンテナのホストが他のAWSリソースにリクエストを送信するために必要なロールである。
Fargateの場合、不要である。

▼ タスクロール¶
Amazon ECSタスク内のコンテナのアプリケーションが、他のAWSリソースにリクエストを送信するために必要なロールである。
アプリケーションにAmazon S3やAWS Systems Managerへの認可スコープを与えたい場合は、タスク実行ロールではなくタスクロールに認可スコープを紐付ける。

*実装例*
アプリケーションからAmazon CloudWatch Logsにログを送信するために、Amazon ECSタスクロールにカスタマー管理ポリシーを紐付ける。
{
"Version": "2012-10-17",
"Statement":
[
{
"Effect": "Allow",
"Action": ["logs:CreateLogStream", "logs:PutLogEvents"],
"Resource": ["arn:aws:logs:*:*:*"],
},
],
}
*実装例*
パラメーターストアから変数を取得するために、Amazon ECSタスクロールにインラインポリシーを紐付ける。
{
"Version": "2012-10-17",
"Statement":
[{"Effect": "Allow", "Action": ["ssm:GetParameters"], "Resource": "*"}],
}
▼ タスク実行ロール¶

Amazon ECSタスク内のAmazon ECSコンテナエージェントが、他のAWSリソースにリクエストを送信するために必要なロールのこと。
AWS管理ポリシーである『AmazonECSTaskExecutionRolePolicy』が紐付けられたロールを、タスクに紐付ける必要がある。
このポリシーには、Amazon ECRへの認可スコープの他、Amazon CloudWatch Logsにログを作成するための認可スコープが設定されている。
Amazon ECSタスク内のコンテナがリソースにリクエストを送信するために必要なタスクロールとは区別すること。
{
"Version": "2012-10-17",
"Statement":
[
{
"Effect": "Allow",
"Action":
[
"ecr:GetAuthorizationToken",
"ecr:BatchCheckLayerAvailability",
"ecr:GetDownloadUrlForLayer",
"ecr:BatchGetImage",
"logs:CreateLogStream",
"logs:PutLogEvents",
],
"Resource": "*",
},
],
}
*実装例*
datadogエージェントがAmazon ECSクラスターやコンテナにリクエストを送信できるように、Amazon ECSタスク実行ロールにカスタマー管理ポリシーを紐付ける。
{
"Version": "2012-10-17",
"Statement":
[
{
"Action":
[
"ecs:ListClusters",
"ecs:ListContainerInstances",
"ecs:DescribeContainerInstances",
],
"Effect": "Allow",
"Resource": "*",
},
],
}
03-04. 監視¶
ログ¶
▼ awslogsドライバー¶
標準出力/標準エラー出力に出力されたログをCloudWatch-APIに送信する。
| 設定項目 | 説明 | 補足 |
|---|---|---|
awslogs-group |
ログ宛先のAmazon CloudWatch Logsのロググループを設定する。 | |
awslogs-datetime-format |
日時フォーマットを定義し、加えてこれをログの区切り単位としてログストリームに出力する。 | 正規表現で設定する必要があり、加えてJSONでは『\』を『\\』にエスケープしなければならない。例えば『\\[%Y-%m-%d %H:%M:%S\\]』となる。https://docs.docker.com/config/containers/logging/awslogs/#awslogs-datetime-format |
awslogs-region |
ログ宛先のAmazon CloudWatch Logsのリージョンを設定する。 | |
awslogs-stream-prefix |
ログ宛先のAmazon CloudWatch Logsのログストリームのプレフィックス名を設定する。 | ログストリームには、『<プレフィックス名>/<コンテナ名>/<タスクID>』の形式で送信される。 |
04. on Amazon EC2¶
on Amazon EC2とは¶
EC2をホストとして、コンテナを作成する。
Amazon EC2の最適化AMI¶
任意のEC2を使用できるが、AWSが用意している最適化AMIを選んだほうが良い。
このAMIには、EC2がAmazon ECSと連携するために必要なソフトウェアがプリインストールされており、EC2をセットアップする手間が省ける。
| AMI名 | 説明 | 特に相性の良いアプリ |
|---|---|---|
| Amazon ECS最適化 Amazon Linux 2 | Amazon ECSのための標準的なEC2を作成できる。もっとも推奨。 | |
| Amazon ECS最適化 Amazon Linux 2022 | Amazon Linux 2よりも先進的な機能を持つEC2を作成できる。 https://docs.aws.amazon.com/linux/al2022/ug/compare-al2-to-AL2022.html |
|
| Amazon ECS最適化 Amazon Linux | Amazon ECSのための標準的なEC2を作成できる。非推奨であり、Amazon Linux 2を使用したほうが良い。 | |
| Amazon ECS最適化 Amazon Linux 2 arm64 | arm64ベースのGravitonプロセッサーが搭載されたEC2を作成できる。 | |
| Amazon ECS最適化 Amazon Linux 2 GPU | GPUが搭載されたEC2を作成できる。 | GPUが必要なアプリケーション (計算処理系、機械学習系のアプリケーション) |
| Amazon ECS最適化 Amazon Linux 2 推定 | Amazon EC2 Inf1インスタンスを作成できる。 |
タスク配置戦略¶
Amazon ECSタスクをAmazon ECSクラスターに配置するときのアルゴリズムを選択できる。
| 戦略 | 説明 |
|---|---|
| Spread | Amazon ECSタスクを各場所にバランスよく配置する |
| Binpack | Amazon ECSタスクを 1 個の場所にできるだけ多く配置する。 |
| Random | Amazon ECSタスクをランダムに配置する。 |
05. on Fargate¶
on Fargateとは¶
Fargateをホストとして、コンテナを作成する。
Fargateの実体はEC2である (ドキュメントに記載がないが、AWSサポートに確認済み) 。

05-02. セットアップ¶
コンソール画面の場合¶
▼ Amazon ECSサービス¶
| 設定項目 | 説明 | 補足 |
|---|---|---|
| Amazon ECSタスク定義 | Amazon ECSサービスで維持管理するタスクの定義ファミリー名とリビジョンを設定する。 | |
| 起動タイプ | Amazon ECSタスク内のコンテナの起動タイプを設定する。 | |
| プラットフォームのバージョン | Fargateのカーネルとコンテナランタイムのバージョンを設定する。 | バージョンによって、連携できるAWSリソースが異なる。 |
| サービスタイプ | ||
| Amazon ECSタスクの必要数 | 非スケーリング時またはデプロイ時のタスク数を設定する。 | 最小ヘルス率と最大率の設定値に影響する。 |
| 最小ヘルス率 | Amazon ECSタスクの必要数の設定を 100%とし、新しいタスクのデプロイ時に、稼働中タスクの最低合計数を割合で設定する。 |
例として、タスク必要数が4個だと仮定する。タスクヘルス最小率を50%とすれば、稼働中タスクの最低合計数は2個となる。デプロイ時の既存タスク停止と新タスク起動では、稼働中の既存タスク/新タスクの数が最低合計数未満にならないように制御される。 https://toris.io/2021/04/speeding-up-amazon-ecs-container-deployments |
| 最大率 | Amazon ECSタスクの必要数の設定を 100%とし、新しいタスクのデプロイ時に、稼働中/停止中タスクの最高合計数を割合で設定する。 |
例として、タスク必要数が4個だと仮定する。タスク最大率を200%とすれば、稼働中/停止中タスクの最高合計数は8個となる。デプロイ時の既存タスク停止と新タスク起動では、稼働中/停止中の既存タスク/新タスクの数が最高合計数を超過しないように制御される。 https://toris.io/2021/04/speeding-up-amazon-ecs-container-deployments |
| ヘルスチェックの待機期間 | デプロイ時のALB/NLBのヘルスチェックを開始するまでの待機時間を設定する。猶予期間を過ぎても、ALB/NLBのヘルスチェックが失敗していれば、サービスはタスクを停止し、新しいタスクを再起動する。 | ALB/NLBではターゲットを登録し、ヘルスチェックを実行するプロセスがある。特にNLBでは、これに時間がかかる。またアプリケーションによっては、コンテナの作成に時間がかかる。そのため、NLBのヘルスチェックが完了する前に、Amazon ECSサービスがNLBのヘルスチェックの結果を確認してしまうことがある。例えば、NLBとLaravelを使用する場合は、ターゲット登録とLaravelコンテナの築の時間を加味して、330 秒以上を目安とする。例えば、ALBとNuxt.js (SSRモード) を使用する場合は、600 秒以上を目安とする。注意点として、アプリコンテナ作成にかかる時間は、開発環境での所要時間を参考にする。 |
| タスクの最小数 | スケーリング時のタスク数の最小数を設定する。 | |
| タスクの最大数 | スケーリング時のタスク数の最大数を設定する。 | |
| ロードバランシング | ALBでルーティングするコンテナを設定する。 | |
| タスク数 | Amazon ECSタスクの作成数をいくつに維持するかを設定する。 | タスクが何らかの原因で停止した場合、タスクを自動的に作成する。 |
| デプロイメント | ローリングアップデート、ブルー/グリーンデプロイがある。 | |
| サービスロール |
▼ Amazon ECSタスク定義¶
| 設定項目 | 説明 | 補足 |
|---|---|---|
| Amazon ECSタスク定義名 | Amazon ECSタスク定義の名前を設定する。 | |
| ネットワークモード | ホストとコンテナ間を接続するネットワーク様式を設定する。 | |
| 互換性 | ||
| オペレーティングシステムファミリー | ||
| タスクロール | Amazon ECSタスク内のコンテナのアプリケーションが、他のAWSリソースにリクエストを送信するために必要なロールを設定する。 | |
| タスク実行ロール | Amazon ECSタスク内のAmazon ECSコンテナエージェントが、他のAWSリソースにリクエストを送信するために必要なロールを設定する。 | |
| タスクメモリ | Amazon ECSタスク当たりのコンテナの合計メモリサイズを設定する。 | Amazon ECSタスク内のコンテナに割り振ることを想定し、やや多めにメモリを設定したほうが良い。 |
| タスクCPU | Amazon ECSタスク当たりのコンテナの合計CPUサイズを設定する。 | ・Amazon ECSタスク内のコンテナに割り振ることを想定し、やや多めにメモリを設定したほうが良い。 ・CPUごとに使用できるメモリサイズに違いがあり、大きなCPUほど小さなメモリを使用できない。 |
| コンテナ定義 | Amazon ECSタスク内のコンテナを設定する。 | JSONをインポートしても設定できる。 |
| サービス統合 | ||
| プロキシ | ||
| FireLens統合 | FireLensコンテナを使用する場合に有効化する。 | |
| ボリューム |
▼ コンテナ定義¶
Amazon ECSタスク内のコンテナ1つに対して、環境を設定する。
| 設定項目 | 対応する docker コマンドオプション |
説明 | 補足 |
|---|---|---|---|
| cpu | --cpus |
タスク全体に割り当てられたメモリ (タスクメモリ) のうち、該当のコンテナに最低限割り当てるCPUユニット数を設定する。cpuReservationという名前になっていないことに注意する。 CPUユニット数の比率に基づいて、タスク全体のCPUが各コンテナに割り当てられる。『ソフト制限』ともいう。 | ・https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_definition_parameters.html#container_definition_environment ・https://qiita.com/_akiyama_/items/e9760dd61d94b8031247 |
| dnsServers | --dns |
コンテナが名前解決に使用するDNSサーバーのIPアドレスを設定する。 | |
| essential | コンテナが必須か否かを設定する。 | ・true の場合、コンテナが停止すると、タスクに含まれる全コンテナが停止する。false の場合、コンテナが停止しても、その他のコンテナは停止しない。 |
|
| healthCheck (command) |
--health-cmd |
ホストからFargateに対して、curl コマンドによるリクエストを送信し、レスポンス内容を確認。 |
|
| healthCheck (interval) |
--health-interval |
ヘルスチェックの間隔を設定する。 | |
| healthCheck (retries) |
--health-retries |
ヘルスチェックを成功と見なす回数を設定する。 | |
| hostName | --hostname |
コンテナにホスト名を設定する。 | |
| image | Amazon ECRのURLを設定する。 | 指定できるURLの記法は、Dockerfileの FROM 処理と同じである。https://hiroki-it.github.io/tech-notebook/infrastructure_as_code/infrastructure_as_code_docker_dockerfile.html |
|
| logConfiguration (logDriver) |
--log-driver |
ログドライバーを指定することにより、ログの出力先を設定する。 | Dockerのログドライバーにおおよそ対応しており、Fargateであれば『awslogs、awsfirelens、splunk』に設定できる。EC2であれば『awslogs、json-file、syslog、journald、fluentd、gelf、logentries』を設定できる。 |
| logConfiguration (options) |
--log-opt |
各ログドライバーのオプションを設定する。 | |
| portMapping | --publish--expose |
ホストとFargateのアプリケーションのポート番号をマッピングし、ポートフォワーディングを実行する。 | containerPort のみを設定し、hostPort は設定しなければ、EXPOSEとして定義できる。https://docs.aws.amazon.com/AmazonECS/latest/APIReference/API_PortMapping.html |
| secrets (volumesFrom) |
パラメーターストアから出力する変数を設定する。 | ||
| memory | --memory |
コンテナのメモリサイズの閾値を設定し、これを超えた場合にコンテナを停止する『ハード制限』ともいう。 | ・https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_definition_parameters.html#container_definition_memory |
| memoryReservation | --memory-reservation |
タスク全体に割り当てられたメモリ (タスクメモリ) のうち、該当のコンテナに最低限割り当てるメモリ分を設定する。『ソフト制限』ともいう。 | ・https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_definition_parameters.html#container_definition_memory |
| mountPoints | 隠蔽されたホストとコンテナの間でボリュームマウントを実行する。Fargateは、脆弱性と性能の観点で、バインドマウントに対応していない。 | ・https://hiroki-it.github.io/tech-notebook/virtualization/virtualization_container_docker.html | |
| ulimit | Linuxコマンドの--ulimit に相当 |
05-03. Amazon ECSタスク¶
サイドカー¶
マイクロサービスのコンテナからログを収集する場合に、AWS以外 (Google Cloud Logging) に送信するのであればサイドカーパターンでログルーター (EC2ならFluentBit、FargateならFireLens) を採用しないといけない。
Amazon ECSサービスを増えるたびにサイドカーの横展開していく。
IPアドレス¶
▼ Amazon ECSタスクのIPアドレス¶
Amazon ECSタスクごとに異なるプライベートIPが割り当てられる。
このIPアドレスに対して、ALBはルーティングを実行する。
▼ FargateのIPアドレス¶
Fargateは動的パブリックIPアドレス (Fargateの再作成後に変化するIPアドレス) を持ち、固定パブリックIPアドレスであるElastic IPアドレスを設定できない。
リクエストの先にある外部サービスが、セキュリティ上で静的なIPアドレスを要求する場合、リクエスト (パブリックネットワーク向き通信) 時に送信元パケットに付加されるIPアドレスが動的になり、リクエストできなくなってしまう。
そこで、Fargateのリクエストが、Elastic IPアドレスを持つAWS NAT Gatewayを経由する (Fargateは、パブリックサブネットとプライベートサブネットのどちらに配置しても良い) 。
これによって、AWS NAT GatewayのElastic IPアドレスが送信元パケットに付加されるため、Fargateの送信元IPアドレスを見かけ上静的に扱えるようになる。

Amazon ECSタスクの一時起動¶
▼ DBマイグレーション¶
現在起動中のAmazon ECSタスクとは別に、新しいタスクを一時的に起動する。
CI/CDパイプライン上で実行する以外に、ローカルマシンから手動で実行する場合もある。
起動時に、overrides オプションを使用して、指定したAmazon ECSタスク定義のコンテナ設定を上書きできる。
正規表現で設定する必要があり、加えてJSONでは『\』を『\\』にエスケープしなければならない。
コマンドが実行された後に、タスクは自動的にStopped状態になる。
*実装例*
LaravelのSeederコマンドやロールバックコマンドを、ローカルマシンから実行する。
#!/bin/bash
set -x
echo "Set Variables"
SERVICE_NAME="dev-foo-ecs-service"
CLUSTER_NAME="dev-foo-ecs-cluster"
TASK_NAME="dev-foo-ecs-task-definition"
SUBNETS_CONFIG=$(aws ecs describe-services \
--cluster ${CLUSTER_NAME} \
--services ${SERVICE_NAME} \
--query "services[].deployments[].networkConfiguration[].awsvpcConfiguration[].subnets[]")
SGS_CONFIG=$(aws ecs describe-services \
--cluster ${CLUSTER_NAME} \
--services ${SERVICE_NAME} \
--query "services[].deployments[].networkConfiguration[].awsvpcConfiguration[].securityGroups[]")
# 実行したいコマンドをoverridesに設定する
# AWSのステージング環境では、動作確認のために使用する初期データを挿入する
echo "Run Task"
TASK_ARN=$(aws ecs run-task \
--launch-type FARGATE \
--cluster ${CLUSTER_NAME} \
--platform-version "1.4.0" \
--network-configuration "awsvpcConfiguration={subnets=${SUBNETS_CONFIG},securityGroups=${SGS_CONFIG}}" \
--task-definition ${TASK_NAME} \
--overrides '{\"containerOverrides\": [{\"name\": \"laravel-container\",\"command\": [\"php\", \"artisan\", \"db:seed\", \"--class=DummySeeder\", \"--force\"]}]}' \
--query "tasks[0].taskArn" | tr -d """)
echo "Wait until task stopped"
aws ecs wait tasks-stopped \
--cluster ${CLUSTER_NAME} \
--tasks ${TASK_ARN}
echo "Get task result"
RESULT=$(aws ecs describe-tasks \
--cluster ${CLUSTER_NAME} \
--tasks ${TASK_ARN})
echo ${RESULT}
EXIT_STATUS=$(echo ${RESULT} | jq .tasks[0].containers[0].exitStatus)
echo exitStatus ${EXIT_STATUS}
exit ${EXIT_STATUS}
注意点として、実行IAMユーザーを作成し、Amazon ECSタスクを起動できる必要最低限の認可スコープを紐付ける。
{
"Version": "2012-10-17",
"Statement":
[
{
"Effect": "Allow",
"Action":
[
"iam:PassRole",
"ecs:RunTask",
"ecs:DescribeServices",
"ecs:DescribeTasks",
],
"Resource":
[
"arn:aws:ecs:*:<AWSアカウントID>:service/*",
"arn:aws:ecs:*:<AWSアカウントID>:task/*",
"arn:aws:ecs:*:<AWSアカウントID>:task-definition/*",
"arn:aws:iam::<AWSアカウントID>:role/*",
],
},
],
}
Amazon ECSタスクのデプロイ手法¶
▼ ローリングアップデート¶
(1)-
最小ヘルス率の設定値を基に、ローリングアップデート時の稼働中タスクの最低合計数が決定される。
(2)-
最大率の設定値を基に、ローリングアップデート時の稼働中/停止中タスクの最高合計数が決まる
(3)-
Amazon ECSは、既存タスクを稼働中のまま、新タスクを最高合計数いっぱいまで作成する。
(4)-
Amazon ECSは、待機時間後にALB/NLBによる新タスクに対するヘルスチェックの結果を確認する。ヘルスチェックが成功していれば、既存タスクを停止する。ただし、最小ヘルス率によるタスクの最低合計数が保たれる。
(5)-
『新タスクの起動』と『ヘルスチェック確認後の既存タスクの停止』のプロセスが繰り返し実行され、徐々に既存タスクが新タスクに置き換わる。
(6)-
全ての既存タスクが新タスクに置き換わる。

▼ ブルー/グリーンデプロイメント¶
CodeDeployを使用してデプロイする。
プライベートサブネット内のFargateからAmazon VPC外のAWSリソースへのアクセス¶

| VPCエンドポイントの接続先 | タイプ | プライベートDNS名 | 説明 |
|---|---|---|---|
| Amazon CloudWatch Logs | Interface | logs.ap-northeast-1.amazonaws.com |
Amazon ECSコンテナのログをPOSTリクエストを送信するため。 |
| Amazon ECR | Interface | api.ecr.ap-northeast-1.amazonaws.com*.dkr.ecr.ap-northeast-1.amazonaws.com |
イメージのGETリクエストを送信するため。 |
| Amazon S3 | Gateway | なし | イメージのレイヤーをPOSTリクエストを送信するため |
| AWS Systems Manager | Interface | ssm.ap-northeast-1.amazonaws.com |
AWS Systems ManagerのパラメーターストアにGETリクエストを送信するため。 |
| AWS Secrets Manager | Interface | ssmmessage.ap-northeast-1.amazonaws.com |
AWS Secrets Managerを使用するため。 |
プライベートサブネット内のFargateからVPC外のAWSリソース (例:コントロールプレーン、Amazon ECR、Amazon S3、AWS Systems Manager、Amazon CloudWatch Logs、DynamoDBなど) にリクエストを送信する場合、専用のVPCエンドポイントを設ける必要がある。
AWS NAT GatewayとVPCエンドポイントの両方を作成している場合、ルートテーブルでは、VPCエンドポイントへのリクエストのほうが優先される。
そのため、AWS NAT Gatewayがある状態でVPCエンドポイントを作成すると、接続先が自動的に変わってしまうことに注意する。
注意点として、パブリックネットワークにリクエストを送信する場合は、VPCエンドポイントのみでなくAWS NAT Gatewayも作成する必要がある。
Fargate上のコンテナへの接続¶
▼ AWS SSM Session Managerを使用したAmazon ECS Exec¶

AWS SSM Session Managerを使用してAmazon ECSタスク内のコンテナに接続し、コンテナのログインシェルを起動する。
AWS Systems Managerを使用してコンテナに接続する場合、コンテナのホストにsystems-managerエージェントをインストールしておく必要がある。
ただし、AWS FargateとしてのAmazon EC2には、systems-managerエージェントがプリインストールされているため、これは不要である。
(1)-
Amazon ECSサービスで、ECS-Execオプションを有効化する。
(2)-
Amazon VPCエンドポイントにて、ssmmessagesエンドポイントを作成する。
(3)-
Amazon ECSタスク実行ロールにIAMポリシーを付与する。
これにより、Amazon ECSタスクがAWS SSM Session Managerにリクエストを送信できるようになる。
{
"Version": "2012-10-17",
"Statement":
[
{
"Effect": "Allow",
"Action":
[
"ssmmessages:CreateControlChannel",
"ssmmessages:CreateDataChannel",
"ssmmessages:OpenControlChannel",
"ssmmessages:OpenDataChannel",
],
"Resource": "*",
},
],
}
(4)-
Amazon ECS Execの実行ユーザーに、IAMポリシーを付与する。
{
"Version": "2012-10-17",
"Statement":
[
{
"Effect": "Allow",
"Action": ["ecs:ExecuteCommand"],
"Resource":
[
"arn:aws:ecs:*:<AWSアカウントID>:cluster/*",
"arn:aws:ecs:*:<AWSアカウントID>:task/*",
],
},
],
}
(5)-
事前の設定がなされているか否かをecs-exec-checkerスクリプトを実行して確認する。
#!/bin/bash
ECS_CLUSTER_NAME=prd-foo-ecs-cluster
ECS_TASK_ID=bar
bash <(curl -Ls https://raw.githubusercontent.com/aws-containers/amazon-ecs-exec-checker/main/check-ecs-exec.sh) $ECS_CLUSTER_NAME $ECS_TASK_ID
(6)-
Amazon ECSタスク内のコンテナに接続し、コンテナのログインシェルを起動する。bashを実行するときに、『
/bin/bash』や『/bin/sh』で指定すると、binより上のパスもAmazon ECSに送信されてしまう。例えば、Windowsなら『
C:/Program Files/Git/usr/bin/bash』を送信する。これはCloudTrailでExecuteCommandイベントとして確認できる。
Amazon ECSコンテナ内ではbashへのパスが異なるため、接続に失敗する。そのため、bashを直接的に指定する。
#!/bin/bash
set -xe
ECS_CLUSTER_NAME=prd-foo-ecs-cluster
ECS_TASK_ID=bar
ECS_CONTAINER_NAME=laravel
aws ecs execute-command \
--cluster $ECS_CLUSTER_NAME \
--task $ECS_TASK_ID \
--container $ECS_CONTAINER_NAME \
--interactive \
--debug \
--command "bash"