Amazon's CloudWatch is a powerful Amazon Web Services (AWS) feature that monitors deployed systems and can respond with alerts or even react by calling another AWS service. CloudWatch alarm creation typically occurs via the AWS Management Console, but today I'm going to show you how to configure an alarm with PowerShell.

When you're talking about automating deployments of entire environments, scripting your CloudWatch alarm's creation becomes necessary, especially as the environment increases in complexity and scope.

Prerequisites ^

I'll limit the scope of this article to configuring CloudWatch. Having said that, there are a few prerequisites to getting started if you want to follow along:

  • Install and configure AWS PowerShell.
  • Have an AWS resource to monitor with CloudWatch: an Elastic Compute Cloud (EC2) instance, Fargate Cluster, etc.
  • Create an Identity and Access Management (IAM) user and Simple Notification Service (SNS) topic.
  • Identify a target to monitor. Although these are usually compute resources, you can also monitor items like Simple Storage Service (S3) or AWS Billing.

Creating an alarm ^

To create an alarm with PowerShell, we can use the Write-CWMetricAlarm cmdlet provided by the AWS PowerShell module. This creates an alarm (or updates it if the alarm already exists) and associates the alarm with the specified metric.

Since there are many parameters for this cmdlet, I prefer to use the splatting feature of PowerShell to ensure my parameters all go to the right place, and to make my command more human readable.

A few parameters of this function can get a little tricky, and I've listed them below.

Dimension: By definition, this is the resource scope you are trying to monitor. At minimum, there are two components to a "dimension." One component is an identifier for the resource you wish to have metrics for. This could be an EC2 instance name, S3 bucket name, Elastic Container Service (ECS) cluster, or any AWS resource you can observe with CloudWatch. The second dimension is the specific component of the resource you wish to monitor.

In some cases this will be the CPU utilization percentage. In the case of S3, it can be the number of objects in the bucket, and there are many, many more. You can view all the available dimensions by using the AWS Management Console. And by manually creating a new CloudWatch alarm, you will find all of the scoping parameters listed there. You can also create custom CloudWatch metrics and set your dimensions around your unique logs, but that is outside the scope of this article. This parameter currently cannot accept string input, so to define this you must first create an object of the type Amazon.CloudWatch.Model.Dimension and then input it into your command. I'll show you how to do this in the code below.

TreatMissingData: The TreatMissingData parameter is useful because there are times where your AWS resource simply won't be observable by CloudWatch, or it will be in a condition where it can't report its metrics. Depending on the business criticality of the metric you're monitoring with CloudWatch, you can configure TreatMissingData to respond in a few different ways.

  • missing: The alarm does not take missing data into consideration when evaluating whether or not it needs to change state. Your alarm will likely have an amount of time that needs to expire before it will change from a "good" to "bad" state or vice versa. In this case, you won't have to have however many minutes of valid data. If some of the data is missing, but the pieces that have come in have been bad for the appropriate time period, this will enable your alarm.
  • ignore: The alarm state is maintained despite missing data. For instance, if your alarm was "good" then stopped transmitting data, the alarm would continue to be "good." If something tripped your alarm to "bad," your alarm would continue to be bad even if metric data stopped getting reported to CloudWatch.
  • breaching: missing data will enable the alarm.
  • nonBreaching: will treat missing data as "within the threshold" for the alarm.

Unit: This is the unit of measurement for the statistic. Amazon has a published list of available options for this, but to summarize them, they are the metrics you want to monitor, such as seconds, percentages, a raw count, or even computer metrics like bytes.

AlarmAction: The alarm takes this action upon enabling it. For my alarms, I like to use Amazon SNS. Each SNS notification configuration is called an SNS topic.

Configuring an alarm action such as a notification requires creating the appropriate SNS topic. After this, Amazon will generate the Amazon Resource Name (ARN) for the SNS topic, used to connect AWS resources. You can use the ARN of the SNS topic to create an SNS notification action for your alarm.

For my alarm, I want to configure an alert so if an S3 bucket of my choosing becomes empty, I get an email. To do this, we'll start by creating the dimension objects as described above to look for a bucket I've named "source-01" Since that bucket contains some high availability data as well as some reduced redundancy data, we want to configure it to look at all storage types.

I want to get a notification from my SNS topic whenever the number of objects in my desired S3 bucket is zero, so we set the "Unit" parameter to a "count" of the number of objects in my S3 bucket. We then use the comparison operator of "GreaterThanOrEqualToThreshold" and a threshold of 1. Lastly, we'll need to configure the timing of the alarm. For time settings, we have the Period and EvaluationPeriod parameters.

The period of the alarm is in seconds, and it's the time over which it applies a specified statistic. I'll set my period to 300 so it checks my bucket every five minutes to determine if it is empty. The EvaluationPeriod parameter is how many periods it compares the data to my threshold. For my purposes, I'll use two evaluation periods. This configures my alarm so if I have no data in my S3 bucket for at least 10 minutes, it will enable my alarm.

The commands to create my alarm look like this:

# Set Dimensions
$dimension1 = New-Object Amazon.CloudWatch.Model.Dimension
$dimension2 = New-Object Amazon.CloudWatch.Model.Dimension

$dimensions = ($dimension1, $dimension2)

# Specify Parameters
$params = @{"AlarmName" = "MyS3Alarm";
    "AlarmDescription" = "Ensure we have more than 0 objects in our S3 bucket";
    "ActionsEnabled" = $true;
    "AlarmAction" = "arn:aws:sns:us-east-1:934106316506:s3adminlist"
    "ComparisonOperator" = "GreaterThanOrEqualToThreshold";
    "Dimensions" = $dimensions;
    "EvaluationPeriod" = 2;
    "MetricName" = "NumberOfObjects";
    "Namespace" = "AWS/S3";
    "Period" = 300;
    "Statistic" = "Sum";
    "Threshold" = 1;
    "TreatMissingData" = "ignore";
    "Unit" = "Count"

# Create Rule
Write-CWMetricAlarm @params

As you can see, the parameters are self-explanatory for the most part and are easier to understand the more you work with AWS CloudWatch.

Once we submit the Write-CWMetricAlarm cmdlet, let's log into our AWS Management Console to check out the rule we just created. We then navigate to the CloudWatch menu and click on Alarms. While your alarm starts to receive and process data, it may have a state of INSUFFICIENT_DATA. After it gathers enough data based on the number of evaluation periods and the duration of a period, you will see the alarm state of ALARM or OK, depending on whether it's failing or passing the test.

Alarm status after creation

Alarm status after creation

Also in the console, feel free to monitor your alarm by clicking the Actions button, followed by "modify." This will also help you if you're trying to create a custom alarm with PowerShell but need to know what available values there are for specific parameters.

Manual modification of an alarm in the AWS Management Console

Manual modification of an alarm in the AWS Management Console

A note about permissions ^

By using the Write-CWMetricsAlarm cmdlet, you automatically create and apply the alarm to your account. If this is your first time creating an alarm, CloudWatch will go ahead and create the appropriate service role for your account.

If you'd like to view this role's permissions, you can do so by looking at the role AWSServiceRoleForCloudWatchEvents in your IAM console. For any rule you create after your first, it will automatically run with the permissions of the AWSServiceRoleForCloudWatchEvents role.

If you have configured actions to take after your alarm runs, you will need to ensure you configure the role to have permissions to the resource you want to take action on (EC2 or S3, for instance)

Summary ^

As you've just experienced, by using PowerShell we were able to create a CloudWatch alarm quickly and easily. By using this article as a template, you could write your own alarms and configure them to use in your deployment scripts for new environments.

CloudWatch alarm and service health

CloudWatch alarm and service health

Have an alarm configuration you'd like to share? Feel free to post it in the comments below.


Leave a reply

Your email address will not be published.


© 4sysops 2006 - 2022


Please ask IT administration questions in the forums. Any other messages are welcome.


Log in with your credentials


Forgot your details?

Create Account