Keeping in line with creating infrastructure as code, I tend to create (most) CloudWatch Dashboards via CloudFormation. The reason I do this is not because it is cool (which it is), but because:
- It allows me to reuse the template across other stacks that are similar. I just need to pass in relevant parameters for the stack
- The Cloudwatch dashboard is automatically updated every time the Auto Scaling Group (and other related components) are updated. This is a huge win for me as I don’t need to manually update each and every widget of the cloudwatch dashboard every time the Auto Scaling Group is updated
The CloudWatch dashboard below is for an application stack which includes an Auto Scaling Group of web servers behind an ELB (Classic).
I’m interested in looking at only certain ASG and ELB (Classic) metrics that I believe are important for this application stack. A complete list of Auto Scaling Group Metrics and ELB Metrics (Classic) can be found on the Amazon Docs site here and here

My Cloudformation Template for creating the dashboard:
---
AWSTemplateFormatVersion: "2010-09-09"
Description: Creates Cloudwatch Dashboard
Parameters:
AutoScalingGroupName:
Description: Enter the name of the Auto Scaling Group
Type: String
LoadBalancerName:
Description: Enter the name of the Load Balancer
Type: String
DashboardName:
Description: Enter the name of the CloudWatch Dashboard
Type: String
Resources:
BasicDashboard:
Type: AWS::CloudWatch::Dashboard
Properties:
DashboardName: !Ref DashboardName
DashboardBody:
Fn::Sub: '{
"widgets": [
{
"type": "metric",
"width": 12,
"height": 6,
"properties": {
"metrics": [
["AWS/EC2","CPUUtilization","AutoScalingGroupName","${AutoScalingGroupName}"]
],
"region": "${AWS::Region}",
"period": 60,
"title": "AutoScalingGroup-CPU Utilization"
}
},
{
"type": "metric",
"width": 12,
"height": 6,
"properties": {
"metrics": [
["AWS/AutoScaling","GroupTotalInstances","AutoScalingGroupName","${AutoScalingGroupName}"],
["AWS/ELB","HealthyHostCount","LoadBalancerName","${LoadBalancerName}"]
],
"region": "${AWS::Region}",
"period": 60,
"title": "AutoScalingGroup-Instances"
}
},
{
"type": "metric",
"width": 12,
"height": 6,
"properties": {
"metrics": [
["AWS/ELB","Latency","LoadBalancerName","${LoadBalancerName}"]
],
"region": "${AWS::Region}",
"period": 60,
"title": "LoadBalancer-Latency"
}
},
{
"type": "metric",
"width": 12,
"height": 6,
"properties": {
"metrics": [
["AWS/ELB","RequestCount","LoadBalancerName","${LoadBalancerName}"]
],
"region": "${AWS::Region}",
"stat": "Sum",
"period": 60,
"title": "LoadBalancer-RequestCount"
}
},
{
"type": "metric",
"width": 12,
"height": 6,
"properties": {
"metrics": [
["AWS/ELB","HTTPCode_Backend_2XX","LoadBalancerName","${LoadBalancerName}"],
[".","HTTPCode_Backend_3XX",".","."],
[".","HTTPCode_Backend_4XX",".","."],
[".","HTTPCode_Backend_5XX",".","."]
],
"region": "${AWS::Region}",
"stat": "Sum",
"period": 60,
"title": "LoadBalancer-BackendResponses"
}
},
{
"type": "metric",
"width": 12,
"height": 6,
"properties": {
"metrics": [
["AWS/ELB","HTTPCode_ELB_4XX","LoadBalancerName","${LoadBalancerName}"],
[".","HTTPCode_ELB_5XX",".","."]
],
"region": "${AWS::Region}",
"stat": "Sum",
"period": 60,
"title": "LoadBalancer-ErrorCodes"
}
},
{
"type": "metric",
"width": 12,
"height": 6,
"properties": {
"metrics": [
["AWS/ELB","SpilloverCount","LoadBalancerName","${LoadBalancerName}"]
],
"region": "${AWS::Region}",
"stat": "Sum",
"period": 60,
"title": "LoadBalancer-SpilloverCount"
}
},
{
"type": "metric",
"width": 12,
"height": 6,
"properties": {
"metrics": [
["AWS/ELB","SurgeQueueLength","LoadBalancerName","${LoadBalancerName}"]
],
"region": "${AWS::Region}",
"stat": "Maximum",
"period": 60,
"title": "LoadBalancer-SurgeQueueLength"
}
}
]
}'
This template is part of a bigger (Ansible) playbook that is responsible for creating other components (Auto Scaling Group, Load Balancer, etc).
- name: Create CloudWatch Dashboard
cloudformation:
stack_name: "{{ service_name }}-cloudwatch-dashboard
state: present
template: "./cloudformation/app-dashboard.yml"
template_parameters:
DashboardName: "{{ service_name }}"
AutoScalingGroupName: "{{ auto_scaling_name }}"
LoadBalancerName: "{{ load_balancer_name }}"