My AWS Notebook
Table of Contents
CPUUtilization
and MemoryUtilization
(Maximum)CPUUtilization
and MemoryUtilization
(Maximum)See predefined metric
ASGAverageCPUUtilization
for EC2 Cluster
Probably not reactive enough if using Average for traffic that does not have a pattern; could be a huge difference between Max and Average.
"TargetTrackingScalingPolicy": {
"Type": "AWS::AutoScaling::ScalingPolicy",
"Properties": {
"AutoScalingGroupName": {"Ref": "ECSAutoScalingGroup"},
"PolicyType": "TargetTrackingScaling",
"TargetTrackingConfiguration": {
"DisableScaleIn": false,
"PredefinedMetricSpecification": {
"PredefinedMetricType": "ASGAverageCPUUtilization"
},
"TargetValue": {"Ref": "ClusterAutoScalingGroupAverageCPUUtilization"}
}
}
},
CPUUtilization
and MemoryUtilization
(Maximum)To scale in your Auto Scaling group when the specified metric has insufficient data, create a simple or step scaling policy and have an alarm invoke the scaling policy when it changes to the INSUFFICIENT_DATA state.
E.g. On CPUUtilization
"TargetTrackingScalingPolicyOnCPUUtilization": {
"Type": "AWS::AutoScaling::ScalingPolicy",
"Properties": {
"AutoScalingGroupName": {"Ref": "ECSAutoScalingGroup"},
"PolicyType": "TargetTrackingScaling",
"TargetTrackingConfiguration": {
"CustomizedMetricSpecification": {
"Dimensions": [{
"Name": "ClusterName",
"Value": {"Fn::Join": ["-", [{"Fn::FindInMap": ["StageMap", {"Ref":"Stage"}, "EnvironmentName"]}, "Cluster"]]}
}],
"MetricName": "CPUUtilization",
"Namespace": "AWS/ECS",
"Statistic": "Maximum",
"Unit": "Percent"
},
"DisableScaleIn": false,
"TargetValue": {"Ref": "ClusterAutoScalingGroupTargetCPUUtilization"}
}
}
},
CPUUtilization
and MemoryUtilization
(Maximum)E.g. On CPUUtilization
"StepScalingScaleOutPolicyOnCPUUtilization": {
"Type": "AWS::AutoScaling::ScalingPolicy",
"Properties": {
"AdjustmentType": "ChangeInCapacity",
"AutoScalingGroupName": {"Ref": "ECSAutoScalingGroup"},
"EstimatedInstanceWarmup": 300,
"MetricAggregationType": "Maximum",
"PolicyType": "StepScaling",
"StepAdjustments": [{
"MetricIntervalLowerBound": 0,
"ScalingAdjustment": 1
}]
}
},
"StepScalingScaleOutPolicyOnMemoryUtilization": {
"Type": "AWS::AutoScaling::ScalingPolicy",
"Properties": {
"AdjustmentType": "ChangeInCapacity",
"AutoScalingGroupName": {"Ref": "ECSAutoScalingGroup"},
"EstimatedInstanceWarmup": 300,
"MetricAggregationType": "Maximum",
"PolicyType": "StepScaling",
"StepAdjustments": [{
"MetricIntervalLowerBound": 0,
"ScalingAdjustment": 1
}]
}
},
"StepScalingScaleInPolicyOnCPUUtilization": {
"Type": "AWS::AutoScaling::ScalingPolicy",
"Properties": {
"AdjustmentType": "ChangeInCapacity",
"AutoScalingGroupName": {"Ref": "ECSAutoScalingGroup"},
"MetricAggregationType": "Average",
"PolicyType": "StepScaling",
"StepAdjustments": [{
"MetricIntervalUpperBound": 0,
"ScalingAdjustment": -1
}]
}
},
"AutoScalingHighEcsCpuAlarm": {
"Type": "AWS::CloudWatch::Alarm",
"Properties": {
"AlarmActions": [
{"Ref": "StepScalingScaleOutPolicyOnCPUUtilization"},
{"Ref": "SnsNotificationTopic"}
],
"AlarmDescription": {"Fn::Join": [" ",
["Containers CPU Utilization High", {"Ref": "ClusterAutoScalingHighCPUValue"}]
]},
"AlarmName": {"Fn::Join": ["/", [{"Ref": "ECSCluster"}, "CPUUtilizationHigh"]]},
"ComparisonOperator": "GreaterThanOrEqualToThreshold",
"Dimensions": [{
"Name": "ClusterName",
"Value": {"Ref": "ECSCluster"}
}],
"EvaluationPeriods": 1,
"MetricName": "CPUUtilization",
"Namespace": "AWS/ECS",
"Period": 60,
"Statistic": "Maximum",
"Threshold": {"Ref": "ClusterAutoScalingHighCPUValue"},
"TreatMissingData": "notBreaching"
}
},
"AutoScalingHighEcsMemoryAlarm": {
"Type": "AWS::CloudWatch::Alarm",
"Properties": {
"AlarmActions": [
{"Ref": "StepScalingScaleOutPolicyOnMemoryUtilization"},
{"Ref": "SnsNotificationTopic"}
],
"AlarmDescription": {"Fn::Join": [" ",
["Containers Memory Utilization High", {"Ref": "ClusterAutoScalingHighMemoryValue"}]
]},
"AlarmName": {"Fn::Join": ["/", [{"Ref": "ECSCluster"}, "MemoryUtilizationHigh"]]},
"ComparisonOperator": "GreaterThanOrEqualToThreshold",
"Dimensions": [{
"Name": "ClusterName",
"Value": {"Ref": "ECSCluster"}
}],
"EvaluationPeriods": 1,
"MetricName": "MemoryUtilization",
"Namespace": "AWS/ECS",
"Period": 60,
"Statistic": "Maximum",
"Threshold": {"Ref": "ClusterAutoScalingHighMemoryValue"},
"TreatMissingData": "notBreaching"
}
},
"AutoScalingLowEcsCpuAlarm": {
"Type": "AWS::CloudWatch::Alarm",
"Properties": {
"AlarmActions": [
{"Ref": "StepScalingScaleInPolicyOnCPUUtilization"}
],
"AlarmDescription": {"Fn::Join": [" ",
["Containers CPU Utilization Low", {"Ref": "ClusterAutoScalingLowCPUValue"}]
]},
"AlarmName": {"Fn::Join": ["/", [{"Ref": "ECSCluster"}, "CPUUtilizationLow"]]},
"ComparisonOperator": "LessThanOrEqualToThreshold",
"Dimensions": [{
"Name": "ClusterName",
"Value": {"Ref": "ECSCluster"}
}],
"EvaluationPeriods": 1,
"MetricName": "CPUUtilization",
"Namespace": "AWS/ECS",
"Period": 600,
"Statistic": "Average",
"Threshold": {"Ref": "ClusterAutoScalingLowCPUValue"},
"TreatMissingData": "notBreaching"
}
},
See also Migrating to Amazon Linux 2
In CloudFormation
Add Parameters
for always using the latest AMI
"EcsOptimizedAmi": {
"Description": "Amazon ECS-optimized AMI",
"Type": "AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>",
"Default": "/aws/service/ecs/optimized-ami/amazon-linux-2/recommended/image_id"
},
In BlockDeviceMappings
, use /dev/xvda
instead of xvdcz
"BlockDeviceMappings": [{
"DeviceName": "/dev/xvda",
"Ebs": {
"VolumeType": "gp2",
"VolumeSize": {"Ref": "EcsInstanceVolumeSize"}
}
}],
In AWS::CloudFormation::Init
, use awslogsd
instead of awslogs
"services": {
"sysvinit": {
"cfn-hup": {
"enabled": true,
"ensureRunning": true,
"files": [
"/etc/cfn/cfn-hup.conf",
"/etc/cfn/hooks.d/cfn-auto-reloader.conf"
]
},
"awslogsd": {
"enabled": true,
"ensureRunning": true,
"files": [
"/etc/awslogs/awslogs.conf",
"/etc/awslogs/awscli.conf"
]
}
}
}