githubEdit

6945212153__attaching-multiple-sns-subscriptions-to-aws-cloudwatch-alarms

Attaching Multiple SNS Subscriptions to AWS CloudWatch Alarms

Attaching Multiple SNS Subscriptions to AWS CloudWatch Alarms Overview This guide explains how to use a Python script to efficiently add SNS topic subscriptions to multiple AWS CloudWatch alarms. Instead of manually configuring each alarm through the AWS Console, this script allows you to verify and update multiple alarms in a single operation, saving significant time. This solution is particularly valuable for customers who manage dozens or even hundreds of CloudWatch alarms. Most customers have 50+ alarms in their environments, and connecting SNS topics to each one manually through the console would take an hour of tedious, repetitive work. By automating this process with a script, you can complete in minutes what would otherwise require substantial repetitive manual effort. Prerequisites Python 3.6+ boto3 library installed ( pip install boto3 ) VS Code workspace Complete Script import boto3 def check_cloudwatch_alarm_actions(alarms_arns, topic_arn=None): """ Check if CloudWatch alarms have actions configured for the ALARM, INSUFFICIENT_DATA, or OK state. Optionally check if any actions match a named ARN. """

Create CloudWatch client

cloudwatch = boto3.client('cloudwatch')

Create SNS client

sns = boto3.client('sns') non_compliant_alarms = [] for alarm_arn in alarms_arns: try:

Get alarm configuration

alarm_config = cloudwatch.describe_alarms(AlarmNames=[alarm_arn])

Extract alarm actions

metric_alarm = alarm_config['MetricAlarms'][0] alarm_actions = metric_alarm.get('AlarmActions', []) insufficient_data_actions = metric_alarm.get('InsufficientDataActions', []) ok_actions = metric_alarm.get('OKActions', []) if not alarm_actions and not insufficient_data_actions and not ok_actions: non_compliant_alarms.append(alarm_arn)

Optionally check if any actions match the SNS topic ARN

if topic_arn: if topic_arn in alarm_actions or topic_arn in insufficient_data_actions or topic_arn in ok_actions: non_compliant_alarms.remove(alarm_arn) except Exception as e: print(f"Error checking alarm {alarm_arn}: {e}") return non_compliant_alarms def attach_sns_to_alarms(non_compliant_alarms, topic_arn): """ Attach an SNS topic to alarms that don't have it configured. IMPORTANT: CloudWatch PutMetricAlarm API requires the entire alarm configuration to be specified, not just the parts being changed. This function retrieves the complete existing configuration first, then reapplies it with the SNS topic added. """ cloudwatch = boto3.client('cloudwatch') updated_alarms = [] for alarm_arn in non_compliant_alarms: try:

Get the alarm name from the ARN

alarm_name = alarm_arn.split(':')[-1]

Get current alarm configuration

alarm_config = cloudwatch.describe_alarms(AlarmNames=[alarm_name]) metric_alarm = alarm_config['MetricAlarms'][0]

Get existing actions

alarm_actions = metric_alarm.get('AlarmActions', []) insufficient_data_actions = metric_alarm.get('InsufficientDataActions', []) ok_actions = metric_alarm.get('OKActions', [])

Add SNS topic to actions if not already present

if topic_arn not in alarm_actions: alarm_actions.append(topic_arn)

Update the alarm with the new actions AND reapply all other settings

CloudWatch requires the complete alarm configuration in each PutMetricAlarm call

response = cloudwatch.put_metric_alarm( AlarmName=alarm_name, AlarmActions=alarm_actions, InsufficientDataActions=insufficient_data_actions, OKActions=ok_actions, **{k: v for k, v in metric_alarm.items() if k not in [ 'AlarmArn', 'AlarmConfigurationUpdatedTimestamp', 'StateValue', 'StateReason', 'StateReasonData', 'StateUpdatedTimestamp', 'AlarmActions', 'InsufficientDataActions', 'OKActions' ]} ) updated_alarms.append(alarm_name) print(f"Updated alarm: {alarm_name}") except Exception as e: print(f"Error updating alarm {alarm_arn}: {e}") return updated_alarms if name == "main":

List of CloudWatch alarm ARNs - REPLACE WITH YOUR ALARM ARNs

alarm_arns = [ 'arn:aws:cloudwatch:us-west-2:123456789012:alarm:YOUR-ALARM-NAME-1', 'arn:aws:cloudwatch:us-west-2:123456789012:alarm:YOUR-ALARM-NAME-2',

Add more alarm ARNs as needed

]

SNS topic ARN - REPLACE WITH YOUR SNS TOPIC ARN

sns_topic_arn = 'arn:aws:sns:us-west-2:123456789012:YOUR-SNS-TOPIC'

Check CloudWatch alarm actions

non_compliant_alarms = check_cloudwatch_alarm_actions(alarm_arns, sns_topic_arn) if non_compliant_alarms: print("\nNon-compliant alarms (no actions configured or matching SNS topic ARN):") for alarm in non_compliant_alarms: print(alarm)

Attach SNS topic to non-compliant alarms

if input("\nWould you like to attach the SNS topic to non-compliant alarms? (y/n): ").lower() == 'y': updated_alarms = attach_sns_to_alarms(non_compliant_alarms, sns_topic_arn) print(f"\nUpdated {len(updated_alarms)} alarms with SNS topic subscription.") else: print("All alarms are compliant.") Script Parameters Required Parameters alarm_arns (List of strings) : A list of CloudWatch alarm ARNs to check and update Example: 'arn:aws:cloudwatch:us-west-2:123456789012:alarm:YOUR-ALARM-NAME' You must replace the example ARNs with your actual alarm ARNs sns_topic_arn (String) : The SNS topic ARN to attach to the alarms Example: 'arn:aws:sns:us-west-2:123456789012:YOUR-SNS-TOPIC' You must replace the example with your actual SNS topic ARN How to Use the Script

  1. Create and Configure the Script Open VS Code in your workspace Create a new Python file (e.g., attach_sns_to_alarms.py ) Copy the complete script above into the file Replace the example values: Replace the ARNs in the alarm_arns list with your actual alarm ARNs Replace the sns_topic_arn with your actual SNS topic ARN Important : This script preserves your complete alarm configuration because CloudWatch's put_metric_alarm API requires specifying the entire alarm configuration when making any changes. The script fetches each alarm's current settings, adds the SNS topic subscription, and then reapplies the complete configuration.

  2. Execute the Script Open a terminal in VS Code Ensure boto3 is installed: pip install boto3 Run the script: python attach_sns_to_alarms.py

  3. Script Execution Flow The script will: Check all specified alarms to see if they have any alarm actions configured Identify alarms that don't have the specified SNS topic attached Display a list of non-compliant alarms Ask if you want to attach the SNS topic to these alarms If you confirm (by typing 'y'), it will update all non-compliant alarms with the SNS topic subscription Region Considerations If your alarms are in a different region, you can specify the region in the boto3 client initialization: cloudwatch = boto3.client('cloudwatch', region_name='your-region') sns = boto3.client('sns', region_name='your-region') Benefits Time Saving : Configure many alarms at once instead of one by one in the console Reusability : Script can be reused whenever new alarms are created

Last updated

Was this helpful?