Ravindra BagaleCourses & study guides मराठी Track your progress

EC2 and EBS Health Check Alarms in CloudWatch (Status Checks, BurstBalance, Queue Length)

How to Stop, Start, Reboot or Recover an EC2 Instance with a CloudWatch Alarm showed the alarm actions. Now we point them at the right health signals: the EC2 status checks and the EBS volume signals. These are the alarms every production server should have from day one.

What you'll learn in this chapter

  • System, instance and attached EBS status checks, and who fixes each
  • Lab: auto-recover on StatusCheckFailed_System, reboot on StatusCheckFailed_Instance
  • EBS volume status checks (ok, warning, impaired)
  • BurstBalance and VolumeQueueLength alarms, with the reason for each value

1. A story: the site is down, but CPU looks fine

A Node.js shop site stops answering at 2 AM. The CPU graph shows a flat 0%. The team thinks "low traffic". In fact the server has frozen: the OS ran out of memory. CPU alarms cannot see this. Status checks can.

Another night a MySQL server on a small gp2 disk becomes very slow. CPU is low again. The disk ran out of burst credits. Only EBS metrics show it.

2. EC2 status checks

Why do we need this?

A server can be "running" in the console and still be useless. AWS tests every instance every minute so you know if it really works.

What is it?

Check / metricWhat it testsTypical causeWho fixesAlarm action
System status check
StatusCheckFailed_System
AWS host: power, network, hardwareHost hardware failureAWSRecover
Instance status check
StatusCheckFailed_Instance
Your OS answers network testsOut of memory, kernel panic, bad network config, full disk at bootYouReboot
Attached EBS check
StatusCheckFailed_AttachedEBS
Attached EBS volumes can do I/OStorage or host problemAWS / you (stop-start)Notify, or stop then start; recover is not supported
Both
StatusCheckFailed
1 if any check fails--Notify

Each metric is 0 (pass) or 1 (fail). So the statistic is Maximum and the threshold is >= 1. The attached EBS check works only on Nitro instances (t3, m5, c5 and newer).

Which check failed, what to doStatus check = 1System check?AWS hardware→ Recover actionsame ID, same IPsInstance check?your OS→ Reboot actionthen read logs
Read top to bottom: decide by which check failed.

Ravindra Bagale's Tip

Many current instance types already have simplified automatic recovery turned on by default for system check failures. A recover alarm is still useful: it also sends you an email and works the same on every instance type that supports recovery.

3. Lab 1: auto-recover and auto-reboot alarms

Use one t3.micro (Amazon Linux 2023) with only EBS storage. Why EBS only: recover is not supported for instances with instance-store volumes.

Part A: recover on system check

  1. CloudWatch → Alarms → Create alarm → Select metric → EC2 → Per-Instance Metrics → your ID → StatusCheckFailed_System.
  2. Statistic Maximum. Period 1 minute. Why: status checks are sent every minute even with basic monitoring.
  3. Condition Greater/Equal 1. Datapoints 2 out of 2. Why 2: avoids reacting to one odd minute.
  4. Next → Add EC2 action → In alarm → Recover this instance. Add the SNS topic ops-alerts too.
  5. Name web1-system-recover → Create.

Part B: reboot on instance check

  1. Create alarm → metric StatusCheckFailed_Instance, Maximum, 1 minute.
  2. Condition >= 1, datapoints 3 out of 3. Why 3: AWS advises a different evaluation length from the recover alarm, so both do not fire at the same moment.
  3. EC2 action: Reboot this instance. Add SNS. Name web1-instance-reboot.
aws cloudwatch put-metric-alarm --alarm-name web1-system-recover \
  --namespace AWS/EC2 --metric-name StatusCheckFailed_System \
  --dimensions Name=InstanceId,Value=i-0abc1234567890def \
  --statistic Maximum --period 60 --evaluation-periods 2 --datapoints-to-alarm 2 \
  --threshold 1 --comparison-operator GreaterThanOrEqualToThreshold \
  --alarm-actions arn:aws:automate:ap-south-1:ec2:recover arn:aws:sns:ap-south-1:111122223333:ops-alerts

aws cloudwatch put-metric-alarm --alarm-name web1-instance-reboot \
  --namespace AWS/EC2 --metric-name StatusCheckFailed_Instance \
  --dimensions Name=InstanceId,Value=i-0abc1234567890def \
  --statistic Maximum --period 60 --evaluation-periods 3 --datapoints-to-alarm 3 \
  --threshold 1 --comparison-operator GreaterThanOrEqualToThreshold \
  --alarm-actions arn:aws:automate:ap-south-1:ec2:reboot arn:aws:sns:ap-south-1:111122223333:ops-alerts

Part C: test safely

  1. You cannot break AWS hardware, so test the action with a forced state:
aws cloudwatch set-alarm-state --alarm-name web1-instance-reboot --state-value ALARM --state-reason "lab test"
  1. Verify: an ALARM email arrives, and uptime on the server shows a fresh boot (a few minutes). The next real check moves the alarm back to OK.
  2. To see a real instance-check failure, on a throwaway instance run sudo systemctl stop sshd; sudo ip link set ens5 down. The instance check fails in a few minutes and the reboot alarm brings it back (the change was not saved, so the network comes up after boot).

4. EBS volume status checks

Why do we need this?

A disk can become unsafe to use: AWS may detect data that could be inconsistent. Writing to it then can damage data.

What is it?

Every EBS volume has a volume status: ok, warning, impaired or insufficient-data. This is a status check you see in EC2 → Volumes → Status checks, not a normal CloudWatch metric. When AWS sees possible inconsistency it can turn off I/O (the "auto-enable I/O" setting decides if I/O comes back on by itself).

aws ec2 describe-volume-status --volume-ids vol-0abc1234567890def \
  --query 'VolumeStatuses[0].VolumeStatus'
# expected: {"Status": "ok", "Details": [{"Name": "io-enabled","Status":"passed"}, ...]}

To alarm on the disk from the instance side, use StatusCheckFailed_AttachedEBS (AWS/EC2). AWS recommends Maximum, period 60 s, 10 out of 10. To be told about volume-status events, create an EventBridge rule on EBS Volume Notification events and send them to SNS.

5. BurstBalance and VolumeQueueLength

Why do we need this?

A slow disk makes every app slow, but CPU stays low, so CPU alarms are silent. These two metrics show disk pain directly.

What is it?

Metric (AWS/EBS)Plain meaningApplies toAlarm idea
BurstBalance% of burst credits left. Like mobile data left in your packgp2, st1, sc1 (not gp3, which has no burst bucket)Average < 20 for 15 min
VolumeQueueLengthRequests waiting for the disk. Like a queue at a bank counterAll typesAverage > 10 for 15 min (tune to your app)
VolumeIdleTimeSeconds with no I/OAllHelps find unused disks
VolumeReadOps / VolumeWriteOpsRead and write operationsAllDivide by period seconds to get IOPS

Worked example: a 100 GiB gp2 volume has a baseline of 300 IOPS and can burst to 3,000. A MySQL import runs at 3,000 IOPS. BurstBalance falls 100 → 60 → 20 → 0. At 0, the disk drops to 300 IOPS, the queue grows to 40, and queries that took 50 ms take 2 s. An alarm at 20% gives you time to act. The fix: change the volume to gp3 (baseline 3,000 IOPS for any size) with Modify volume, no downtime.

Lab 2: EBS alarms

  1. EC2 → Volumes → select the root volume of your instance → copy the Volume ID and note the type (gp2 or gp3).
  2. CloudWatch → Create alarm → EBS → Per-Volume Metrics → your volume → VolumeQueueLength.
  3. Average, 5 minutes, Greater than 10, 3 out of 3. SNS ops-alerts. Name web1-disk-queue.
  4. If the volume is gp2: another alarm on BurstBalance, Average, 5 minutes, Lower than 20, 3 out of 3. Name web1-burst-low.
  5. Attached-EBS alarm with the CLI:
aws cloudwatch put-metric-alarm --alarm-name web1-attached-ebs \
  --namespace AWS/EC2 --metric-name StatusCheckFailed_AttachedEBS \
  --dimensions Name=InstanceId,Value=i-0abc1234567890def \
  --statistic Maximum --period 60 --evaluation-periods 10 --datapoints-to-alarm 10 \
  --threshold 1 --comparison-operator GreaterThanOrEqualToThreshold \
  --alarm-actions arn:aws:sns:ap-south-1:111122223333:ops-alerts
  1. Make the disk busy to watch the queue:
sudo dnf install -y fio
sudo fio --name=q --filename=/tmp/fio.bin --size=1G --rw=randwrite --bs=4k --iodepth=64 --ioengine=libaio --direct=1 --runtime=600 --time_based
rm -f /tmp/fio.bin
  1. Verify: in the volume Monitoring tab, Average queue length rises; with gp2 the burst balance falls. The queue alarm goes to ALARM.
  2. Cleanup: delete web1-system-recover, web1-instance-reboot, web1-disk-queue, web1-burst-low, web1-attached-ebs; stop or terminate the instance.

6. Health alarms per stack

ServerMust-have health alarms
nginx / Apache webSystem recover, instance reboot
MySQL / PostgreSQL on EC2Recover, attached EBS, VolumeQueueLength, BurstBalance (gp2)
Java Spring / .NET app serverInstance reboot (memory hangs), plus agent memory alarm
Node.js / Python / Go API in Auto ScalingNo reboot alarm; the group replaces bad instances (EC2 or ELB health checks)

7. Interview questions

Q. System vs instance status check?

System = AWS host problem, fix with recover. Instance = your OS problem, fix with reboot or by repairing the OS.

Q. Why is BurstBalance empty on a gp3 volume?

gp3 has no burst bucket. It gives a fixed baseline (3,000 IOPS, 125 MiB/s) that you can raise.

Q. Which statistic for status check alarms?

Maximum, because the value is 0 or 1 and one failure must count.

Try at home

  1. Add recover and reboot alarms to one of your lab servers and test the reboot with set-alarm-state.
  2. Run the fio test on a small gp2 volume and watch BurstBalance fall. Then modify it to gp3 and watch the queue drop.

In short

  1. StatusCheckFailed_System → recover; StatusCheckFailed_Instance → reboot.
  2. StatusCheckFailed_AttachedEBS watches disks from the instance (Nitro only); recover is not supported for it.
  3. Volume status (ok/warning/impaired) is a check, seen with describe-volume-status.
  4. BurstBalance (gp2/st1/sc1) and VolumeQueueLength show slow disks that CPU alarms miss.

Practice Tasks

About this scenario

Patil Dairy is a dairy business in Kolhapur. Sunita Patil looks after its IT and cloud work. They count money in INR and run their AWS resources in the ap-south-1 Region. In the tasks below you do real jobs for them using what this lesson teaches. All names, account IDs, IP addresses and numbers are made up for practice.

0 / 11

Easy Create an SNS topic

Why: A topic is a channel: publish once, every subscriber gets it.

What to do: Create topic patildairy-alerts.

How:
  1. Read the task and decide which AWS service it is about.
  2. Write aws, then the service name, then the operation (the action word).
  3. Add each needed flag (--name) followed by its value from the task.
  4. Flags can be in any order. Click Check answer.

Easy List alarms that are firing

Why: In an incident, first see which alarms are in ALARM state.

What to do: Describe only the alarms whose state is ALARM.

How:
  1. Read the task and decide which AWS service it is about.
  2. Write aws, then the service name, then the operation (the action word).
  3. Add each needed flag (--name) followed by its value from the task.
  4. Flags can be in any order. Click Check answer.

Easy List metrics in a namespace

Why: See which metrics AWS already collects for a service.

What to do: List the metrics in the AWS/EC2 namespace.

How:
  1. Read the task and decide which AWS service it is about.
  2. Write aws, then the service name, then the operation (the action word).
  3. Add each needed flag (--name) followed by its value from the task.
  4. Flags can be in any order. Click Check answer.

Easy Publish to one topic

Why: An alerting app only needs to publish.

What to do: Allow sns:Publish on arn:aws:sns:ap-south-1:100444365147:patildairy-alerts only.

How:
  1. Start with { "Version": "2012-10-17", "Statement": [ ... ] }.
  2. In each statement write Effect, Action and Resource.
  3. Give only what the task needs (least privilege).
  4. Use double quotes and commas correctly. Click Check answer.

Medium Subscribe an email

Why: Email subscribers must click the confirm link before they receive messages.

What to do: Subscribe ops@patildairy.in by email to arn:aws:sns:ap-south-1:100444365147:patildairy-alerts.

How:
  1. Read the task and decide which AWS service it is about.
  2. Write aws, then the service name, then the operation (the action word).
  3. Add each needed flag (--name) followed by its value from the task.
  4. Flags can be in any order. Click Check answer.

Medium Publish a custom metric

Why: Custom metrics let you graph and alarm on business numbers, like orders per minute.

What to do: Publish metric OrdersPlaced with value 6 in namespace PatilDairy/Shop.

How:
  1. Read the task and decide which AWS service it is about.
  2. Write aws, then the service name, then the operation (the action word).
  3. Add each needed flag (--name) followed by its value from the task.
  4. Flags can be in any order. Click Check answer.

Medium Check target health

Why: If targets are unhealthy the site shows 502/503 errors.

What to do: Show the health of the targets in arn:aws:elasticloadbalancing:ap-south-1:100444365147:targetgroup/patildairy-tg/6d0ecf831eec9f09.

How:
  1. Read the task and decide which AWS service it is about.
  2. Write aws, then the service name, then the operation (the action word).
  3. Add each needed flag (--name) followed by its value from the task.
  4. Flags can be in any order. Click Check answer.

Medium Check instance status checks

Why: System and instance status checks tell you if AWS hardware or your OS has a problem.

What to do: Show the status checks of instance i-0b415a34440011a2b.

How:
  1. Read the task and decide which AWS service it is about.
  2. Write aws, then the service name, then the operation (the action word).
  3. Add each needed flag (--name) followed by its value from the task.
  4. Flags can be in any order. Click Check answer.

Medium Kubernetes LoadBalancer Service

Why: A Service of type LoadBalancer gets an AWS load balancer.

What to do: Write a Service of type LoadBalancer selecting app: web, port 80 to targetPort 8080.

How:
  1. Start from the top-level keys the task names.
  2. Indent child keys with 2 spaces (no tabs).
  3. Fill in each property with the value from the task.
  4. Click Check answer. Key order does not matter.

Hard Create a CPU alarm

Why: An alarm watches a metric and notifies you before users notice a problem.

What to do: Create alarm patildairy-cpu-high: AWS/EC2 CPUUtilization, Average over 300 seconds, 1 evaluation period, GreaterThanThreshold 80, for InstanceId=i-0b415a34440011a2b, notify arn:aws:sns:ap-south-1:100444365147:patildairy-alerts.

How:
  1. Read the task and decide which AWS service it is about.
  2. Write aws, then the service name, then the operation (the action word).
  3. Add each needed flag (--name) followed by its value from the task.
  4. Flags can be in any order. Click Check answer.

Hard Auto-recover an instance with an alarm

Why: A recover action moves the instance to healthy hardware when the system check fails.

What to do: Create alarm patildairy-recover on AWS/EC2 StatusCheckFailed_System, Maximum over 60 s, 2 periods, GreaterThanOrEqualToThreshold 1, InstanceId=i-0b415a34440011a2b, action arn:aws:automate:ap-south-1:ec2:recover.

How:
  1. Read the task and decide which AWS service it is about.
  2. Write aws, then the service name, then the operation (the action word).
  3. Add each needed flag (--name) followed by its value from the task.
  4. Flags can be in any order. Click Check answer.

Revision, comparison and interview cards

Revise this lesson in a few minutes. Save the cards on your phone or download them as PNG files. The QR code on each card opens this lesson.

Revision card: EC2 status checks. A server can show "running" and still be frozen. CPU alarms cannot see that. AWS tests each instance every minute. Each check is 0 (pass) or 1 (fail). Alarm: statistic Maximum, period 1 minute, threshold >= 1. Node.js server runs out of memory → StatusCheckFailed_Instance = 1 → reboot alarm fires.
Revision card: EC2 status checks · Download PNG
Revision card: Attached EBS status check. If a disk cannot read or write, the app hangs while CPU looks fine. StatusCheckFailed_AttachedEBS is 1 when an attached EBS volume cannot do I/O. Nitro instances only (t3, m5, c5…). Alarm: Maximum, 60 s, 10 out of 10, >= 1, notify SNS. Recover is not supported for this metric. Fix: stop then start the instance to move it to a new host, or replace the volume.
Revision card: Attached EBS status check · Download PNG
Revision card: EBS BurstBalance. A small gp2 disk can become very slow after heavy use, with no CPU warning. BurstBalance = % of burst credits left on gp2, st1 or sc1, like mobile data left in your pack. gp3 has none. Alarm: AWS/EBS BurstBalance, Average, 5 min, lower than 20, 3 of 3. 100 GiB gp2: burst 3,000 IOPS, baseline 300. At 0% it drops to 300. Fix: modify to gp3.
Revision card: EBS BurstBalance · Download PNG
Revision card: EBS VolumeQueueLength. Slow disks make every query slow, but CPU stays low, so CPU alarms stay silent. VolumeQueueLength = requests waiting for the disk, like a queue at a bank counter. Alarm: AWS/EBS VolumeQueueLength, Average, 5 min, greater than 10, 3 of 3. Tune to your app. MySQL import: queue grows from 1 to 40, queries go from 50 ms to 2 s.
Revision card: EBS VolumeQueueLength · Download PNG
Comparison: StatusCheckFailed_System vs StatusCheckFailed_Instance. StatusCheckFailed_System: Check of the AWS host: power, network, hardware. StatusCheckFailed_Instance: Check of your OS: does it answer network tests?
Comparison: StatusCheckFailed_System vs StatusCheckFailed_Instance · Download PNG
Comparison: gp2 volume vs gp3 volume. gp2 volume: General Purpose SSD whose speed grows with size. gp3 volume: General Purpose SSD with a fixed baseline.
Comparison: gp2 volume vs gp3 volume · Download PNG
Comparison: EBS volume status vs StatusCheckFailed_AttachedEBS. EBS volume status: Health state of one volume: ok, warning, impaired. StatusCheckFailed_AttachedEBS: EC2 metric: 1 when an attached volume cannot do I/O.
Comparison: EBS volume status vs StatusCheckFailed_AttachedEBS · Download PNG
Comparison: VolumeQueueLength vs BurstBalance. VolumeQueueLength: EBS metric: requests waiting for the disk. BurstBalance: EBS metric: % of burst credits left.
Comparison: VolumeQueueLength vs BurstBalance · Download PNG
Interview card: System status check vs instance status check: what is the difference?. System = AWS host (power, network, hardware). Instance = your OS (memory, kernel, network config). The fix is different: AWS hardware needs a move, your OS needs a restart or repair. StatusCheckFailed_System → recover action. StatusCheckFailed_Instance → reboot action.
Interview card: System status check vs instance status check: what is the difference? · Download PNG
Interview card: Which statistic do you use for a status check alarm, and why?. Maximum, with threshold greater than or equal to 1. The metric is 0 or 1. Average could hide one failed minute. Period 60 s, 2 out of 2 for recover; 3 out of 3 for reboot.
Interview card: Which statistic do you use for a status check alarm, and why? · Download PNG
Interview card: Why is BurstBalance empty for a gp3 volume?. gp3 has no burst bucket. It gives a fixed baseline you can raise. No credits means no sudden slowdown after heavy use. gp3 baseline: 3,000 IOPS and 125 MiB/s at any size. gp2 100 GiB: 300 IOPS baseline.
Interview card: Why is BurstBalance empty for a gp3 volume? · Download PNG
Interview card: The app is slow but CPU is low. Which EBS metrics do you check?. VolumeQueueLength (requests waiting) and BurstBalance (credits left on gp2). A disk that cannot keep up makes every request wait, while CPU sits idle. Queue 40 and BurstBalance 0% on gp2 → change to gp3 with Modify volume, no downtime.
Interview card: The app is slow but CPU is low. Which EBS metrics do you check? · Download PNG

More cards: Ravi Sir's Cards.