Skip to content

Commit

Permalink
Merge pull request #8 from Guslington/feature/scaling
Browse files Browse the repository at this point in the history
scaling policy
  • Loading branch information
Guslington authored Aug 21, 2018
2 parents cd02b20 + b815052 commit 5f5bc2d
Show file tree
Hide file tree
Showing 3 changed files with 144 additions and 13 deletions.
6 changes: 6 additions & 0 deletions ecs-service.cfhighlander.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,12 @@
ComponentParam 'DnsDomain'
end

ComponentParam 'DesiredCount', 1
ComponentParam 'MinimumHealthyPercent', 100
ComponentParam 'MaximumPercent', 200

ComponentParam 'EnableScaling', 'false', allowedValues: ['true','false']

if ((defined? network_mode) && (network_mode == "awsvpc"))
maximum_availability_zones.times do |az|
ComponentParam "SubnetCompute#{az}"
Expand Down
135 changes: 122 additions & 13 deletions ecs-service.cfndsl.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
az_conditions_resources('SubnetCompute', maximum_availability_zones)
end

Condition('IsScalingEnabled', FnEquals(Ref('EnableScaling'), 'true'))

log_retention = 7 unless defined?(log_retention)
Resource('LogGroup') {
Type 'AWS::Logs::LogGroup'
Expand Down Expand Up @@ -89,6 +91,13 @@
task_def.merge!({MountPoints: mount_points })
end

# volumes from
if task.key?('volumes_from')
task['volumes_from'].each do |source_container|
task_def.merge!({ VolumesFrom: [ SourceContainer: source_container ] })
end
end

# add port
if task.key?('ports')
port_mapppings = []
Expand Down Expand Up @@ -277,17 +286,9 @@
end

IAM_Role('Role') do
AssumeRolePolicyDocument ({
Statement: [
Effect: 'Allow',
Principal: { Service: [ 'ecs.amazonaws.com' ] },
Action: [ 'sts:AssumeRole' ]
]
})
AssumeRolePolicyDocument service_role_assume_policy('application-autoscaling')
Path '/'
Policies Policies(IAMPolicies.new.create_policies([
'ecs-service-role'
]))
ManagedPolicyArns ["arn:aws:iam::aws:policy/service-role/AmazonEC2ContainerServiceRole"]
end

has_security_group = false
Expand All @@ -307,12 +308,20 @@
end
end

desired_count = 1
if (defined? scaling_policy) && (scaling_policy.has_key?('min'))
desired_count = scaling_policy['min']
elsif defined? desired
desired_count = desired
end

ECS_Service('Service') do
Cluster Ref("EcsCluster")
DesiredCount 1
Property("HealthCheckGracePeriodSeconds", health_check_grace_period || 0)
DesiredCount Ref('DesiredCount')
DeploymentConfiguration ({
MinimumHealthyPercent: 100,
MaximumPercent: 200
MinimumHealthyPercent: Ref('MinimumHealthyPercent'),
MaximumPercent: Ref('MaximumPercent')
})
TaskDefinition Ref('Task')

Expand All @@ -332,4 +341,104 @@
end
end if defined? task_definition

if defined?(scaling_policy)

IAM_Role(:ServiceECSAutoScaleRole) {
Condition 'IsScalingEnabled'
AssumeRolePolicyDocument service_role_assume_policy('application-autoscaling')
Path '/'
Policies ([
PolicyName: 'ecs-scaling',
PolicyDocument: {
Statement: [
{
Effect: "Allow",
Action: ['cloudwatch:DescribeAlarms','cloudwatch:PutMetricAlarm','cloudwatch:DeleteAlarms'],
Resource: "*"
},
{
Effect: "Allow",
Action: ['ecs:UpdateService','ecs:DescribeServices'],
Resource: Ref('Service')
}
]
}])
}

ApplicationAutoScaling_ScalableTarget(:ServiceScalingTarget) {
Condition 'IsScalingEnabled'
MaxCapacity scaling_policy['max']
MinCapacity scaling_policy['min']
ResourceId FnJoin( '', [ "service/", Ref('EcsCluster'), "/", FnGetAtt(:Service,:Name) ] )
RoleARN FnGetAtt(:ServiceECSAutoScaleRole,:Arn)
ScalableDimension "ecs:service:DesiredCount"
ServiceNamespace "ecs"
}

ApplicationAutoScaling_ScalingPolicy(:ServiceScalingUpPolicy) {
PolicyName FnJoin('-', [ Ref('EnvironmentName'), component_name, "scale-up-policy" ])
PolicyType "StepScaling"
ScalingTargetId Ref(:ServiceScalingTarget)
StepScalingPolicyConfiguration({
AdjustmentType: "ChangeInCapacity",
Cooldown: scaling_policy['up']['cooldown'] || 300,
MetricAggregationType: "Average",
StepAdjustments: [{ ScalingAdjustment: scaling_policy['up']['adjustment'].to_s, MetricIntervalLowerBound: 0 }]
})
}

ApplicationAutoScaling_ScalingPolicy(:ServiceScalingDownPolicy) {
Condition 'IsScalingEnabled'
PolicyName FnJoin('-', [ Ref('EnvironmentName'), component_name, "scale-down-policy" ])
PolicyType 'StepScaling'
ScalingTargetId Ref(:ServiceScalingTarget)
StepScalingPolicyConfiguration({
AdjustmentType: "ChangeInCapacity",
Cooldown: scaling_policy['up']['cooldown'] || 900,
MetricAggregationType: "Average",
StepAdjustments: [{ ScalingAdjustment: scaling_policy['down']['adjustment'].to_s, MetricIntervalLowerBound: 0 }]
})
}

default_alarm = {}
default_alarm['metric_name'] = 'CPUUtilization'
default_alarm['namespace'] = 'AWS/ECS'
default_alarm['statistic'] = 'Average'
default_alarm['period'] = '60'
default_alarm['evaluation_periods'] = '5'
default_alarm['dimentions'] = [
{ Name: 'ServiceName', Value: FnGetAtt(:Service,:Name)},
{ Name: 'ClusterName', Value: Ref('EcsCluster')}
]

CloudWatch_Alarm(:ServiceScaleUpAlarm) {
Condition 'IsScalingEnabled'
AlarmDescription FnJoin(' ', [Ref('EnvironmentName'), "#{component_name} ecs scale down alarm"])
MetricName scaling_policy['up']['metric_name'] || default_alarm['metric_name']
Namespace scaling_policy['up']['namespace'] || default_alarm['namespace']
Statistic scaling_policy['up']['statistic'] || default_alarm['statistic']
Period (scaling_policy['up']['period'] || default_alarm['period']).to_s
EvaluationPeriods scaling_policy['up']['evaluation_periods'].to_s
Threshold scaling_policy['up']['threshold'].to_s
AlarmActions [Ref(:ServiceScalingUpPolicy)]
ComparisonOperator 'GreaterThanThreshold'
Dimensions scaling_policy['up']['dimentions'] || default_alarm['dimentions']
}

CloudWatch_Alarm(:ServiceScaleDownAlarm) {
Condition 'IsScalingEnabled'
AlarmDescription FnJoin(' ', [Ref('EnvironmentName'), "#{component_name} ecs scale down alarm"])
MetricName scaling_policy['down']['metric_name'] || default_alarm['metric_name']
Namespace scaling_policy['down']['namespace'] || default_alarm['namespace']
Statistic scaling_policy['down']['statistic'] || default_alarm['statistic']
Period (scaling_policy['down']['period'] || default_alarm['period']).to_s
EvaluationPeriods scaling_policy['down']['evaluation_periods'].to_s
Threshold scaling_policy['down']['threshold'].to_s
AlarmActions [Ref(:ServiceScalingDownPolicy)]
ComparisonOperator 'LessThanThreshold'
Dimensions scaling_policy['down']['dimentions'] || default_alarm['dimentions']
}

end

end
16 changes: 16 additions & 0 deletions ecs-service.config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ log_retention: 7

# network_mode: awsvpc

# health_check_grace_period: 60
#
# cpu: 256
# memory: 256
#
Expand Down Expand Up @@ -48,3 +50,17 @@ log_retention: 7
# priority: 20
# tags:
# Name: api

# scaling_policy:
# min: 2
# max: 4
# up:
# cooldown: 150
# threshold: 70
# evaluation_periods: 5
# adjustment: 2
# down:
# cooldown: 600
# threshold: 70
# evaluation_periods: 5
# adjustment: -1

0 comments on commit 5f5bc2d

Please sign in to comment.