AWS Builder Center
5 Automated CloudWatch Dashboards Every Operations Team Needs

5 Automated CloudWatch Dashboards Every Operations Team Needs

Build five automated AWS CloudWatch dashboards for infrastructure, applications, Lambda, RDS, and incident response using IaC.

5 Automated CloudWatch Dashboards Every Operations Team Needs

Your monitoring problem is probably not a lack of metrics.
It is a lack of answers.
AWS can give an operations team thousands of data points. CPU utilization. Lambda errors. Target response time. Database connections. Disk queues. Throttles. Logs.
Then production breaks, and someone spends the next ten minutes opening tabs.
That is not observability.
That is archaeology.
A useful CloudWatch dashboard should shorten the distance between “something is wrong” and “here is where to look.”
And if that dashboard matters in production, it should not depend on somebody remembering how they built it six months ago.
It should be code.
Observability flow diagram showing EC2, ALB, Lambda, and RDS feeding metrics into CloudWatch, then into a dashboard, alarm, and operator decision.
A simplified CloudWatch observability flow showing how AWS service metrics move from EC2, ALB, Lambda, and RDS into dashboards and alarms that help operators make faster decisions.
This article covers five CloudWatch dashboards worth automating:
  1. Infrastructure Health
  2. Application Performance
  3. Serverless Operations
  4. Database Health
  5. Incident Command
Each one follows the same pattern: what to visualize, how to automate it, what to alarm on, and what the graphs are trying to tell you.

Before You Build: Three Things to Get Right

1. Treat dashboards as infrastructure

CloudWatch dashboards can be created with CloudFormation, Terraform, CDK, the AWS CLI, APIs, or SDKs.
For deployment roles, cloudwatch:PutDashboard is the key permission for creating or updating dashboards. Creating alarms requires permissions such as cloudwatch:PutMetricAlarm; publishing your own custom metrics requires cloudwatch:PutMetricData.
Keep the dashboard definition in the same repository as the service or infrastructure it monitors.
Your ideal workflow is:
1
2
3
4
5
6
7
Git commit
↓
CI/CD
↓
Infrastructure
+ Dashboard
+ Alarms
Observability should ship with the system.

2. Use a naming convention

There is an easy CloudWatch detail to miss: dashboards are global within an AWS account, not Region-specific. A dashboard name therefore needs enough context to avoid collisions.
A useful convention is:
1
<environment>-<region>-<service>-<purpose>
For example:
1
2
3
prod-us-east-1-checkout-application
prod-us-east-1-checkout-database
staging-eu-west-1-orders-serverless
For organizations with many AWS accounts, consider a central monitoring account. CloudWatch supports cross-account observability and dashboards that combine metrics and logs from multiple accounts and Regions.

3. Know which metrics exist by default

EC2 gives you useful infrastructure metrics out of the box, but guest operating-system memory and filesystem usage are not standard EC2 metrics.
To collect values such as memory utilization and filesystem disk usage, install and configure the CloudWatch agent. Those additional metrics are commonly published under the CWAgent namespace. AWS's EC2 health guidance includes agent configuration for memory, disk, swap, disk I/O, and CPU data.
That distinction matters. A dashboard that promises memory graphs without explaining the agent is not deployable documentation.

1. Infrastructure Health Dashboard

The infrastructure dashboard answers the first question during an incident:
Is the platform itself under pressure?
For EC2-heavy systems, start with:
  • CPUUtilization
  • EC2 status checks
  • Network activity
  • EBS read/write activity
  • EBS queue pressure
  • Auto Scaling capacity
  • Healthy/unhealthy load-balancer targets
  • Memory and filesystem usage through the CloudWatch agent
Infrastructure health dashboard mockup showing CPU utilization, memory, EBS queue, network throughput, healthy targets, and Auto Scaling capacity.
Infrastructure health dashboard mockup showing CPU utilization, memory, EBS queue, network throughput, healthy targets, and Auto Scaling capacity.
AWS recommends several EBS metrics for operational visibility, including read/write operations, queue length, throughput percentage, and burst balance.
The goal is not to create a wall of graphs.
It is to reveal saturation.

Automate it

Here is a small Terraform example that puts an EC2 metric and an agent-provided memory metric on the same dashboard:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
resource "aws_cloudwatch_dashboard" "infra" {
dashboard_name = "${var.environment}-${var.region}-infra-health"

dashboard_body = jsonencode({
widgets = [
{
type = "metric"
x = 0
y = 0
width = 12
height = 6

properties = {
title = "EC2 CPU Utilization"
region = var.region
period = 60
metrics = [
[
"AWS/EC2",
"CPUUtilization",
"InstanceId",
var.instance_id
]
]
stat = "Average"
}
},
{
type = "metric"
x = 12
y = 0
width = 12
height = 6

properties = {
title = "Host Memory"
region = var.region
period = 60
metrics = [
[
"CWAgent",
"mem_used_percent",
"InstanceId",
var.instance_id
]
]
stat = "Average"
}
}
]
})
}
Terraform's aws_cloudwatch_dashboard resource accepts the dashboard body as JSON, which makes the same underlying widget model usable whether you prefer Terraform or native AWS tooling.

Alarm starting points

These are examples to baseline against your own workloads:
  • EC2 status check failure: >= 1
  • Sustained CPU: >80% for 10 minutes
  • Host memory: >85% for 10 minutes
  • Healthy target count: alert when it falls below the capacity needed to serve normal traffic
Do not cargo-cult the numbers. A batch worker running at 95% CPU may be healthy. A latency-sensitive API at the same utilization may be minutes away from pain.

What to look for

CPU up + network up + request volume up
Likely traffic-driven pressure. Check whether scaling is responding quickly enough.
Memory up while CPU stays normal
Look for memory leaks, cache growth, JVM or runtime pressure, or a workload whose bottleneck is not CPU.
EBS queue pressure + application latency up
Storage may be the constraint even though EC2 CPU looks healthy.
The lesson: resource pressure is useful only when correlated with customer-facing symptoms.

2. Application Performance Dashboard

Infrastructure can be green while users are having a terrible day.
Your application dashboard should answer:
What is the customer experiencing?
For an Application Load Balancer, useful CloudWatch metrics include:
  • RequestCount
  • TargetResponseTime
  • HTTPCode_Target_5XX_Count
  • HTTPCode_ELB_5XX_Count
  • HealthyHostCount
  • UnHealthyHostCount
AWS documents Sum as the meaningful statistic for request and target HTTP response-code counts, while HealthyHostCount is typically examined with statistics such as Average, Minimum, or Maximum.
One graph tells you what happened.
Several related graphs tell you why.

Show error rate, not just error count

Application performance dashboard mockup showing request volume, P95 latency, 5XX error rate, and healthy targets, with a visual flow indicating traffic increases lead to higher latency and more 5XX errors.
A simplified application performance dashboard showing request volume, P95 latency, 5XX error rate, and target health so operators can quickly see how rising traffic can lead to slower responses and more application errors.
“500 errors” means almost nothing without traffic context.
500 errors from 1,000 requests is a crisis.
500 errors from 50 million requests is a different conversation.
CloudWatch metric math lets you derive a time series from multiple metrics. AWS even uses dividing errors by invocations as an example of creating an error-rate metric.
For an ALB, a widget can calculate target 5XX percentage like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
{
"type": "metric",
"width": 12,
"height": 6,
"properties": {
"title": "Target 5XX Error Rate",
"region": "us-east-1",
"metrics": [
[
"AWS/ApplicationELB",
"HTTPCode_Target_5XX_Count",
"LoadBalancer",
"app/prod-alb/abc123",
{"id": "errors", "stat": "Sum", "visible": false}
],
[
"AWS/ApplicationELB",
"RequestCount",
"LoadBalancer",
"app/prod-alb/abc123",
{"id": "requests", "stat": "Sum", "visible": false}
],
[
{
"expression": "IF(requests>0,100*errors/requests,0)",
"label": "5XX %",
"id": "errorRate"
}
]
],
"period": 60
}
}
Now your dashboard is showing impact, not just activity.

Alarm starting points

Examples:
  • Target 5XX rate: >1% for 5 minutes
  • P95 latency: alarm relative to your service SLO
  • Unhealthy targets: >0 for critical services, or below your minimum safe capacity
  • Sudden request-rate change: compare with historical baseline or anomaly detection
The SLO is more important than a generic threshold.
“Latency is high” is vague.
“Checkout P95 breached the 750 ms objective for five minutes” is operational.

What to look for

Request volume up + latency up + healthy hosts stable
Your targets may simply be saturated.
5XX rate up + traffic flat
Suspect a code change, dependency failure, configuration problem, or bad deployment.
Healthy hosts down + ALB 5XX up
Start with target health and application startup/readiness failures.
A good application dashboard does not ask, “Which graph looks scary?”
It asks, “What changed at the same time?”

3. Serverless Operations Dashboard

Serverless removes servers from your to-do list.
It does not remove operations.
For Lambda, start with:
  • Invocations
  • Errors
  • Duration
  • Throttles
  • ConcurrentExecutions
AWS recommends viewing invocation metrics such as errors and throttles with Sum, while concurrency metrics such as ConcurrentExecutions should be examined with Max. Lambda also supports percentile statistics such as p95 for duration analysis.
Lambda operations dashboard mockup showing invocations versus errors, duration with p95 and average response time, throttles, and concurrent executions.
A simplified Lambda operations dashboard that helps operators track invocations, errors, response duration, throttling events, and concurrency trends in one view.

Automate it with CloudFormation

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
ServerlessDashboard:
Type: AWS::CloudWatch::Dashboard
Properties:
DashboardName: !Sub '${Environment}-${AWS::Region}-serverless'
DashboardBody: !Sub |
{
"widgets": [
{
"type": "metric",
"width": 12,
"height": 6,
"properties": {
"title": "Invocations vs Errors",
"region": "${AWS::Region}",
"period": 60,
"metrics": [
["AWS/Lambda","Invocations","FunctionName","${FunctionName}",
{"stat":"Sum"}],
["AWS/Lambda","Errors","FunctionName","${FunctionName}",
{"stat":"Sum"}]
]
}
},
{
"type": "metric",
"width": 12,
"height": 6,
"properties": {
"title": "Duration",
"region": "${AWS::Region}",
"period": 60,
"metrics": [
["AWS/Lambda","Duration","FunctionName","${FunctionName}",
{"stat":"p95"}],
["AWS/Lambda","Duration","FunctionName","${FunctionName}",
{"stat":"Average"}]
]
}
}
]
}

Ship an alarm beside it

If the dashboard lives in code but the alarms live in somebody's memory, the system is only half automated.
Here is a simple throttling alarm:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
LambdaThrottleAlarm:
Type: AWS::CloudWatch::Alarm
Properties:
AlarmName: !Sub '${Environment}-${FunctionName}-throttles'
Namespace: AWS/Lambda
MetricName: Throttles
Dimensions:
- Name: FunctionName
Value: !Ref FunctionName
Statistic: Sum
Period: 60
EvaluationPeriods: 3
DatapointsToAlarm: 2
Threshold: 0
ComparisonOperator: GreaterThanThreshold
TreatMissingData: notBreaching
CloudFormation's AWS::CloudWatch::Alarm resource also supports alarms based on metric-math expressions, which is useful when you want to alarm on a Lambda error rate instead of a raw error count.

Alarm starting points

  • Throttles: >0 across 2 of 3 minutes for synchronous critical functions
  • Error rate: >1% as an initial investigation threshold
  • P95 duration: relative to timeout and latency SLO
  • Concurrency: alert before consistently approaching reserved or regional capacity

What to look for

Invocations up + concurrency up + throttles up
Capacity is probably the first place to investigate.
Duration up + errors flat
The function is becoming slower without necessarily failing. Inspect dependencies, cold starts, downstream latency, and code paths.
Errors up while invocations stay flat
That often points toward a deployment, dependency, permissions, or configuration change rather than traffic growth.
The important principle:
Serverless scales infrastructure automatically. It does not scale your understanding automatically.

4. Database Health Dashboard

Applications often complain before databases scream.
By the time users notice slowness, the database may already have been accumulating pressure for several minutes.
For standard RDS DB instances, useful CloudWatch metrics include:
  • CPUUtilization
  • DatabaseConnections
  • FreeStorageSpace
  • FreeableMemory
  • ReadIOPS
  • WriteIOPS
  • ReadLatency
  • WriteLatency
  • DiskQueueDepth
AWS publishes these metrics under AWS/RDS; DBInstanceIdentifier is the dimension used to isolate a specific DB instance.
RDS health dashboard mockup showing CPU, database connections, read latency, write latency, IOPS, and free storage, with a diagnostic note linking rising connections and latency to possible pool, lock, or query issues.
A simplified RDS health dashboard that helps operators monitor CPU, connections, latency, IOPS, and storage so they can identify database constraints before they become application outages.

Automate it

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
{
"type": "metric",
"width": 24,
"height": 6,
"properties": {
"title": "RDS Pressure",
"region": "us-east-1",
"metrics": [
[
"AWS/RDS",
"CPUUtilization",
"DBInstanceIdentifier",
"prod-orders-db",
{"stat": "Average"}
],
[
"AWS/RDS",
"DatabaseConnections",
"DBInstanceIdentifier",
"prod-orders-db",
{"stat": "Average", "yAxis": "right"}
]
],
"period": 60
}
}
Do not stop with one graph. Pair connections and CPU with latency, free storage, IOPS, and queue behavior.

RDS is not Aurora with a different logo

Aurora adds cluster-level behavior and metrics that differ from traditional RDS instances. AWS documents Aurora metrics at both cluster and instance level, including engine-specific and cluster-specific measurements.
For deeper diagnosis, use CloudWatch Database Insights and, where appropriate, Enhanced Monitoring. Enhanced Monitoring exposes operating-system detail through CloudWatch Logs, while Database Insights adds deeper database-load and query-oriented analysis.
Your dashboard should therefore have two layers:
1
2
3
4
5
Shared RDS baseline
+
Engine / Aurora-specific metrics
+
Deep-dive database tooling
Do not force every database into one universal template.

Alarm starting points

Examples:
  • CPU: sustained >80%
  • Free storage: alert well before exhaustion, based on growth rate and recovery time
  • Connection count: alert relative to your configured safe maximum
  • Read/write latency: baseline against your workload
AWS notes that read latencies above roughly 20 ms can merit investigation, but also explicitly says the right threshold depends on your application.
That is exactly how thresholds should be treated: evidence, not commandments.

What to look for

Connections up + CPU flat + latency up
Investigate connection-pool exhaustion, lock contention, blocked transactions, or inefficient queries.
CPU up + latency up + connections stable
Look for expensive SQL, changed execution plans, or a workload shift.
IOPS near provisioned capacity + read/write latency up
Storage performance may be the bottleneck. AWS recommends considering both IOPS and throughput rather than using IOPS alone.
A database dashboard should show you the constraint forming before users call it “the website is slow.”

5. Incident Command Dashboard

The first four dashboards explain individual layers.
The fifth exists for the moment nobody wants.
Production is failing.
Incident command dashboard mockup showing active alarms, error rate, P95 latency, traffic, healthy hosts, database and Lambda signals, recent errors, last deployment time, and a runbook link.
A simplified incident command dashboard that brings alarms, service health, recent errors, deployment timing, and next-step runbook access into one view so operators can investigate faster from a single screen.
Your incident dashboard should answer:
  • What is alarming?
  • What are users experiencing?
  • Which layer changed?
  • What happened recently?
  • Where is the runbook?
CloudWatch gives you more than metric graphs. Dashboard bodies support metric, alarm, log, and text widgets, among other types. Alarm status widgets can surface alarms by state, log widgets can run CloudWatch Logs Insights queries, and text widgets can hold Markdown such as runbook links.
Use them.

Automate the command center

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
{
"widgets": [
{
"type": "alarm",
"width": 24,
"height": 4,
"properties": {
"title": "Active Production Alarms",
"alarms": [
"arn:aws:cloudwatch:us-east-1:123456789012:alarm:api-errors",
"arn:aws:cloudwatch:us-east-1:123456789012:alarm:db-latency"
],
"states": ["ALARM", "INSUFFICIENT_DATA"],
"sortBy": "stateUpdatedTimestamp"
}
},
{
"type": "log",
"width": 18,
"height": 6,
"properties": {
"region": "us-east-1",
"title": "Recent Application Errors",
"query": "SOURCE '/aws/lambda/orders-api' | fields @timestamp, @message\n| filter @message like /ERROR/\n| sort @timestamp desc\n| limit 50",
"view": "table"
}
},
{
"type": "text",
"width": 6,
"height": 6,
"properties": {
"markdown": "## Incident Links\n- [Runbook](https://example.com/runbook)\n- [Status Page](https://example.com/status)\n- Escalation: Platform On-Call"
}
}
]
}
AWS documents both the SOURCE syntax for programmatic Logs Insights queries and the dashboard log-widget format.
The URLs above are placeholders. Replace them with your actual operational links.

What about deployment markers?

CloudWatch does not magically know which vertical line on your graph represents a deployment.
You need a mechanism.
Two clean options are:
Option 1: Emit a deployment metric
Have CI/CD call PutMetricData after a successful deployment:
1
2
3
4
5
aws cloudwatch put-metric-data \
--namespace "Operations/Deployments" \
--metric-name Deployment \
--value 1 \
--dimensions Service=orders,Environment=prod
Plot that metric beside application health.
Option 2: Update dashboard annotations
CloudWatch metric widgets support vertical annotations. Your deployment pipeline can update the dashboard JSON after a release and add a timestamped deployment annotation.
The first approach creates queryable deployment telemetry. The second creates a cleaner visual timeline.
Either is better than writing “add deployment markers” and pretending they appear by themselves.

Alarm starting points

The Incident Command dashboard usually should not invent a second set of thresholds. It should aggregate the alarms already owned by infrastructure, application, Lambda, database, queue, and dependency components.
For high-noise environments, consider using composite or higher-level alarms so one underlying failure does not page the team fifteen times.

What to look for

Alarm + deployment signal at the same time
The last release becomes a strong hypothesis, not automatic proof.
Application errors up + infrastructure stable + DB stable
Look toward application code or external dependencies.
Latency rises first, then errors, then unhealthy targets
The order matters. The first symptom often tells you more than the loudest symptom.
Incident response is partly debugging.
It is also chronology.

Dashboards and Alarms Should Be One Product

A dashboard tells you what is happening.
An alarm tells you when looking becomes urgent.
Treating them as separate projects creates drift.
Instead:
1
2
3
4
5
6
Service observability module
├── Dashboard
├── Metric math
├── Alarms
├── Log queries
└── Runbook links
When the service changes, its observability changes with it.
That is what “automated dashboards” should mean.
Not automated creation of pretty graphs.
Automated operational context.

What Will This Cost?

Do not assume CloudWatch observability is free because many AWS service metrics are published automatically.
Costs can come from:
  • Custom metrics
  • CloudWatch-agent metrics
  • Additional dashboards
  • Alarms
  • Log ingestion and storage
  • Logs Insights queries
  • Some API usage
  • Database Insights or other advanced observability features
AWS currently provides free-tier allowances for a limited number of custom metrics, dashboards, alarm metrics, and log usage. Pricing then varies by feature and Region. AWS also notes that loading dashboard widgets backed by Logs Insights queries can generate query charges.
So optimize dashboards the same way you optimize infrastructure:
collect what creates decisions.
More telemetry is not automatically more observability.

A Practical Deployment Checklist

Before calling any dashboard production-ready, check these boxes:
Infrastructure
  • CloudWatch agent installed where host memory/filesystem metrics are required
  • Correct metric namespaces and dimensions
  • Environment and Region parameterized
Access
  • Deployment role can create/update dashboards
  • Deployment role can create alarms
  • Custom metric publishers have only the permissions they require
Naming
Use:
1
environment-region-service-purpose
Remember that dashboard names are account-global.
Multi-account AWS
If you operate across several accounts, decide whether teams should open dashboards account by account or use a monitoring account with cross-account observability. CloudWatch supports central views of metrics, logs, and traces from source accounts.
Thresholds
Start with reasonable numbers.
Then replace assumptions with:
  • SLOs
  • historical baselines
  • capacity limits
  • customer impact
  • recovery time
That is how an alarm becomes useful instead of noisy.

The Real Test of an Operations Dashboard

Imagine it is 2:13 AM.
An alarm wakes somebody up.
They know nothing about the incident yet.
Your dashboard has one job:
reduce uncertainty.
Can the operator answer these questions quickly?
  1. What changed?
  2. Are customers affected?
  3. Which layer is under pressure?
  4. Did anything deploy recently?
  5. What should I investigate next?
If the answer is no, another twelve graphs probably will not save the dashboard.
Delete what does not help.
Promote what does.
Automate what matters.
The best CloudWatch dashboard is not the one with the most widgets.
It is the one that gets the operator to the next correct decision faster.

Any opinions in this article are those of the individual author and may not reflect the opinions of AWS.
Enjoyed reading this content? Let the author know!

Your likes, comments, shares, and saves help creators reach more builders.

Loading recommendations

Loading article