Create alarms with AWS CDK

To Nha Notes | Dec. 10, 2022, 8:29 p.m.

Sample code in TypeScript

import { Construct } from 'constructs';

import * as sns from 'aws-cdk-lib/aws-sns';

import * as cloudwatch from 'aws-cdk-lib/aws-cloudwatch';

import * as cloudwatch_actions from 'aws-cdk-lib/aws-cloudwatch-actions';

import * as cdk from 'aws-cdk-lib';


 

export type SampleAlarmProps = {

  project: string;

  stage: string;

  autoscalingGroupName: string;

  instanceType: string;

  instanceId?: string;

  imageId?: string;

  alarmTopicArn: string;

}

 

export class SampleAlarm extends Construct {

  constructor(scope: Construct, id: string, props: SampleAlarmProps) {

    super(scope, id);

    // const context = scope.node.tryGetContext(props.stage);

    // const stackPrefix = `${context.project}-${context.stage}-etl`;

    const alarmTopic = props.stage === 'staging'

      ? new sns.Topic(this, 'AlarmTopic')

      : sns.Topic.fromTopicArn(this, 'AlarmTopic', props.alarmTopicArn);

    // Daily ASG alarms ******************************************************************

    // Daily ASG mem usage alarm**********************************************************

    const memUsageMetric = new cloudwatch.Metric({

      namespace: 'CWAgent',

      metricName: 'mem_used_percent',

      label: 'mem_used_percent',

      period: cdk.Duration.minutes(5),

      statistic: 'Average',

      unit: cloudwatch.Unit.PERCENT,

      dimensionsMap: {

        AutoScalingGroupName: props.autoscalingGroupName,

        InstanceType: props.instanceType,

        InstanceId: props.instanceId || 'to-be-replaced-by-launched-instance-id',

        ImageId: props.imageId || 'to-be-replaced-by-launched-instance-image-id'

      } // to be updated to add InstanceId by a corntab in running instance

    });

    const memUsageAlarm = memUsageMetric.createAlarm(this, 'MemoryUsageAlarm', {

      alarmName: `${props.autoscalingGroupName}-mem-used-percent-too-high`,

      alarmDescription: 'Average mem used percent over 80% in last 5 minutes',

      threshold: 80,

      comparisonOperator: cloudwatch.ComparisonOperator.GREATER_THAN_THRESHOLD,

      evaluationPeriods: 1,

      datapointsToAlarm: 1,

      actionsEnabled: true

    });

    memUsageAlarm.addAlarmAction(new cloudwatch_actions.SnsAction(alarmTopic));

    // Instance status check failed alarm

    const instanceStatusMetric = new cloudwatch.Metric({

      namespace: 'AWS/EC2',

      metricName: 'StatusCheckFailed_Instance',

      label: 'StatusCheckFailed_Instance',

      period: cdk.Duration.minutes(1),

      statistic: 'Average',

      unit: cloudwatch.Unit.COUNT,

      dimensionsMap: {

        AutoScalingGroupName: props.autoscalingGroupName,

      }

    });

    const instanceStatusAlarm = instanceStatusMetric.createAlarm(this, 'InstanceStatusAlarm', {

      alarmName: `${props.autoscalingGroupName}-instance-status-check-failed`,

      alarmDescription: 'Instance status check failed in last 1 minute',

      threshold: 0,

      comparisonOperator: cloudwatch.ComparisonOperator.GREATER_THAN_THRESHOLD,

      evaluationPeriods: 1,

      datapointsToAlarm: 1,

      actionsEnabled: true

    });

    instanceStatusAlarm.addAlarmAction(new cloudwatch_actions.SnsAction(alarmTopic));

    // Daily ASG system status check failed alarm

    const systemStatusMetric = new cloudwatch.Metric({

      namespace: 'AWS/EC2',

      metricName: 'StatusCheckFailed_System',

      label: 'StatusCheckFailed_System',

      period: cdk.Duration.minutes(1),

      statistic: 'Average',

      unit: cloudwatch.Unit.COUNT,

      dimensionsMap: {

        AutoScalingGroupName: props.autoscalingGroupName,

      } // to be updated to add InstanceId by a corntab in running instance

    });

    const systemStatusAlarm = systemStatusMetric.createAlarm(this, 'SystemStatusAlarm', {

      alarmName: `${props.autoscalingGroupName}-system-status-check-failed`,

      alarmDescription: 'System status check failed in last 1 minute',

      threshold: 0,

      comparisonOperator: cloudwatch.ComparisonOperator.GREATER_THAN_THRESHOLD,

      evaluationPeriods: 1,

      datapointsToAlarm: 1,

      actionsEnabled: true

    });

    systemStatusAlarm.addAlarmAction(new cloudwatch_actions.SnsAction(alarmTopic));

  }

}

new SampleAlarm(this, "SampleAlarm", {

      project: context.project,

      stage: context.stage,

      autoscalingGroupName: asgName,

      instanceType: context.etl.instanceType,

      alarmTopicArn: context.etl.alarmTopicArn

    });

 

Optionally, we can create alarms with AWS Cli in bash script:

#!/usr/bin/env bash

tance_id=$(curl -s http://169.254.169.254/latest/meta-data/instance-id)

aws cloudwatch put-metric-alarm \

    --alarm-name "sample-mem-used-percent-too-high" \

    --alarm-description "Average mem used percent over 80% in last 5 minutes" \

    --metric-name mem_used_percent \

    --namespace CWAgent \

    --statistic Average \

    --period 300 \

    --threshold 80 \

    --comparison-operator GreaterThanThreshold  \

    --dimensions "Name=InstanceId,Value=${instance_id}" \

    --evaluation-periods 1 \

    --alarm-actions arn:aws:sns:ap-northeast-1:200941983230:topicName \

    --unit Percent \

    --region ap-northeast-1