Understanding CloudFormation Monitoring
AWS CloudFormation gives you a powerful way to model and provision your entire infrastructure using code. But once your stacks are created or updated, the story doesn’t end. Without proper monitoring, you can miss drift, silent failures, or rolled-back changes until they cause an outage. Monitoring CloudFormation means tracking stack events, detecting configuration drift, and surfacing critical status changes through metrics, alarms, and dashboards — so your team can respond before customers are impacted.
This tutorial covers exactly what to monitor, why it matters, and how to implement it step by step using CloudWatch, EventBridge, and CloudFormation itself. You’ll see real code examples that you can adapt immediately.
Why Monitoring CloudFormation Matters
CloudFormation stacks are the backbone of many AWS environments. A stack stuck in UPDATE_FAILED or ROLLBACK_IN_PROGRESS can leave resources in an inconsistent state, block further deployments, and create hidden security gaps. Monitoring gives you:
- Early detection of failures – Know instantly when a stack enters a failed or rollback state.
- Drift awareness – Get alerted when live resources diverge from their template definitions.
- Operational visibility – Build dashboards that show stack health across all environments and accounts.
- Audit readiness – Keep a continuous record of stack events for compliance and troubleshooting.
By turning CloudFormation activity into metrics, you can apply the same rigorous monitoring you already use for application performance, but to your infrastructure code pipeline.
Key Metrics for CloudFormation
CloudFormation does not publish built-in CloudWatch metrics. Instead, you generate metrics from CloudTrail logs, EventBridge events, or custom code. Below are the three essential metric categories you should collect.
Stack Events and Status Metrics
Every CloudFormation stack change generates CloudTrail events like CreateStack, UpdateStack, DeleteStack, and detailed resource-level events. By creating a CloudWatch metric filter on the CloudTrail log group, you can count stack statuses and publish a metric that tracks failures over time.
A common approach is to publish a metric named StackFailureCount whenever a stack operation ends with a FAILED or ROLLBACK status. The metric filter pattern looks like this:
{
"eventSource": "cloudformation.amazonaws.com",
"eventName": "UpdateStack",
"responseElements": {
"stackStatus": "UPDATE_FAILED"
}
}
You can combine patterns for multiple failure statuses using || in the filter. For example:
{ ($.eventName = "UpdateStack" AND $.responseElements.stackStatus = "UPDATE_FAILED")
|| ($.eventName = "CreateStack" AND $.responseElements.stackStatus = "CREATE_FAILED")
|| ($.eventName = "DeleteStack" AND $.responseElements.stackStatus = "DELETE_FAILED") }
Resource-level Metrics
Sometimes you need to monitor specific resources inside a stack — for example, whether an EC2 instance was replaced unexpectedly, or whether a security group was modified outside of CloudFormation. Resource-level CloudTrail events (like CreateSecurityGroup with requestParameters showing the stack ID) can be filtered to create per-resource or per-stack metrics. You can then build alarms on, say, unauthorized changes to a critical security group that is supposed to be managed only by CloudFormation.
Custom Metrics via CloudWatch
For complex monitoring logic — such as tracking stack deployment duration, counting drift occurrences, or checking for stacks that haven’t been updated in weeks — a Lambda function can push custom metrics directly to CloudWatch. This is covered later in the alarms section.
Setting Up CloudWatch Alarms
Alarms translate metrics into actionable notifications. The following patterns cover the most critical CloudFormation scenarios.
Alarms for Stack Failures
Once you have a metric filter publishing a failure metric, you can create an alarm that triggers when any failure occurs, or when failures exceed a threshold within a period. Here’s an example CloudFormation snippet that creates the metric filter and alarm together:
Resources:
CloudTrailLogGroup:
Type: AWS::Logs::LogGroup
Properties:
RetentionInDays: 90
StackFailureMetricFilter:
Type: AWS::Logs::MetricFilter
Properties:
LogGroupName: !Ref CloudTrailLogGroup
FilterPattern: '{ ($.eventName = "UpdateStack" AND $.responseElements.stackStatus = "UPDATE_FAILED") || ($.eventName = "CreateStack" AND $.responseElements.stackStatus = "CREATE_FAILED") }'
MetricTransformations:
- MetricName: StackFailureCount
MetricNamespace: CloudFormationMonitoring
MetricValue: "1"
StackFailureAlarm:
Type: AWS::CloudWatch::Alarm
Properties:
AlarmName: CloudFormation-Stack-Failure
AlarmDescription: "Triggers when a CloudFormation stack creation or update fails"
Namespace: CloudFormationMonitoring
MetricName: StackFailureCount
Statistic: Sum
Period: 60
EvaluationPeriods: 1
Threshold: 0
ComparisonOperator: GreaterThanThreshold
TreatMissingData: notBreaching
AlarmActions:
- !Ref SnsNotificationTopic
This alarm fires immediately on the first failure within a one-minute period. Adjust EvaluationPeriods and Threshold if you want to suppress transient single failures and only alert on repeated issues.
Alarms for Drift Detection
Drift detection tells you when live resources no longer match their CloudFormation template. CloudFormation emits CloudTrail events for DetectStackDrift and DescribeStackDriftDetectionStatus. You can set up a metric filter for drift results that contain "StackDriftStatus": "DRIFTED" and create an alarm that triggers daily if drift is found.
A more proactive method is to run drift detection on a schedule using a Lambda function, and push a custom metric DriftedStackCount. The Lambda can query all stacks, count those with drift, and publish the number. The alarm below watches that custom metric:
DriftCheckAlarm:
Type: AWS::CloudWatch::Alarm
Properties:
AlarmName: Drift-Detected-Across-Stacks
AlarmDescription: "Alerts when one or more stacks have drifted"
Namespace: CloudFormationMonitoring
MetricName: DriftedStackCount
Statistic: Maximum
Period: 86400
EvaluationPeriods: 1
Threshold: 0
ComparisonOperator: GreaterThanThreshold
AlarmActions:
- !Ref SnsNotificationTopic
Combine this with a daily Lambda schedule (via CloudWatch Events) to keep your environment consistently monitored for configuration drift.
Alarms for Rollback States
A stack entering ROLLBACK_IN_PROGRESS or ROLLBACK_FAILED is a serious incident. You can extend the failure metric filter to also match rollback statuses. For example:
FilterPattern: '{ ($.eventName = "UpdateStack" AND ($.responseElements.stackStatus = "UPDATE_FAILED" OR $.responseElements.stackStatus = "ROLLBACK_IN_PROGRESS" OR $.responseElements.stackStatus = "ROLLBACK_FAILED")) }'
Then use an identical alarm configuration. This ensures you’re alerted even when CloudFormation tries to revert changes but encounters issues.
Building CloudWatch Dashboards
Dashboards give your team a real-time view of CloudFormation health across stacks, environments, and accounts. You can create dashboards directly in the AWS Console, but a better practice is to define them as CloudFormation resources so they are versioned and reproducible.
Creating a Dashboard via Console
In the CloudWatch console, you can add widgets that show your custom metrics (like StackFailureCount) alongside alarms. A typical layout includes:
- A time-series graph of stack failures over the last 24 hours.
- A number widget showing total failed stacks in the current hour.
- Alarm status widgets for your failure and drift alarms.
However, manual dashboard creation doesn’t scale across multiple accounts. That’s where CloudFormation-managed dashboards shine.
Dashboard via CloudFormation
The AWS::CloudWatch::Dashboard resource lets you define a JSON string with the entire dashboard body. Below is a complete example that displays stack failures, drift count, and alarm statuses:
MonitoringDashboard:
Type: AWS::CloudWatch::Dashboard
Properties:
DashboardName: CloudFormation-Health
DashboardBody: |
{
"widgets": [
{
"type": "metric",
"x": 0,
"y": 0,
"width": 12,
"height": 6,
"properties": {
"metrics": [
[ "CloudFormationMonitoring", "StackFailureCount", { "stat": "Sum", "period": 300 } ]
],
"view": "timeSeries",
"stacked": false,
"region": "us-east-1",
"title": "Stack Failures (5 min intervals)"
}
},
{
"type": "metric",
"x": 12,
"y": 0,
"width": 6,
"height": 6,
"properties": {
"metrics": [
[ "CloudFormationMonitoring", "DriftedStackCount", { "stat": "Maximum", "period": 86400 } ]
],
"view": "singleValue",
"region": "us-east-1",
"title": "Drifted Stacks (last 24h)"
}
},
{
"type": "alarm",
"x": 0,
"y": 6,
"width": 18,
"height": 6,
"properties": {
"alarms": [
"CloudFormation-Stack-Failure",
"Drift-Detected-Across-Stacks"
],
"title": "Active CloudFormation Alarms"
}
}
]
}
This dashboard gives you a single pane of glass for CloudFormation operations. You can extend it with widgets for stack update duration (using custom metrics from a Lambda) or per-environment breakdowns by including multiple metric queries.
Best Practices
- Centralize monitoring across accounts – Use cross-account CloudWatch or a central monitoring account to aggregate CloudFormation metrics from all member accounts. This prevents blind spots in multi-account setups.
- Treat dashboards as code – Always define dashboards in CloudFormation (or CDK) and store them in version control. Manual console changes lead to drift in your monitoring layer.
- Combine alarms with incident management – Forward SNS notifications to Slack, PagerDuty, or AWS Chatbot so that CloudFormation issues are routed to the on-call team immediately.
- Test alarms regularly – Simulate a stack failure (e.g., using a template with an invalid resource) in a development environment to verify that alarms fire and notifications arrive as expected.
- Monitor drift proactively – Run drift detection at least daily and alarm on any drift found. Integrate this with a dashboard widget so operators see drift status alongside failures.
- Set up rollback alarms – A rollback is a failure that already impacted resources; treat it with the same urgency as a creation failure.
- Use composite alarms for complex logic – If you want to alert only when both a failure occurs and a specific stack is in production, combine metrics using CloudWatch composite alarms.
- Keep retention high on CloudTrail logs – Your metric filters depend on CloudTrail logs. Ensure log groups have sufficient retention (at least 90 days) to support historical analysis.
Conclusion
Monitoring CloudFormation is not an afterthought — it’s a critical part of running infrastructure as code reliably. By turning stack events and drift detection into CloudWatch metrics, wrapping those metrics in alarms, and surfacing everything through coded dashboards, you gain continuous visibility into the health of your infrastructure deployment pipeline. The examples in this tutorial give you a production-ready starting point. Implement them, extend them for your own stack landscape, and make CloudFormation monitoring a seamless part of your DevOps observability strategy.