terraform

Announcing Support for Predictive Scaling Policy in the Terraform AWS Provider

The Terraform AWS provider now supports predictive scaling policy, a machine learning based scaling mechanism of Amazon EC2 Auto Scaling.

Along with our partner Amazon Web Services, we are pleased to announce support for predictive scaling policy for Amazon EC2 Auto Scaling in the Terraform AWS Provider. Predictive Scaling uses machine learning to analyze the history of the Auto Scaling group in order to launch capacity levels in advance.

»How It Works

Predictive scaling is a new auto scaling policy that proactively increases capacity of your EC2 Auto Scaling group to meet upcoming demand. In other words, predictive scaling learns from the historic demand and usage patterns within an EC2 Auto Scaling group, including regularly occurring spikes, to predict future capacity. After predicting capacity requirements, your Auto Scaling group will then launch the required number of instances to ensure that enough instances are provisioned to meet predicted demand. As a result, applications are more responsive for end users without over-provisioned capacity going unused.

In order to accurately forecast demand and capacity, predictive scaling relies on two historical metrics, Load Metric and Scaling Metric. Load Metric is a proxy for total demand on the Auto Scaling group while Scaling Metric is a proxy for average usage of an instance within an Auto Scaling group.

Predictive scaling forecasts demand based on Load Metric trends. To calculate required capacity, predictive scaling tracks the corresponding trend of the Scaling Metric against the Load Metric and ensures that enough instances are launched to maintain the Scaling Metric at the target value.

AWS recommends using both dynamic scaling and predictive scaling for more accurate auto scaling. Predictive scaling sets the baseline capacity according to the historic pattern of your Auto Scaling group, while dynamic scaling makes upward adjustments to account for any deviations on top of forecasted demand. Predictive scaling leads to a scaling action only if the predicted capacity is higher than the desired capacity. Predictive scaling does not scale-in your Auto Scaling groups on its own and relies on dynamic scaling to scale-in. If you are using an alternate mechanism to change the desired capacity of an Auto Scaling group, you can continue using that along with predictive scaling.

Additional information about this service can be found within the EC2 Auto Scaling documentation.

»Enabling Predictive Scaling Policy in the Terraform AWS Provider

In order to use Predictive Scaling Policy in the Terraform AWS provider, you will need to employ one new resource aws_predictive_scaling_configuration as well as make some changes to the existing aws_autoscaling_policy resource.

In order to try out this feature, you will need:

  • Terraform v0.12 or greater installed
  • The latest version of the Terraform AWS provider

The Terraform configuration below demonstrates how the Terraform AWS provider can be used to configure Predictive Scaling within an EC2 Auto Scaling group.

data "aws_ami" "amzn" {                                                         
 most_recent = true                                                            
 owners      = ["amazon"]                                                          
 filter {                                                                      
   name   = "name"                                                             
   values = ["amzn2-ami-hvm-*-x86_64-gp2"]                                     
 }                                                                             
}                                                                               
data "aws_availability_zones" "available" {                                      
 state = "available"                                                           
 filter {                                                                      
   name   = "opt-in-status"                                                    
   values = ["opt-in-not-required"]                                            
 }                                                                             
}                                                                               
resource "aws_launch_configuration" "test" {                                    
 name          = "launch_configuration"                                                          
 image_id      = data.aws_ami.amzn.id                                          
 instance_type = "t2.micro"                                                    
}                                                                               
resource "aws_autoscaling_group" "test" {                                       
 availability_zones   = slice(data.aws_availability_zones.available.names, 0, 2)
 name                 = "autoscaling_group"                                                   
 max_size             = 0                                                      
 min_size             = 0                                                      
 force_delete         = true                                                   
 launch_configuration = aws_launch_configuration.test.name                     
}
resource "aws_autoscaling_policy" "policy_predictive" {
 name                   = "policy_predictive"
 policy_type            = "PredictiveScaling"
 autoscaling_group_name = aws_autoscaling_group.test.name
 predictive_scaling_config {
   metric_specification {
     target_value = 32
     predefined_scaling_metric_specification {
      predefined_metric_type = "ASGAverageCPUUtilization"
      resource_label         = "testLabel"
     }
     predefined_load_metric_specification {
      predefined_metric_type = "ASGTotalCPUUtilization"
      resource_label         = "testLabel"
     }
   }
   mode                          = "ForecastAndScale"
   scheduling_buffer_time        = 10
   max_capacity_breach_behavior  = "IncreaseMaxCapacity"
   max_capacity_buffer           = 10
 }
}
data "aws_ami" "amzn" {                                                          most_recent = true                                                             owners      = ["amazon"]                                                           filter {                                                                         name   = "name"                                                                values = ["amzn2-ami-hvm-*-x86_64-gp2"]                                      }                                                                             }                                                                               data "aws_availability_zones" "available" {                                       state = "available"                                                            filter {                                                                         name   = "opt-in-status"                                                       values = ["opt-in-not-required"]                                             }                                                                             }                                                                               resource "aws_launch_configuration" "test" {                                     name          = "launch_configuration"                                                           image_id      = data.aws_ami.amzn.id                                           instance_type = "t2.micro"                                                    }                                                                               resource "aws_autoscaling_group" "test" {                                        availability_zones   = slice(data.aws_availability_zones.available.names, 0, 2) name                 = "autoscaling_group"                                                    max_size             = 0                                                       min_size             = 0                                                       force_delete         = true                                                    launch_configuration = aws_launch_configuration.test.name                     }resource "aws_autoscaling_policy" "policy_predictive" { name                   = "policy_predictive" policy_type            = "PredictiveScaling" autoscaling_group_name = aws_autoscaling_group.test.name predictive_scaling_config {   metric_specification {     target_value = 32     predefined_scaling_metric_specification {      predefined_metric_type = "ASGAverageCPUUtilization"      resource_label         = "testLabel"     }     predefined_load_metric_specification {      predefined_metric_type = "ASGTotalCPUUtilization"      resource_label         = "testLabel"     }   }   mode                          = "ForecastAndScale"   scheduling_buffer_time        = 10   max_capacity_breach_behavior  = "IncreaseMaxCapacity"   max_capacity_buffer           = 10 }}

»Further Information

For more information on how to use this feature in Terraform, consult the provider documentation in the Terraform Registry.

To report bugs and request enhancements for this feature, open an issue on the Terraform AWS Provider repository on GitHub. We would love to hear your feedback!

Sign up for the latest HashiCorp news