CloudWatch isn't just for the cloud

How to extend CloudWatch to monitor and graph whatever you like

4 minute read

Amazon CloudWatch is an inexpensive way to monitor your solution in AWS and due to the extensive set of metrics provided for every AWS service out of the box, it’s easy and quick to adopt. Granted it’s not going to replace your enterprise monitoring solution overnight, but for those who haven’t got the time or justification to spin up their own Nagios/Zabbix/OpsView solution it can do basic event monitoring and alerting.

But there’s more…

As well as Amazon CloudWatch supporting a bunch of metrics for most AWS services, it has powerful functionality that frankly isn’t talked up enough: custom metrics. Combine that fact with the very easy to use AWS CLI/API that you can run from anywhere and you have the ability to quickly start storing metrics for anything and everything in Amazon CloudWatch - even if it’s not in the cloud.

It’s a bit chilly in the garage!

For ages, I’ve had a USB CurrentCost meter hooked up in the garage so that I can track power consumption over time. As well as power consumption in watts the meter is capable of reporting the current temperature where it’s sat, so I previously set up MRTG and latterly Cacti to collect and store these values over time so I could graph it. Yep - if I can graph it and store it for analysis I will. Blame my past as a monitoring specialist for that. Of course this is all very nice, but MRTG doesn’t natively support any form of alerting and at the time Cacti’s monitoring support felt like a bit of a hack.

As part of my drive to minimise the amount of hardware I have at home and simplify some of the random scripts I have - I started looking at alternative ways to collect, store and hopefully alert on these values when they went out of bound. Step forward Amazon CloudWatch.

Create IAM user

The first thing you’ll need to do is create an IAM user in your AWS account with sufficient privileges to talk to CloudWatch via the AWS API. If you do this via the wizard you can get it to give you an access key ID & secret access key which you’ll need for later.

Go ahead and create the IAM user via the AWS Management Console and then give it an inline policy (or create a managed policy) like the one below:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "AllowCloudWatchPutMetricData",
      "Action": "cloudwatch:putMetricData",
      "Effect": "Allow",
      "Resource": "*"
    }
  ]
}

This gives your IAM user the ability to publish metrics into CloudWatch and nothing else.

Set up the AWS CLI

On the machine that had my USB CurrentCost meter attached, I needed to download and install the AWS CLI. Depending on your OS and distribution there are a variety of ways to achieve this; Ubuntu provide a package (apt-get install aws-cli) but for most other distributions you’re best off running this if you’ve got Python’s package manager installed:

pip install --upgrade --user awscli

Hopefully that’s got the AWS CLI all installed for you. Next pick the user that will be running the CLI to push your custom metrics to CloudWatch and sudo/su to that user. Once you’re in a shell as that user, run the following and use the credentials you obtained when you created your IAM user:

$ aws configure
AWS Access Key ID [None]: ZZZZZZZZZZZZZZZZZZZZ
AWS Secret Access Key [None]: AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTt
Default region name [None]: (any valid AWS region.. I chose eu-west-1)
Default output format [None]:

This configures the AWS CLI to use the credentials of your IAM user by default whenever it is run under that user account, by creating ~/.aws/config and ~/.aws/credentials.

Test it

You should now be ready to start publishing custom metrics to Amazon CloudWatch. You can incorporate a call out to the AWS CLI in any of your custom scripts like so:

MONITOR_VALUE=15.1
aws cloudwatch put-metric-data --namespace Home/Environmentals --metric-name GarageTemperatureCelsius --value ${MONITOR_VALUE}

Wrap that command into a cronjob or custom script that extracts the metric you’re interested in, replace MONITOR_VALUE with it, change the metric name to something that represents your data and also change the namespace to protect the innocent remembering it can be anything that doesn’t begin “AWS/”.

You now have your own custom metric going into CloudWatch that you can create alarms against, sending notifications to SNS topics when that garage gets a bit nippy.

comments powered by Disqus