Home / AWS

AWSHow-toBeginner

CloudWatch basics: your first alarm with SNS email, from metric to notification

Understand metrics, statistics and periods, create a CPU and a status-check alarm that emails you through SNS, test it on purpose, and avoid the beginner settings that make alarms noisy or silent.

Deepak Bhardwaj3 min read

Applies toAmazon CloudWatch metrics and alarms, Amazon SNS, EC2, AWS CLI v2

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: Average CPU over 5 minutes, Maximum over 1 minute, Sum of 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.