Skip to main content

CloudWatch Alarms Must Have ALARM State Actions Configured

Overview

This check verifies that your Amazon CloudWatch alarms have at least one action configured for the ALARM state. When a monitored metric crosses its threshold, the alarm should do something useful - like sending you a notification or triggering an automated response.

Risk

Without an action configured for the ALARM state, your CloudWatch alarm becomes a silent observer. When something goes wrong:

  • No one gets notified - Critical issues can go undetected for hours or days
  • No automated response - You lose the ability to auto-scale, restart services, or trigger remediation
  • Delayed incident response - By the time someone notices the problem manually, damage may already be done

This is rated high severity because silent alarms defeat the entire purpose of monitoring.

Remediation Steps

Prerequisites

You need:

  • AWS Console access with CloudWatch permissions, OR
  • AWS CLI configured with appropriate credentials
  • An SNS topic to receive notifications (you can create one during this process)

AWS Console Method

  1. Open the CloudWatch console at https://console.aws.amazon.com/cloudwatch/

  2. In the left navigation, click Alarms > All alarms

  3. Find the alarm that needs an action and click on its name

  4. Click the Actions dropdown, then select Edit

  5. Scroll down to the Notification section (Step 3 in the wizard)

  6. Under Alarm state trigger, make sure In alarm is selected

  7. For Select an SNS topic, either:

    • Choose an existing SNS topic from the dropdown, OR
    • Select Create new topic and enter an email address to receive alerts
  8. Click Update alarm

That's it! Your alarm will now send notifications when it enters the ALARM state.

AWS CLI Method

Adding an Action to an Existing Alarm

First, get the current alarm configuration:

aws cloudwatch describe-alarms \
--alarm-names "your-alarm-name" \
--region us-east-1

Then update the alarm to add an SNS action. You must re-specify all the original parameters plus the new action:

aws cloudwatch put-metric-alarm \
--alarm-name "your-alarm-name" \
--metric-name "CPUUtilization" \
--namespace "AWS/EC2" \
--statistic Average \
--period 300 \
--evaluation-periods 2 \
--threshold 80 \
--comparison-operator GreaterThanThreshold \
--alarm-actions "arn:aws:sns:us-east-1:123456789012:my-alerts-topic" \
--region us-east-1

Important: Replace the placeholder values:

  • your-alarm-name - The name of your alarm
  • 123456789012 - Your AWS account ID
  • my-alerts-topic - Your SNS topic name

Creating a New Alarm with Actions

aws cloudwatch put-metric-alarm \
--alarm-name "high-cpu-alarm" \
--alarm-description "Alarm when CPU exceeds 80%" \
--metric-name "CPUUtilization" \
--namespace "AWS/EC2" \
--dimensions Name=InstanceId,Value=i-1234567890abcdef0 \
--statistic Average \
--period 300 \
--evaluation-periods 2 \
--threshold 80 \
--comparison-operator GreaterThanThreshold \
--alarm-actions "arn:aws:sns:us-east-1:123456789012:my-alerts-topic" \
--treat-missing-data notBreaching \
--region us-east-1
CloudFormation Template
AWSTemplateFormatVersion: '2010-09-09'
Description: CloudWatch Alarm with ALARM state action configured

Parameters:
AlarmName:
Type: String
Description: Name of the CloudWatch alarm
Default: my-alarm

MetricName:
Type: String
Description: Name of the metric to monitor
Default: CPUUtilization

Namespace:
Type: String
Description: Namespace of the metric
Default: AWS/EC2

Threshold:
Type: Number
Description: Threshold for the alarm
Default: 80

SNSTopicArn:
Type: String
Description: ARN of the SNS topic to notify when alarm triggers

Resources:
CloudWatchAlarm:
Type: AWS::CloudWatch::Alarm
Properties:
AlarmName: !Ref AlarmName
AlarmDescription: Alarm that triggers when metric exceeds threshold
MetricName: !Ref MetricName
Namespace: !Ref Namespace
Statistic: Average
Period: 300
EvaluationPeriods: 2
Threshold: !Ref Threshold
ComparisonOperator: GreaterThanThreshold
AlarmActions:
- !Ref SNSTopicArn
TreatMissingData: notBreaching

Outputs:
AlarmArn:
Description: ARN of the created alarm
Value: !GetAtt CloudWatchAlarm.Arn

Deploy with:

aws cloudformation deploy \
--template-file template.yaml \
--stack-name cloudwatch-alarm-with-actions \
--parameter-overrides \
AlarmName=my-cpu-alarm \
SNSTopicArn=arn:aws:sns:us-east-1:123456789012:my-alerts-topic \
--region us-east-1
Terraform Configuration
terraform {
required_version = ">= 1.0"
required_providers {
aws = {
source = "hashicorp/aws"
version = ">= 4.0"
}
}
}

provider "aws" {
region = "us-east-1"
}

variable "alarm_name" {
description = "Name of the CloudWatch alarm"
type = string
default = "my-alarm"
}

variable "metric_name" {
description = "Name of the metric to monitor"
type = string
default = "CPUUtilization"
}

variable "namespace" {
description = "Namespace of the metric"
type = string
default = "AWS/EC2"
}

variable "threshold" {
description = "Threshold for the alarm"
type = number
default = 80
}

variable "sns_topic_arn" {
description = "ARN of the SNS topic to notify when alarm triggers"
type = string
}

resource "aws_cloudwatch_metric_alarm" "this" {
alarm_name = var.alarm_name
alarm_description = "Alarm that triggers when metric exceeds threshold"
comparison_operator = "GreaterThanThreshold"
evaluation_periods = 2
metric_name = var.metric_name
namespace = var.namespace
period = 300
statistic = "Average"
threshold = var.threshold
treat_missing_data = "notBreaching"

alarm_actions = [var.sns_topic_arn]
}

output "alarm_arn" {
description = "ARN of the created alarm"
value = aws_cloudwatch_metric_alarm.this.arn
}

Apply with:

terraform init
terraform apply -var="sns_topic_arn=arn:aws:sns:us-east-1:123456789012:my-alerts-topic"

Verification

After configuring the alarm action, verify it's working:

  1. Go to CloudWatch > Alarms > All alarms
  2. Click on your alarm name
  3. In the Actions section, confirm you see an action listed under ALARM
CLI Verification
aws cloudwatch describe-alarms \
--alarm-names "your-alarm-name" \
--query 'MetricAlarms[0].AlarmActions' \
--region us-east-1

The output should show at least one ARN (like an SNS topic). If it returns an empty array [], the alarm still has no actions configured.

To list all alarms missing ALARM actions:

aws cloudwatch describe-alarms \
--query 'MetricAlarms[?length(AlarmActions)==`0`].AlarmName' \
--region us-east-1

Additional Resources

Notes

  • Actions vs. Notifications: Alarm actions can do more than send emails. You can trigger Lambda functions, Auto Scaling policies, EC2 actions (stop, terminate, reboot), or Systems Manager automation.

  • Multiple Actions: You can configure multiple actions for the same alarm state. For example, send an email AND trigger a Lambda function.

  • Other Alarm States: Consider also configuring actions for the OK state (to know when issues resolve) and INSUFFICIENT_DATA state (to catch monitoring gaps).

  • SNS Subscription Confirmation: If you create a new SNS topic with email subscribers, those subscribers must confirm their subscription by clicking a link in the confirmation email before they'll receive alerts.

  • Testing Your Alarm: You can use aws cloudwatch set-alarm-state to temporarily force an alarm into the ALARM state to test that notifications are working. Just remember this is temporary and the alarm will return to its actual state on the next evaluation.