Please note: This workshop version is now deprecated, and an updated version has been moved to AWS Workshop Studio. This workshop remains here for reference to those who have used this workshop before for reference only. Link to updated workshop is here: Launching EC2 Spot Instances.
When adopting EC2 Spot Instances, we recommend you to consider Amazon EC2 Auto Scaling group (ASG) since it offers the most up to date EC2 features such as attribute-based instance type selection, capacity rebalancing, scaling policies and many more functionalities.
Amazon EC2 Auto Scaling groups contain a collection of Amazon EC2 Instances that are treated as a logical grouping for the purposes of automatic scaling and management. Auto Scaling groups also enable you to use Amazon EC2 Auto Scaling features such as health check replacements and scaling policies. Both maintaining the number of instances in an Auto Scaling group and automatic scaling are the core functionality of the Amazon EC2 Auto Scaling service.
In the past, Auto Scaling groups used launch configurations. Applications using launch configurations should migrate to launch templates so that you can leverage the latest features. With launch templates you can provision capacity across multiple instance types using both Spot Instances and On-Demand Instances to achieve the desired scale, performance, and cost optimization.
Being instance flexible is an important Spot best practice, you can use attribute-based instance type selection (ABIS) to automatically select multiple instance types matching your requirements. A common case when using Auto Scaling groups, is to use it with workloads that require a mix of Spot and On-Demand capacity.
In this step you create a json file for creating Auto Scaling groups using AWS CLI. The configuration uses the launch template that you created in the previous steps and ABIS to pick any current generation non-GPU instance types with 2 vCPU
and no limit on memory. OnDemandBaseCapacity
allows you to set an initial capacity of 1
On-Demand Instance. Remaining capacity is mix of 25%
On-Demand Instances and 75%
Spot Instances defined by the OnDemandPercentageAboveBaseCapacity
.
cat <<EoF > ./asg-policy.json
{
"LaunchTemplate":{
"LaunchTemplateSpecification":{
"LaunchTemplateId":"${LAUNCH_TEMPLATE_ID}",
"Version":"1"
},
"Overrides":[{
"InstanceRequirements": {
"VCpuCount": {
"Min": 2,
"Max": 2
},
"MemoryMiB": {
"Min": 0
},
"CpuManufacturers": [
"intel",
"amd"
],
"InstanceGenerations": [
"current"
],
"AcceleratorCount": {
"Max": 0
}
}
}]
},
"InstancesDistribution":{
"OnDemandBaseCapacity":1,
"OnDemandPercentageAboveBaseCapacity":25,
"SpotAllocationStrategy":"price-capacity-optimized"
}
}
EoF
In this configuration you set the SpotAllocationStrategy
to price-capacity-optimized
. The price-capacity-optimized
allocation strategy allocates instances from the Spot Instance pools that offer low prices and high capacity availability. You can read more about the price-capacity-optimized
allocation strategy in Introducing the price-capacity-optimized allocation strategy for EC2 Spot Instances blog post.
export VPC_ID=$(aws ec2 describe-vpcs --filters Name=isDefault,Values=true | jq -r '.Vpcs[0].VpcId')
export SUBNETS=$(aws ec2 describe-subnets --filters Name=vpc-id,Values="${VPC_ID}")
export SUBNET_1=$((echo $SUBNETS) | jq -r '.Subnets[0].SubnetId')
export SUBNET_2=$((echo $SUBNETS) | jq -r '.Subnets[1].SubnetId')
2
Availability Zones, min-size 2
, max-size 20
, and desired-capacity 10
vCPU units.aws autoscaling create-auto-scaling-group --auto-scaling-group-name EC2SpotWorkshopASG --min-size 2 --max-size 20 --desired-capacity 10 --desired-capacity-type vcpu --vpc-zone-identifier "${SUBNET_1},${SUBNET_2}" --capacity-rebalance --mixed-instances-policy file://asg-policy.json
You have now created a mixed instances Auto Scaling group!
Given the configuration you used above, try to answer the following questions. Click to expand and see the answers.
A Spot capacity pool is a set of unused EC2 Instances with the same instance type (for example, m5.large) and Availability Zone. At the time of creation of the workshop, our example matched 35 instance types and 3 Availability Zones, which makes a total of (35*2)=70 Spot pools. Increasing the number of Spot pools is a key for adopting Spot best practices.
The desired capacity is 10
vCPUs, so 5 instances having a sum of 10 vCPUs are provisioned. Out of them, the first 1 EC2 instance is On-Demand as requested by the OnDemandBaseCapacity. The rest of the instances, follow a proportion of 25%
On-Demand (1 instances) and 75%
Spot (3 Instances) according to OnDemandPercentageAboveBaseCapacity.
To check the instances within the newly created Auto Scaling group you can use describe-auto-scaling-groups
.
aws autoscaling describe-auto-scaling-groups --auto-scaling-group-names EC2SpotWorkshopASG
To check the newly created instances Auto Scaling group in the AWS Console, head to EC2 Dashboard home, click on “Instances (running), and filter the list of instances using aws:autoscaling:groupName = EC2SpotWorkshopASG
.
To describe one or more instances you use describe-instances
. To retrieve all the Spot Instances that have been launched with the Auto Scaling group, you apply two filters: instance-lifecycle
set to spot
to retrieve only Spot Instances and the custom tag aws:autoscaling:groupName
that must be set to EC2SpotWorkshopASG
. To learn more about Tagging lifecycle, review this documentation.
aws ec2 describe-instances --filters Name=instance-lifecycle,Values=spot Name=tag:aws:autoscaling:groupName,Values=EC2SpotWorkshopASG Name=instance-state-name,Values=running --query "Reservations[*].Instances[*].[InstanceId]" --output text
Similarly, you can run the following command to retrieve the identifiers of the instances that have been launched using the On-Demand purchasing model.
aws ec2 describe-instances --filters Name=tag:aws:autoscaling:groupName,Values=EC2SpotWorkshopASG Name=instance-state-name,Values=running --query "Reservations[*].Instances[? InstanceLifecycle==null].[InstanceId]" --output text
To create an Auto Scaling group with specific/individual instance types, you can use a json file that is given below. The example uses m5.large, c5.large, r5.large, m4.large, c4.large, and r4.large.
cat <<EoF > ./asg-policy.json
{
"LaunchTemplate":{
"LaunchTemplateSpecification":{
"LaunchTemplateId":"${LAUNCH_TEMPLATE_ID}",
"Version":"1"
},
"Overrides":[
{
"InstanceType":"m5.large"
},
{
"InstanceType":"c5.large"
},
{
"InstanceType":"r5.large"
},
{
"InstanceType":"m4.large"
},
{
"InstanceType":"c4.large"
},
{
"InstanceType":"r4.large"
}
]
},
"InstancesDistribution":{
"OnDemandBaseCapacity":1,
"OnDemandPercentageAboveBaseCapacity":25,
"SpotAllocationStrategy":"price-capacity-optimized"
}
}
EoF
To create an Auto Scaling group with specific/individual instance types, you can use a json file that is given below. The example instances that have 2 vCPUs and 4 vCPUs example m5.large, c5.large, r5.large, m5.xlarge, c5.xlarge, and r5.xlarge.
cat <<EoF > ./asg-policy.json
{
"LaunchTemplate":{
"LaunchTemplateSpecification":{
"LaunchTemplateId":"${LAUNCH_TEMPLATE_ID}",
"Version":"1"
},
"Overrides":[{
"InstanceRequirements": {
"VCpuCount": {
"Min": 2,
"Max": 4
},
"MemoryMiB": {
"Min": 0
},
"CpuManufacturers": [
"intel",
"amd"
],
"InstanceGenerations": [
"current"
],
"AcceleratorCount": {
"Max": 0
}
}
}]
},
"InstancesDistribution":{
"OnDemandBaseCapacity":1,
"OnDemandPercentageAboveBaseCapacity":25,
"SpotAllocationStrategy":"capacity-optimized"
}
}
EoF
The capacity-optimized
allocation strategy allocates instances from the Spot Instance pools with the optimal capacity for the number of instances that are launching, making use of real-time capacity data and optimizing the selection of used Spot Instances. Use capacity-optimized
Spot allocation strategy works well for workloads where the cost of a Spot interruption is very significant. You can read about the benefits of using capcity-optimized
in the blog post Capacity-Optimized Spot Instance allocation in action at Mobileye and Skyscanner.
cat <<EoF > ./asg-policy.json
{
"LaunchTemplate":{
"LaunchTemplateSpecification":{
"LaunchTemplateId":"${LAUNCH_TEMPLATE_ID}",
"Version":"1"
},
"Overrides":[{
"InstanceRequirements": {
"VCpuCount": {
"Min": 2,
"Max": 2
},
"MemoryMiB": {
"Min": 0
},
"CpuManufacturers": [
"intel",
"amd"
],
"InstanceGenerations": [
"current"
],
"AcceleratorCount": {
"Max": 0
}
}
}]
},
"InstancesDistribution":{
"OnDemandBaseCapacity":1,
"OnDemandPercentageAboveBaseCapacity":25,
"SpotAllocationStrategy":"capacity-optimized"
}
}
EoF
These are some of the characteristics and functionality that make Amazon EC2 Auto Scaling groups the right choice for most workloads: