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"