An alarm watches one metric and changes state when it crosses a threshold. Wire it to SNS and you get an email. That is the whole idea; the details below decide whether the alarm is useful.
Metrics in three words: namespace, dimension, statistic
- Namespace: the service, for example
AWS/EC2. - Dimensions: which resource, for example
InstanceId=i-0abc. - Statistic over a period:
AverageCPU over 5 minutes,Maximumover 1 minute,Sumof errors.
aws cloudwatch list-metrics --namespace AWS/EC2 --dimensions Name=InstanceId,Value=i-0abc1234def567890 --output table
aws cloudwatch get-metric-statistics --namespace AWS/EC2 --metric-name CPUUtilization \
--dimensions Name=InstanceId,Value=i-0abc1234def567890 \
--start-time $(date -u -d '-3 hours' +%FT%TZ) --end-time $(date -u +%FT%TZ) \
--period 300 --statistics Average Maximum --output table
Tip
EC2 sends basic metrics every 5 minutes. Memory and disk space are not included; install the CloudWatch agent to get them.
Step 1: an SNS topic for notifications
TOPIC=$(aws sns create-topic --name ops-alerts --query TopicArn --output text)
aws sns subscribe --topic-arn $TOPIC --protocol email --notification-endpoint oncall@example.com
Open the confirmation email and click the link. Until you do, nothing is delivered.
Step 2: a CPU alarm
aws cloudwatch put-metric-alarm --alarm-name web01-cpu-high \
--namespace AWS/EC2 --metric-name CPUUtilization \
--dimensions Name=InstanceId,Value=i-0abc1234def567890 \
--statistic Average --period 300 --evaluation-periods 3 --datapoints-to-alarm 3 \
--threshold 85 --comparison-operator GreaterThanThreshold \
--treat-missing-data missing \
--alarm-actions $TOPIC --ok-actions $TOPIC
This fires when average CPU is above 85% for three 5-minute periods in a row: 15 minutes of real load, not a 30-second spike.
Step 3: a status-check alarm that also recovers the instance
aws cloudwatch put-metric-alarm --alarm-name web01-status-failed \
--namespace AWS/EC2 --metric-name StatusCheckFailed_System \
--dimensions Name=InstanceId,Value=i-0abc1234def567890 \
--statistic Maximum --period 60 --evaluation-periods 2 \
--threshold 0 --comparison-operator GreaterThanThreshold \
--alarm-actions $TOPIC arn:aws:automate:eu-west-1:ec2:recover
The recover action moves the instance to healthy hardware when AWS detects a host problem. Many current instance types also do this automatically; check your instance type's simplified automatic recovery support.
Step 4: test it on purpose
aws cloudwatch set-alarm-state --alarm-name web01-cpu-high --state-value ALARM --state-reason "test"
aws cloudwatch describe-alarm-history --alarm-name web01-cpu-high --max-records 5 --output table
You should get an email within a minute. The alarm returns to its real state at the next evaluation.
The settings beginners get wrong
| Setting | Problem | Better |
|---|---|---|
| Period 60, 1 evaluation | Alerts on every spike | 5 min x 3, or "3 out of 5" with datapoints-to-alarm |
| Average for error counts | Hides bursts | Sum for counts, Maximum for "any failure" |
| Missing data = breaching on a metric that only reports on errors | Alarm stuck in ALARM | notBreaching for sparse error metrics |
| Missing data = notBreaching on a heartbeat metric | A dead server looks fine | breaching when silence means trouble |
| No OK action | Nobody knows it recovered | Add --ok-actions |
See all your alarms
aws cloudwatch describe-alarms --state-value ALARM --query "MetricAlarms[].[AlarmName,StateReason]" --output table
aws cloudwatch describe-alarms --query "MetricAlarms[?ActionsEnabled==\`false\`].AlarmName"
Prevent it next time
- Every production instance gets a status-check alarm and an agent-based disk-space alarm.
- Route alarms to a team address or chat channel, not one person's inbox.
- Review alarms that fired more than ten times last month; tune or delete them.