<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Pablo</title>
    <description>The latest articles on DEV Community by Pablo (@kas84).</description>
    <link>https://dev.to/kas84</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F224906%2Fff0b5bd4-e5ae-4cab-9b50-7fa4b53ce432.jpg</url>
      <title>DEV Community: Pablo</title>
      <link>https://dev.to/kas84</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/kas84"/>
    <language>en</language>
    <item>
      <title>Automatically setup cloudwatch alarms on AWS</title>
      <dc:creator>Pablo</dc:creator>
      <pubDate>Fri, 06 Sep 2019 15:06:46 +0000</pubDate>
      <link>https://dev.to/kas84/automatically-setup-cloudwatch-alarms-on-aws-211n</link>
      <guid>https://dev.to/kas84/automatically-setup-cloudwatch-alarms-on-aws-211n</guid>
      <description>&lt;p&gt;At &lt;a href="https://www.tramitapp.com/app-control-horario-trabajadores-2019/"&gt;TramitApp Control Horario&lt;/a&gt;, due to our steady growth, month over month, we've had to move our platform from a hybrid cloud to AWS "all in" due to it's scalability benefits.&lt;/p&gt;

&lt;p&gt;For example, you can setup alarms so that when an ec2-instance has an average CPU of X for Y minutes, you can spin up another ec2-instance to help cope with the load.&lt;/p&gt;

&lt;h1&gt;
  
  
  Setup
&lt;/h1&gt;

&lt;p&gt;Create a script that will install CloudWatch Monitoring tools and setup a cronjob that will post metrics every 5 minutes, in our case &lt;em&gt;memory used&lt;/em&gt;, &lt;em&gt;memory utilization&lt;/em&gt; and &lt;em&gt;disk space utilization&lt;/em&gt; in two volumes, / and /data&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#!/bin/bash
sudo yum install -y perl-Switch perl-DateTime perl-Sys-Syslog perl-LWP-Protocol-https perl-Digest-SHA.x86_64
cd $HOME
wget http://aws-cloudwatch.s3.amazonaws.com/downloads/CloudWatchMonitoringScripts-1.2.1.zip
unzip CloudWatchMonitoringScripts-1.2.1.zip
rm CloudWatchMonitoringScripts-1.2.1.zip

(crontab -l 2&amp;gt;/dev/null; echo "*/5 * * * * ~/aws-scripts-mon/mon-put-instance-data.pl --mem-used --mem-util --disk-space-util --disk-path=/ --disk-path=/data --from-cron") | crontab -
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h1&gt;
  
  
  AWS Configure
&lt;/h1&gt;

&lt;p&gt;Create a script that will do a default aws-configure to configure the proper REGION for our alarms&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#!/bin/sh
REGION=$(ec2-metadata -z | grep -Po "(us|sa|eu|ap)-(north|south|central)?(east|west)?-[0-9]+")

if [ ! -d /home/ec2-user/.aws/ ]; then
  mkdir -p /home/ec2-user/.aws/
fi

if [ ! -d /root/.aws/ ]; then
   mkdir -p /root/.aws/
fi


echo "[default]"&amp;gt; /home/ec2-user/.aws/config
echo "region = $REGION" &amp;gt;&amp;gt;/home/ec2-user/.aws/config

echo "[default]"&amp;gt; /root/.aws/config
echo "region = $REGION" &amp;gt;&amp;gt;/root/.aws/config


&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h1&gt;
  
  
  Create alarms script
&lt;/h1&gt;

&lt;p&gt;In my case, I use Amazon Linux, so we have ec2-metadata command, but you you can always curl &lt;a href="http://169.254.169.254/latest/dynamic/instance-identity/document"&gt;http://169.254.169.254/latest/dynamic/instance-identity/document&lt;/a&gt; from the ec2-instance and get the same info you get with ec2-metadata if you use other distro.&lt;/p&gt;

&lt;p&gt;In this example&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#!/bin/sh
REGION=$(ec2-metadata -z | grep -Po "(us|sa|eu|ap)-(north|south|central)?(east|west)?-[0-9]+")

if [ "$REGION" = "eu-west-1" ]; then
  SNS_TOPIC="WHATEVER_ARN_ID_YOU_HAVE_IN_THIS_REGION"
fi

if [ "$REGION" = "eu-west-2" ]; then
  SNS_TOPIC="WHATEVER_ARN_ID_YOU_HAVE_IN_THIS_REGION"
fi

if [ "$REGION" = "eu-west-3" ]; then
  SNS_TOPIC="WHATEVER_ARN_ID_YOU_HAVE_IN_THIS_REGION"
fi

INSTANCE_ID=$(ec2-metadata --instance-id | cut -d " " -f 2)
INSTANCE_PRIVATE_IP=$(ec2-metadata -o | cut -d " " -f 2)
PRIMARY_PUBLIC_IP_ADDRESS=$(ec2-metadata -v | cut -d " " -f 2)
ROOT_DISK_THRESHOLD=75
DATA_DISK_THRESHOLD=80
MEMORY_THRESHOLD=75
CPU_THRESHOLD=75
FIVE_MINUTES_PERIOD=300
FIFTEEN_MINUTES_PERIOD=900
ROOT_DEVICE=/dev/nvme0n1p1
DATA_DEVICE=/dev/nvme1n1
ROOT_PATH=/
DATA_PATH=/data

echo "Setting up ${INSTANCE_PRIVATE_IP}-cpu-utilization"
aws cloudwatch put-metric-alarm \
--alarm-name "${INSTANCE_PRIVATE_IP}-cpu-utilization" \
--alarm-description "Alarm when CPU exceeds $CPU_THRESHOLD percent" \
--metric-name CPUUtilization \
--namespace AWS/EC2 \
--statistic Average \
--period ${FIFTEEN_MINUTES_PERIOD} \
--threshold ${CPU_THRESHOLD} \
--treat-missing-data breaching \
--comparison-operator GreaterThanThreshold \
--dimensions  Name=InstanceId,Value=${INSTANCE_ID} \
--evaluation-periods 1 \
--alarm-actions $SNS_TOPIC \
--ok-actions $SNS_TOPIC \
--unit Percent 


echo "Setting up $INSTANCE_PRIVATE_IP-root-disk-space-utilization"
aws cloudwatch put-metric-alarm \
--alarm-name $INSTANCE_PRIVATE_IP-root-disk-space-utilization \
--alarm-description "Alarm when root disk space exceeds $ROOT_DISK_THRESHOLD percent" \
--metric-name DiskSpaceUtilization \
--namespace System/Linux \
--statistic Average \
--period $FIVE_MINUTES_PERIOD \
--threshold $ROOT_DISK_THRESHOLD \
--treat-missing-data breaching \
--comparison-operator GreaterThanThreshold \
--dimensions Name=Filesystem,Value=$ROOT_DEVICE Name=InstanceId,Value=$INSTANCE_ID Name=MountPath,Value=$ROOT_PATH \
--evaluation-periods 1 \
--alarm-actions $SNS_TOPIC \
--ok-actions $SNS_TOPIC \
--unit Percent 


echo "Setting up $INSTANCE_PRIVATE_IP-data-disk-space-utilization"
aws cloudwatch put-metric-alarm \
--alarm-name $INSTANCE_PRIVATE_IP-data-disk-space-utilization \
--alarm-description "Alarm when data disk space exceeds $DATA_DISK_THRESHOLD percent" \
--metric-name DiskSpaceUtilization \
--namespace System/Linux \
--statistic Average \
--period $FIVE_MINUTES_PERIOD \
--threshold $DATA_DISK_THRESHOLD \
--treat-missing-data breaching \
--comparison-operator GreaterThanThreshold \
--dimensions Name=Filesystem,Value=$DATA_DEVICE Name=InstanceId,Value=$INSTANCE_ID Name=MountPath,Value=$DATA_PATH \
--evaluation-periods 1 \
--alarm-actions $SNS_TOPIC \
--ok-actions $SNS_TOPIC \
--unit Percent 

echo "Setting up $INSTANCE_PRIVATE_IP-memory-usage-utilization"
aws cloudwatch put-metric-alarm \
--alarm-name $INSTANCE_PRIVATE_IP-memory-usage-utilization \
--alarm-description "Alarm when memory exceeds $DATA_DISK_THRESHOLD percent" \
--metric-name MemoryUtilization \
--namespace System/Linux \
--statistic Average \
--period $FIFTEEN_MINUTES_PERIOD \
--threshold $MEMORY_THRESHOLD \
--treat-missing-data breaching \
--comparison-operator GreaterThanThreshold \
--dimensions Name=InstanceId,Value=$INSTANCE_ID \
--evaluation-periods 1 \
--alarm-actions $SNS_TOPIC \
--ok-actions $SNS_TOPIC \
--unit Percent 

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h1&gt;
  
  
  Pro Tip
&lt;/h1&gt;

&lt;p&gt;If you create an AMI from this instance and setup a boot service that runs this 3 scripts (just make sure the first one only runs once), you will have the alarms without having to set them up manually.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>cloudwatch</category>
    </item>
  </channel>
</rss>
