# Customizing CloudWatch Alarms

# Prerequisites

Before starting, gather the following information:

  1. AWS Account ID: Locate this in the deployment organization's settings page.
  2. Deployment ID: Found in the deployment's settings page.

Log in to the production SSO account, and assume the ProdAutoPilotSupportLevelTwo role in the correct AWS account.

# Locating The Correct Stack

  1. Open the CloudFormation service in the AWS console.
  2. Use the Deployment ID to filter and locate the main stack.
  3. To simplify the search, untoggle the "View nested" switch.

Once the main stack is identified, proceed to update it.

# Editing The Template

The recommended method for editing the stack's template is through the "Infrastructure Composer" since you can edit it through your browser. Once in the editor, follow these steps:

  1. Navigate to the Template tab within the editor.
  2. Ensure the template remains in JSON format.

Proceed to update the template.

# SNS Topic

AutoPilot deployments include an SNSTopic resource of type AWS::SNS::Topic that is used for sending notifications to configured email addresses. This topic is already configured via api with all the email addresses displayed in the "Resource Alerts" section of the deployment settings page.

Locate the SNSTopic resource in the template to verify it exists. It should look similar to this:

{
    "SNSTopic": {
        "Type": "AWS::SNS::Topic",
        "Properties": {
            "DisplayName": "Deployment Alerts"
        }
    },
}

# Custom CloudWatch Alarm

Usually, CloudWatch alarms are stored in the nested templates and we pass the SNS topic ARN to the nested template via their parameters. However, when adding custom alarms, it is more appropriate and convenient to just add them directly to the main template.

In this example, we'll create a CloudWatch alarm that triggers when the Auto Scaling Group (ASG) exceeds a specified number of instances.

Locate the end of the Resources section in the template and add the following resource to the end of the Resources section:

{
	"Resources": {
		"HighInstanceCountAlarm": {
			"Type": "AWS::CloudWatch::Alarm",
			"Properties": {
				"AlarmName": {
					"Fn::Sub": "${AWS::StackName}-high-instance-count"
				},
				"AlarmDescription": "Triggers when ASG instance count exceeds threshold",
				"MetricName": "GroupDesiredCapacity",
				"Namespace": "AWS/AutoScaling",
				"Statistic": "Average",
				"Period": 300,
				"EvaluationPeriods": 1,
				"Threshold": 10,
				"ComparisonOperator": "GreaterThanThreshold",
				"Dimensions": [
					{
						"Name": "AutoScalingGroupName",
						"Value": {
							"Fn::GetAtt": [
								"LayerJrcWeb",
								"Outputs.AutoScalingGroupName"
							]
						}
					}
				],
				"AlarmActions": [
					{
						"Ref": "SNSTopic"
					}
				],
				"OKActions": [
					{
						"Ref": "SNSTopic"
					}
				]
			}
		}
	}
}

Notice that the Threshold value is set to 10 instances in this example and we send a notification to the SNSTopic when the alarm is triggered and when the alarm returns to OK state. Further customization is always possible, you can reference the CloudWatch Alarm Resource documentation for more information.

# Applying the Changes

  1. Validate the updated template.
  2. Update the stack with the new template.
  3. Use the wizard to apply the changes.

Once the update is complete, you can optionally confirm that the alarm is created with the correct parameters by going to the CloudWatch console and searching for it.

# Auxiliary SNS Topic (Optional)

You might want to setup an auxiliary SNS topic that will be used to send notifications to a different set of recipients. This is unusual, but can be useful. You can simply add a new resource in the Resources section. For example:

{
	"Resources": {
		"AuxiliarySNSTopic": {
			"Type": "AWS::SNS::Topic",
			"Properties": {
				"DisplayName": "Auxiliary Notifications"
			}
		}
	}
}

Next, you will want to edit a couple more sections so that AutoPilot can reference and use the new topic. You will want to reference the topic arn in the Outputs section:

{
	"Outputs": {
		"AuxiliarySNSTopicArn": {
			"Value": {
				"Ref": "AuxiliarySNSTopic"
			}
		},
	}
}

Finally, you will want to define some metadata in the Metadata.JetRails::Processor::Topics section (append to existing array):

{
	"Metadata": {
		"JetRails::Processor::Topics": [
			{
				"FriendlyName": "Auxiliary Alerts",
				"Description": "Whatever description you want to display to the client.",
				"TopicArn": "AuxiliarySNSTopicArn"
			}
		],
	}
}

Once complete, you can see configure whatever alarms you wish to send to the new topic as discribed in the guide above. It will be displayed in the client portal and look like this:

Auxiliary Topic
Auxiliary Topic