endertunc
endertunc

Reputation: 2108

Is it possible to add multiple auto-scaling policy with Elastic Beanstlak

We have automated our deployment life-cyle with ElasticBeanstalk and we are happy it except one thing; we want to have multiple auto-scaling policy like CPU Usage and network traffic but it seems we just have to choose one of the metrics.

We are currently using open source tool named eb_deployer and it supports configuration listed in following link:http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/command-options-general.html#command-options-general-autoscalingtrigger

As far as we understood, we can only set one policy with aws:autoscaling:trigger

We also look for .ebextensions but it seems .ebextension also same limitations on that matter. So, we were wondering is there any way to use multiple auto-scaling policy with ElasticBeanstalk?

Upvotes: 11

Views: 3095

Answers (2)

Tracy Xia
Tracy Xia

Reputation: 390

I faced the same problem and reached out to AWS Tech Support for guidance. Their response is in line with the one @Tamar provided above. The only frustration / annoyance I found is that the monitoring period for CloudWatch Alarms must be 60 seconds or multiples of 60 seconds for the "AWS/xxx" namespace. :( That seems like an awfully long time for production environments.

Here is the entirety of the answer from AWS:

  1. latency-autoscalingtrigger.config
option_settings:
  aws:autoscaling:trigger:
    MeasureName: Latency
    Statistic: Average
    Unit: Seconds
    Period: '1'
    EvaluationPeriods: '1'
    UpperThreshold: '0.3'
    UpperBreachScaleIncrement: '1'
    LowerThreshold: '0.1'
    LowerBreachScaleIncrement: '-1'
  1. cpu-autoscalingtrigger.config
Mappings:
  CustomConfig:
    ScalingConfig: 
      MetricNamespace: AWS/EC2
      TriggerMeasurement: CPUUtilization
      TriggerStatistic: Average
      MeasurementPeriod: '60'
      NumCoolDownPeriods: '1'
      LowerThreshold: '30'
      UpperThreshold: '60'
      LowerBreachIncrement: '-1'
      UpperBreachIncrement: '1'

##############################################
#### Do not modify values below this line ####
##############################################

Resources:
  CustomScalingAlarmHigh:
    Type: AWS::CloudWatch::Alarm
    Properties:
      AlarmActions:
      - {Ref: AutoScalingCustomScaleUpPolicy}
      AlarmDescription: ElasticBeanstalk custom scale up alarm
      ComparisonOperator: GreaterThanThreshold
      Dimensions:
      - Name: AutoScalingGroupName
        Value: {Ref: AWSEBAutoScalingGroup}
      EvaluationPeriods:
        Fn::FindInMap: [CustomConfig, ScalingConfig, NumCoolDownPeriods]
      MetricName:
        Fn::FindInMap: [CustomConfig, ScalingConfig, TriggerMeasurement]
      Namespace:
        Fn::FindInMap: [CustomConfig, ScalingConfig, MetricNamespace]
      Period:
        Fn::FindInMap: [CustomConfig, ScalingConfig, MeasurementPeriod]
      Statistic:
        Fn::FindInMap: [CustomConfig, ScalingConfig, TriggerStatistic]
      Threshold:
        Fn::FindInMap: [CustomConfig, ScalingConfig, UpperThreshold]
  CustomScalingAlarmLow:
    Type: AWS::CloudWatch::Alarm
    Properties:
      AlarmActions:
      - {Ref: AutoScalingCustomScaleDownPolicy}
      AlarmDescription: ElasticBeanstalk custom scale down alarm
      ComparisonOperator: LessThanThreshold
      Dimensions:
      - Name: AutoScalingGroupName
        Value: {Ref: AWSEBAutoScalingGroup}
      EvaluationPeriods:
        Fn::FindInMap: [CustomConfig, ScalingConfig, NumCoolDownPeriods]
      MetricName:
        Fn::FindInMap: [CustomConfig, ScalingConfig, TriggerMeasurement]
      Namespace:
        Fn::FindInMap: [CustomConfig, ScalingConfig, MetricNamespace]
      Period:
        Fn::FindInMap: [CustomConfig, ScalingConfig, MeasurementPeriod]
      Statistic:
        Fn::FindInMap: [CustomConfig, ScalingConfig, TriggerStatistic]
      Threshold:
        Fn::FindInMap: [CustomConfig, ScalingConfig, LowerThreshold]
  AutoScalingCustomScaleDownPolicy:
    Type: AWS::AutoScaling::ScalingPolicy
    Properties:
      AdjustmentType: ChangeInCapacity
      AutoScalingGroupName: {Ref: AWSEBAutoScalingGroup}
      ScalingAdjustment:
        Fn::FindInMap: [CustomConfig, ScalingConfig, LowerBreachIncrement]
  AutoScalingCustomScaleUpPolicy:
    Type: AWS::AutoScaling::ScalingPolicy
    Properties:
      AdjustmentType: ChangeInCapacity
      AutoScalingGroupName: {Ref: AWSEBAutoScalingGroup}
      ScalingAdjustment:
        Fn::FindInMap: [CustomConfig, ScalingConfig, UpperBreachIncrement]

Upvotes: 0

Tamar Inbar
Tamar Inbar

Reputation: 51

The following configuration works for me and should be placed in the elastic bean extensions config files: This configuration does several things that change the default behavior:

  • It disables the auto generated alarms

  • It create 2 scale policies: one CPU load , the other on number of requests per target.

  • Per alarm it is using a different evaluation period for scale up versus scale down, since I wish to scale up fast but scale down slow.

disabling the auto generated alarms:

 ######## disable the default alarms ##############
  AWSEBCloudwatchAlarmHigh:
    Type: AWS::CloudWatch::Alarm
    Properties:
      AlarmActions: []

  AWSEBCloudwatchAlarmLow:
    Type: AWS::CloudWatch::Alarm
    Properties:
      AlarmActions: []
  
  
  #############   create custom policies ##################
  AutoScalingCustomScaleDownPolicy:
    Type: AWS::AutoScaling::ScalingPolicy
    Properties:
      AdjustmentType: ChangeInCapacity
      AutoScalingGroupName: {Ref: AWSEBAutoScalingGroup}
      ScalingAdjustment: -1

  AutoScalingCustomScaleUpPolicy:
    Type: AWS::AutoScaling::ScalingPolicy
    Properties:
      AdjustmentType: ChangeInCapacity
      AutoScalingGroupName: {Ref: AWSEBAutoScalingGroup}
      ScalingAdjustment: 1
 
 
 
 ############## alarms for cpu load - reusing the default policy of EB #######
   CustomScalingAlarmHigh:
    Type: AWS::CloudWatch::Alarm
    Properties:
      AlarmActions:
        - {Ref: AWSEBAutoScalingScaleUpPolicy}
      AlarmDescription: { "Fn::Join" : ["", [{ "Ref" : "AWSEBEnvironmentName" }, ": scale up on cpu load" ]]}
      ComparisonOperator: GreaterThanThreshold
      Dimensions:
        - Name: AutoScalingGroupName
          Value: {Ref: AWSEBAutoScalingGroup}
      Statistic: Average
      Period: 60
      EvaluationPeriods: 2
      MetricName: CPUUtilization
      Namespace: AWS/EC2
      Threshold: 55

  CustomScalingAlarmLow:
    Type: AWS::CloudWatch::Alarm
    Properties:
      AlarmActions:
        - {Ref: AWSEBAutoScalingScaleDownPolicy}
      AlarmDescription: { "Fn::Join" : ["", [{ "Ref" : "AWSEBEnvironmentName" }, ": scale down on cpu load" ]]}
      ComparisonOperator: LessThanThreshold
      Dimensions:
        - Name: AutoScalingGroupName
          Value: {Ref: AWSEBAutoScalingGroup}
      Period: 60
      Statistic: Average
      EvaluationPeriods: 15
      MetricName: CPUUtilization
      Namespace: AWS/EC2
      Threshold: 20



 ############# alarms on request count per target ####################
 ############# using the new custom policy        ####################
  CustomScalingOnRequestCountAlarmLow:
    Type: AWS::CloudWatch::Alarm
    Properties:
      AlarmActions:
        - {Ref: AutoScalingCustomScaleDownPolicy}
      InsufficientDataActions:
        - {Ref: AWSEBAutoScalingScaleDownPolicy}
      AlarmDescription: { "Fn::Join" : ["", [{ "Ref" : "AWSEBEnvironmentName" }, ": scale down on request count." ]]}
      ComparisonOperator: LessThanThreshold
      Dimensions:
        - Name: LoadBalancer
          Value: { "Fn::GetAtt": [ "AWSEBV2LoadBalancer", "LoadBalancerFullName" ] }
        - Name: TargetGroup
          Value: { "Fn::GetAtt": [ "AWSEBV2LoadBalancerTargetGroup", "TargetGroupFullName" ] }
      Period: 60
      Statistic: Sum
      EvaluationPeriods: 5
      MetricName: RequestCountPerTarget
      Namespace: AWS/ApplicationELB
      Threshold: 70

  CustomScalingOnRequestCountAlarmHigh:
    Type: AWS::CloudWatch::Alarm
    Properties:
      AlarmActions:
        - {Ref: AutoScalingCustomScaleUpPolicy}
      AlarmDescription: { "Fn::Join" : ["", [{ "Ref" : "AWSEBEnvironmentName" }, ": scale up on request count." ]]}
      ComparisonOperator: GreaterThanThreshold
      Dimensions:
        - Name: LoadBalancer
          Value: { "Fn::GetAtt": [ "AWSEBV2LoadBalancer", "LoadBalancerFullName" ] }
        - Name: TargetGroup
          Value: { "Fn::GetAtt": [ "AWSEBV2LoadBalancerTargetGroup", "TargetGroupFullName" ] }
      Period: 60
      Statistic: Sum
      EvaluationPeriods: 2
      MetricName: RequestCountPerTarget
      Namespace: AWS/ApplicationELB
      Threshold: 250

Upvotes: 5

Related Questions