I'm looking to optimize the cost of our auto-scaling EC2 groups by having them launch spot instances instead of on-demand instances.
What I really want is to be able to keep some servers in the group as on-demand instances, regardless of what happens to the spot instance pricing market. Then I want any additional servers in the group, above my configured minimum, to be spot instances. I'm generally OK with the delay in adding servers via spot requests.
I can't seem to find any way to do this and I've tried to scour the AWS documentation. It appears that an ASG can either be on-demand or spot, but not a hybrid.
I could possibly manually add an on-demand instance to the Elastic Load Balancer assigned to the auto-scaling group, but then the load of that server would not be factored into the auto-scaling measurements and triggers.
I suppose I could enter a ridiculously high bid price in order to ensure that I always get the servers I need, but then I look at the pricing history and see occasional large spikes.
The AWS documentation is at odds with itself, since in one place it says that if you enter a server minimum, that number is "ensured" to be there. But then when you read about spot instances, there are no assurances. The price differential for spot is compelling, so I'd like to leverage that as much as I can while still maintaining an always-on baseline. Is this possible?
The approach discussed above would be a little messy, and not so flexible. The more canonical approach is to just create 2 ASGs (one for spot, one for on-demand) and then register them both with the same ELB (discussed here). This gives you the ability to control each independently rather than trying to muck with LC swaps in a single ASG.
This hybrid Auto Scaling approach doesn't seem to be available out of the box indeed, unfortunately.
However, you might be able to work around this limitation as follows (untested, just a system design I've been juggling around for a while):
Potential Workaround
As outlined in Using Auto Scaling to Launch Spot Instances, the spot price bid is a parameter of the Launch Configuration in use. As you pointed out, there is no hybrid launch configuration available, rather it must be either on-demand or spot, which means the use case requires two different launch configurations.
This doesn't seem to help right away, because You can attach only one launch configuration to an Auto Scaling group at a time, with the following (partially outdated) constraints (see Launch Configuration):
The emphasized parts are key though, with the former covering the requirement to keep the on-demand instances running after changing from the respective initial on-demand launch configuration to the additional spot launch configuration, and the latter not necessarily being the case anymore due to the recently introduced Auto Scaling Termination Policies (for a change there hasn't been the usually fanfare via an accompanying AWS blog post), documented in Instance Termination Policy for Your Auto Scaling Group:
As outlined in How Your Termination Policy Works, you can now specify NewestInstance, if you want the last launched instance to be terminated, which would be one of the more recently launched spot instances:
Obviously there might be a bit more to this, e.g. you can either specify any one of the policies as a standalone policy, or you can list multiple policies in an ordered list, but this approach should ensure the load of all instances being factored into the auto-scaling measurements and triggers; one caveat remains though:
Caveat
If the load balancer terminates one of the on-demand instances for any other reason (e.g. because it has become unhealthy in itself), it wouldn't be replaced by an on-demand instance automatically. So you'd need to monitor and account for this event separately, e.g. by temporarily activating the on-demand launch configuration again.
Good luck!
I took inspiration from the answers here to come up with https://github.com/ashwanthkumar/matsya
It helps you do the following
In case you only want 1 ASG with static number of on-demand instances, the following should work:
Create Auto Scaling group based on Spot Instance Launch configuration.
Suspend Auto Scaling on ASG
Manually add on-demand instances (static base load) to ASG and turn on instance protection for those instances.
Resume Autoscaling on ASG
The default auto scaling policy will now ignore the on-demand instances (due to protection) and terminate the same number of spot instances as on-demand instance to achieve the desired number of the group. Any scale-in or out activities will only launch or terminate spot instances.
At the moment you can mix ondemand and spot instances across single ASG
Amazon EC2 Auto Scaling now lets you provision and automatically scale instances across purchase options, Availability Zones (AZ), and instance families in a single Auto Scaling group (ASG), to optimize scale, performance, and cost. Now you can include Spot Instances with On-Demand and RIs in a single ASG, to save up to 90% on compute.