ECS Fargate で「Capacity is unavailable at this time」になったときの対処方法
この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
困っていた内容
ECS の「スケジュールされたタスク」で Fargate タスクを実行しています。
先日、タスクが実行されていない事象が発生し、調査したところ CloudTrail の RunTask イベントに次のエラーが記録されていました。
Capacity is unavailable at this time. Please try again later or in a different availability zone
原因と対処方法を教えてください。
どう対応すればいいの?
AWS 側でタスク実行に必要なリソースが確保できなかった旨のエラーです。
時間をおいて、再度 ECS タスクの実行をお試しください。
Troubleshoot unavailable capacity for Fargate tasks | AWS re:Post
If Amazon ECS doesn't have the capacity to launch a Fargate task, then the RunTask API fails with the following error message:
"Capacity is unavailable at this time. Please try again later or in a different availability zone"
EC2 同様、Fargate でも AWS 側でタスク実行に必要な空きリソースがない場合は、キャパシティ不足のエラーが発生する場合があります。
通常、時間をおいて再実行で対処できますが、状況に応じて次の内容も併せてお試しください。
- 別のアベイラビリティーゾーンを指定する(別 AZ の VPC サブネットを指定する)
 - タスク定義で異なるタスクサイズを指定する
 
また、Step Functions を利用することで再実行を自動化することも可能です。
Step Functions で自動リトライを構築してみた
構成図

手順
- Step Functions の作成
 - IAM ポリシーの修正
 - EventBridge の作成
 
事前準備として、ECS クラスターやタスク定義、サブネットは用意します。
準備が完了したら、以下手順を進めます。
Step Functions の作成
Step Functions コンソールを開き、「ステートマシンの作成」をクリックします。

「Blank」を選択して「選択」をクリックします。

「コード」を選択します。

定義(赤枠で囲った部分)に、次のコードを参考に ECS タスクを起動するフローを入力します。

{
    "Comment": "Running Fargate tasks with automatic retry when capacity is insufficient",
    "StartAt": "Run an ECS Task",
    "States": {
        "Run an ECS Task": {
            "Type": "Task",
            "Resource": "arn:aws:states:::ecs:runTask.sync",
            "Parameters": {
                "LaunchType": "FARGATE",
                "Cluster": "<クラスター ARN>",
                "TaskDefinition": "<タスク定義 ARN>:<リビジョン番号>",
                "NetworkConfiguration": {
                    "AwsvpcConfiguration": {
                        "Subnets": [
                            "<サブネットID>"
                        ],
                        "SecurityGroups": [
                            "<セキュリティグループID>"
                        ],
                        "AssignPublicIp": "ENABLED"
                    }
                }
            },
            "Retry": [
                {
                    "ErrorEquals": [
                        "ECS.AmazonECSException"
                    ],
                    "IntervalSeconds": 60,
                    "MaxAttempts": 3,
                    "BackoffRate": 3
                }
            ],
            "End": true
        }
    }
}
「設定」をクリックします。

「ステートマシン名」に任意の名前を入力し「作成」を選択します。

「確認」をクリックします。

IAM ポリシーの修正
IAM ロールやポリシーが自動で作成されますが、iam:PassRoleが不足しているので追加します。
参考:Step FunctionsからECS RunTaskしようとしたら「ECS.AccessDeniedException」と出た時の対処法 | DevelopersIO
「ステートマシンは正常に作成されました」の表示を確認したら、「設定」タブから「IAM で表示」をクリックします。

アタッチされたポリシーをクリックします。

「編集」をクリックします。

「新しいステートメントを追加」をクリックします。

追加されたステートメント(赤枠で囲った部分)を、次の内容に修正します。

{
    "Sid": "Statement1",
    "Effect": "Allow",
    "Action": [
        "iam:PassRole"
    ],
    "Resource": "*"
}
「次へ」をクリックします。

「変更を保存」をクリックします。

ポリシーが正常に更新されたことを確認します。

EventBridge の作成
Step Functions コンソール(作成したステートマシン)の「アクション」から「EventBridge ルールを作成」を選択します。

「名前」に任意の名前を入力し、「スケジュール」を選択します。「EventBridge Scheduler で続行」をクリックします。

実行間隔となるスケジュールパターンを入力し、「次へ」をクリックします。

「テンプレート化されたターゲット」から「StartExecution」を選択します。

作成したステートマシンを選択して「スケジュールの確認と作成をスキップ」を選択します。

「スケジュールを作成」をクリックします。

スケジュールが作成されたことを確認します。

スケジュールされたタスク同様、時間になると自動的に ECS タスクが実行されます。

キャパシティ不足が発生した際は、Retryフィールドの内容に応じて自動再試行が実行されます。

参考資料
- Troubleshoot unavailable capacity for Fargate tasks | AWS re:Post
 - Step Functions ワークフローでのエラーの処理 - AWS Step Functions
 - Step Functions を使用して Amazon ECSまたは Fargate タスクを実行する - AWS Step Functions
 - ECSの「スケジュールされたタスク」で稀に ECS タスクが実行されていないときの対処方法 | DevelopersIO
 - Step Functions で ECS タスク(Fargate)を定期実行してみる | DevelopersIO
 







