Scaling Policies are used to change the Desired Capacity of an Auto Scaling group. These scaling policies can be triggered from an AWS CloudWatch alarm or can be triggered via an API call.
Once Auto Scaling decides to terminate an instance in response to a scaling policy, it uses a Termination Policy to determine which instance to terminate. However, there is no capability for Auto Scaling to inform the instance that it is about to be terminated. As you say, this could result in a busy instance being terminated.
There are several ways to handle this:
- Allowing the termination, but recovering the work that was lost
- Using Auto Scaling group lifecycle hooks
- Controlling instance termination yourself
Allowing the termination to happen is perfectly acceptable if your auto scaling group is processing information from a work queue, such as Amazon Simple Queue Service (SQS). In this case, if an instance pulls a message from an SQS queue, the message will be marked as invisible for a period of time. If the instance does not specifically delete the message within the time period, then the message will reappear in the queue. Thus, the work that was lost will be reprocessed.
Using Auto Scaling group lifecycle hooks allows an instance marked for termination to be moved into a Terminating:Wait
state. A signal is then sent via SNS or SQS, and Auto Scaling waits for a signal to come back before terminating the instance. See Auto Scaling Group Lifecycle.
Controlling instance termination yourself means that your own code will determine which instance to terminate. It could do this in a friendly manner by sending a signal to your application on the chosen instance, effectively telling it to finish processing work and signal back when it is ready to be terminated. There are no standard APIs for this functionality -- you'd have to create it yourself, possibly triggered by a CloudWatch alarm and SNS notification.
You can use the DetachInstances API call to remove an instance from an auto scaling group, after which you would finish jobs and then terminate the instance.