

# Amazon ECS Auto Scaling グループ用に事前初期化されたインスタンスを設定する
<a name="using-warm-pool"></a>

Amazon ECS では、Amazon EC2 Auto Scaling ウォームプールをサポートします。ウォームプールは、事前に初期化済みの Amazon EC2 インスタンスグループでサービス開始が準備されています。アプリケーションがスケールアウトする必要がある場合は、常に Amazon EC2 Auto Scaling はコールドインスタンスを起動するのではなく、ウォームプールから事前に初期化されたインスタンスを使用し、最終的な初期化プロセスの実行を許可し、インスタンスを使用開始します。

ウォームプールの詳細、および Auto Scaling グループにウォームプールを追加する方法については、「*Amazon EC2 Auto Scaling ユーザーガイド*」の「[Amazon EC2 Auto Scaling のウォームプール](https://docs.aws.amazon.com/autoscaling/ec2/userguide/ec2-auto-scaling-warm-pools.html)」を参照してください。

Amazon ECS の Auto Scaling グループのウォームプールを作成または更新する場合、スケールイン (`ReuseOnScaleIn`) 時にインスタンスをウォームプールに戻すオプションを設定することはできません。詳細については、「*AWS Command Line Interface リファレンス*」の「[put-warm-pool](https://docs.aws.amazon.com/cli/latest/reference/autoscaling/put-warm-pool.html)」を参照してください。

Amazon ECS クラスターでウォームプールを使用するには、Amazon EC2 Auto Scaling グループ起動テンプレートの **[User data]** (ユーザーデータ) フィールドで `ECS_WARM_POOLS_CHECK` エージェント設定変数を `true` に設定します。

以下は、Linux インスタンス用の Amazon EC2 起動テンプレートの **[User data]** (ユーザーデータ) フィールドでエージェント設定変数の指定方法の例を示しています。{{MyCluster}} をクラスターの名前に置き換えます。Windows インスタンスの場合は、「[Amazon ECS Windows インスタンスでのウォームプールの使用](#using-warm-pool-windows-lifecycle-hooks)」を参照してください。

```
#!/bin/bash
cat <<'EOF' >> /etc/ecs/ecs.config
ECS_CLUSTER={{MyCluster}}
ECS_WARM_POOLS_CHECK=true
EOF
```

この `ECS_WARM_POOLS_CHECK` 変数は、エージェントバージョン `1.59.0` 以降でのみサポートされています。変数の詳細については、「[Amazon ECS コンテナエージェントの設定](ecs-agent-config.md)」を参照してください。

## Amazon ECS Windows インスタンスでのウォームプールの使用
<a name="using-warm-pool-windows-lifecycle-hooks"></a>

Windows インスタンスで **停止** プール状態でウォームプールを使用する場合は、Amazon EC2 Auto Scaling ライフサイクルフックを使用して、インスタンスが停止する前にユーザーデータの実行が完了していることを確認します。ライフサイクルフックがないと、Amazon ECS の初期化が完了する前にインスタンスが停止することがあります。

Windows ウォームプールインスタンスのライフサイクルフックを設定するには:

1. 次の IAM ポリシーをコンテナインスタンスロールに追加して、インスタンスがライフサイクルアクションを完了できるようにします。

   ```
   {
       "Version": "2012-10-17",
       "Statement": [
           {
               "Effect": "Allow",
               "Action": [
                   "autoscaling:CompleteLifecycleAction"
               ],
               "Resource": "*"
           }
       ]
   }
   ```

1. デフォルトの結果として `ABANDON` で *起動するインスタンス* の Auto Scaling グループにライフサイクルフックを追加し、Amazon ECS の初期化に十分な時間 (10 分など) を許容するハートビートタイムアウトを追加します。詳細については、「*Amazon EC2 Auto Scaling ユーザーガイド*」の「[ライフサイクルフックの追加](https://docs.aws.amazon.com/autoscaling/ec2/userguide/adding-lifecycle-hooks.html)」を参照してください。

1. 以下のユーザーデータを使用して、スケジュールされたタスクを作成し、一定時間後にライフサイクルアクションを完了させます。この遅延により、EC2Launch はインスタンスが停止される前に状態の保存を完了することが保証されます。{{MyCluster}}、{{my-lifecycle-hook}}、{{my-asg-name}} を独自の値に置き換えます。

   ```
   <powershell>
   $lifecycleHookName = "{{my-lifecycle-hook}}"
   $autoScalingGroupName = "{{my-asg-name}}"
   
   $scriptContent = @'
   $token = Invoke-RestMethod -Method Put -Uri http://169.254.169.254/latest/api/token -Headers @{"X-aws-ec2-metadata-token-ttl-seconds" = "21600"}
   $instanceId = Invoke-RestMethod -Method Get -Uri http://169.254.169.254/latest/meta-data/instance-id -Headers @{"X-aws-ec2-metadata-token" = $token}
   $region = Invoke-RestMethod -Method Get -Uri http://169.254.169.254/latest/meta-data/placement/region -Headers @{"X-aws-ec2-metadata-token" = $token}
   $lifecycleHookName = "{{my-lifecycle-hook}}"
   $autoScalingGroupName = "{{my-asg-name}}"
   Complete-ASLifecycleAction -LifecycleHookName $lifecycleHookName -AutoScalingGroupName $autoScalingGroupName -InstanceId $instanceId -LifecycleActionResult 'CONTINUE' -Region $region
   '@
   Set-Content -Path "C:\ProgramData\Amazon\ECS\complete-lifecycle.ps1" -Value $scriptContent
   
   try
   {
       [Environment]::SetEnvironmentVariable("ECS_WARM_POOLS_CHECK", "true", "Machine")
       Import-Module ECSTools
       Initialize-ECSAgent -Cluster {{MyCluster}} -EnableTaskIAMRole
   
       $taskAction = New-ScheduledTaskAction -Execute "powershell.exe" -Argument "-NoProfile -ExecutionPolicy Bypass -File C:\ProgramData\Amazon\ECS\complete-lifecycle.ps1"
       $taskTrigger = New-ScheduledTaskTrigger -Once -At ((Get-Date).AddSeconds(60))
       $settings = New-ScheduledTaskSettingsSet -StartWhenAvailable
       $taskPrincipal = New-ScheduledTaskPrincipal -UserId "SYSTEM" -LogonType ServiceAccount -RunLevel Highest
       Register-ScheduledTask -TaskName "CompleteLifecycleHook" -Action $taskAction -Trigger $taskTrigger -Principal $taskPrincipal -Settings $settings -Force
   }
   catch
   {
       $token = Invoke-RestMethod -Method Put -Uri http://169.254.169.254/latest/api/token -Headers @{"X-aws-ec2-metadata-token-ttl-seconds" = "21600"}
       $INSTANCE = Invoke-RestMethod -Method Get -Uri http://169.254.169.254/latest/meta-data/instance-id -Headers @{"X-aws-ec2-metadata-token" = $token}
       $region = Invoke-RestMethod -Method Get -Uri http://169.254.169.254/latest/meta-data/placement/region -Headers @{"X-aws-ec2-metadata-token" = $token}
       Complete-ASLifecycleAction -InstanceId $INSTANCE -LifecycleHookName $lifecycleHookName -AutoScalingGroupName $autoScalingGroupName -LifecycleActionResult ABANDON -Region $region
   }
   </powershell>
   <persist>true</persist>
   ```

このユーザーデータスクリプトは、以下を実行します。
+ ウォームプールチェックを有効にして Amazon ECS エージェントを初期化します。
+ ユーザーデータの完了から 30 秒待機するスケジュールされたタスクを作成し、ライフサイクルフックにシグナルを送信して続行します。この遅延により、EC2Launch は状態を保存できるため、次回の起動時にユーザーデータが正しく再実行されるようになります。
+ 初期化が失敗すると、ライフサイクルアクションは `ABANDON` で完了するため、インスタンスは終了して置き換えられます。