Agentic AI Engineering with Python: Live Course
AWSMonitoring, CLI & IaC

Monitoring & Alerts - CloudWatch & SNS

You can't fix what you can't see, and you can't react to what nobody tells you about. CloudWatch is the eyes - it collects metrics and logs from every AWS service. SNS is the mouth - it delivers the alert to your inbox or phone. Together they turn "the server fell over at 2 a.m. and we found out at 9" into "my phone buzzed the moment CPU spiked."

The two services, two jobs

   CloudWatch  ── watches: metrics, logs, alarms
        │  alarm fires (e.g. CPU > 80%)

   SNS         ── notifies: email, SMS, Lambda, queues


   You (or an automated response)

CloudWatch observes and decides when something is wrong. SNS spreads the word to whoever (or whatever) needs to act.

CloudWatch: the observability service

CloudWatch collects four kinds of things:

FeatureWhat it does
MetricsNumeric time-series data - CPU, network, request count, etc.
LogsText logs from apps and services, searchable and retained
AlarmsWatch a metric and trigger an action when it crosses a threshold
DashboardsCustom visual panels combining metrics into one view

Metrics

A metric is a measurement over time - CPUUtilization of an instance, RequestCount on a load balancer, FreeStorageSpace on an RDS database. AWS services publish many metrics automatically, for free, at a basic resolution.

   CPUUtilization (i-abc123)
   100% ┤            ╭─╮
    50% ┤      ╭─────╯ ╰──────
     0% ┤──────╯
        └────────────────────── time

A subtlety that surprises people: standard EC2 metrics don't include memory or disk usage. AWS sees CPU, network, and disk I/O from outside the instance, but RAM and disk-space-used live inside the OS. To monitor those, install the CloudWatch agent on the instance - it pushes memory and disk metrics up as custom metrics.

Alarms

An alarm watches one metric and changes state when it breaches a threshold for a set time:

   "If average CPUUtilization > 80% for 5 minutes → ALARM"

        ├─ send an SNS notification (tell a human)
        ├─ trigger Auto Scaling (add an instance)
        └─ stop/reboot the instance (automated remediation)

Alarms have three states: OK, ALARM, and INSUFFICIENT_DATA. The action you attach is what makes an alarm useful - notify, scale, or remediate.

Logs

CloudWatch Logs centralizes text logs. Your app (or the CloudWatch agent) ships log lines to a log group, where you can search them, set retention, and create metric filters - e.g. "count how many times ERROR appears, and alarm if it spikes."

SNS: the notification fan-out

SNS - Simple Notification Service - is publish/subscribe messaging. A message published to a topic is delivered to every subscriber of that topic at once.

   CloudWatch alarm ──publish──► SNS Topic "ops-alerts"
                                      │ fan-out to all subscribers
                          ┌───────────┼───────────┐
                          ▼           ▼           ▼
                       Email        SMS        Lambda
                    (you)       (on-call)   (auto-fix)

Subscribers can be email, SMS, HTTP(S) endpoints, Lambda functions, SQS queues, and more. One alarm can therefore email the team, text the on-call engineer, and trigger an automated response - all from a single published message.

The decoupling is the point. CloudWatch doesn't need to know who gets notified or how - it just publishes to a topic. You manage the recipients by editing the topic's subscriptions. Add a new team member to the alerts? Subscribe their email to the topic; nothing about the alarm changes.

The classic setup: a CPU alarm that emails you

The canonical first monitoring task - get notified when an instance is in trouble:

Create an SNS topic

SNS → Create topic (Standard), name it ec2-alerts.

Subscribe your email

Add an email subscription to the topic, then confirm it via the link AWS sends. (Unconfirmed subscriptions get nothing.)

Create a CloudWatch alarm

CloudWatch → Alarms → Create. Pick the instance's CPUUtilization metric, set the condition (> 80% for 5 minutes), and set the action to notify the ec2-alerts SNS topic.

Test it

Stress the instance's CPU. When it crosses 80%, the alarm flips to ALARM, publishes to SNS, and your inbox gets the alert.

The one you should set up first: the billing alarm

Before any CPU alarm, the most valuable alarm on a learning account watches your spend:

   CloudWatch billing alarm: "EstimatedCharges > $10" ──► SNS ──► email

This is the safety net mentioned back in account setup - now you know how it's built. A billing alarm catches a forgotten NAT Gateway, a stray RDS instance, or an Auto Scaling group you never tore down, while the bill is small. Set the threshold low enough to make you nervous ($5-$10 for learning). It's the single cheapest insurance policy on AWS.

Where monitoring connects to everything else

CloudWatch isn't a standalone topic - it's the nervous system tying the course together:

  • Auto Scaling scales on CloudWatch metrics (CPU, request count).
  • RDS, S3, ELB all publish metrics you can alarm on.
  • Logs from your EC2/Beanstalk/ECS apps land in CloudWatch Logs.
  • Alarms → SNS notify you, and alarms → automated actions remediate.

The mental model to carry forward: measure with CloudWatch, decide with alarms, notify or act through SNS. Almost every "how do I know if X is healthy / how do I get told when it isn't" question on AWS routes through these two services.

Next: driving AWS from the terminal instead of the console - the AWS CLI.

How is this guide?

Last updated on