CloudWatch auto-monitoring on deploy: the Terraform pattern
Most teams add monitoring after their first incident. Here's how to wire it in automatically.
Monitoring module
variable "service_name" {}; variable "environment" {}
variable "alert_email" {}; variable "alb_arn_suffix" {}
resource "aws_cloudwatch_log_group" "service" {
name = "/ecs/${var.environment}/${var.service_name}"
retention_in_days = var.environment == "prod" ? 90 : 14
}
resource "aws_sns_topic" "alerts" { name = "${var.service_name}-${var.environment}-alerts" }
resource "aws_sns_topic_subscription" "email" {
topic_arn = aws_sns_topic.alerts.arn; protocol = "email"; endpoint = var.alert_email
}
resource "aws_cloudwatch_metric_alarm" "error_rate" {
alarm_name = "${var.service_name}-5xx-rate"
comparison_operator = "GreaterThanThreshold"
evaluation_periods = 2; threshold = 5; alarm_actions = [aws_sns_topic.alerts.arn]
metric_query { id = "rate"; expression = "errors/requests*100"; return_data = true }
metric_query { id = "errors"; metric {
metric_name = "HTTPCode_Target_5XX_Count"; namespace = "AWS/ApplicationELB"
period = 60; stat = "Sum"; dimensions = { LoadBalancer = var.alb_arn_suffix }
}}
metric_query { id = "requests"; metric {
metric_name = "RequestCount"; namespace = "AWS/ApplicationELB"
period = 60; stat = "Sum"; dimensions = { LoadBalancer = var.alb_arn_suffix }
}}
}
resource "aws_cloudwatch_dashboard" "service" {
dashboard_name = "${var.service_name}-${var.environment}"
dashboard_body = jsonencode({ widgets = [
{ type = "metric", properties = {
title = "Request Count"
metrics = [["AWS/ApplicationELB","RequestCount","LoadBalancer",var.alb_arn_suffix]]
period = 60; stat = "Sum"
}},
{ type = "metric", properties = {
title = "5XX Errors"
metrics = [["AWS/ApplicationELB","HTTPCode_Target_5XX_Count","LoadBalancer",var.alb_arn_suffix]]
period = 60; stat = "Sum"
}}
]})
}
One-line usage per project
module "monitoring" {
source = "../../modules/service-monitoring"
service_name = "payment-api"; environment = "prod"
alert_email = "oncall@mycompany.com"; alb_arn_suffix = module.alb.arn_suffix
}
Key insight: Terraform's idempotency means the dashboard and alarms exist after every apply. Monitoring is guaranteed by the deploy process itself.
Step2Dev applies this pattern automatically on every project you connect.
👉 step2dev.com
What monitoring do you consider non-negotiable for a new service?
Top comments (0)