Infrastructure Monitoring in AWS
Published: 2023-08-06 15:24:01

## Prerequisites 
- AWS CLI installed
- Terraform installed
- VS Code installed (text editor)

## Set up Project
Create a folder in VS code

aws configure: your credentials
=in the terminal run aws configure

create key pair in aws and download on your system
Under `EC2 > Key pairs > Create key pair`

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/iawmolwqcu969z19o3ua.png)

Download the key pair and copy it to the folder you will be working from

## Create configuration files

terraform configuration

main.tf
```jsx
locals {
  name = "monitoring-server"
}

resource "aws_instance" "poc" {
  ami                    = var.ami
  instance_type          = var.instance_type
  key_name               = var.key_id
  vpc_security_group_ids = [aws_security_group.allow_ssh.id]

  tags = {
    Name = local.name
  }

}

data "aws_vpcs" "default" {}


resource "aws_security_group" "allow_ssh" {
  name        = "allow_ssh"
  description = "Allow SSH inbound traffic"

  ingress {
    description = "SSH from anywhere"
    from_port   = 22
    to_port     = 22
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }

  egress {
    from_port        = 0
    to_port          = 0
    protocol         = "-1"
    cidr_blocks      = ["0.0.0.0/0"]
    ipv6_cidr_blocks = ["::/0"]
  }

  tags = {
    Name = "poc_sg"
  }
}

```


variables.tf
```jsx
variable "region" {
  type    = string
  default = "eu-west-1"
}

variable "ami" {
  type    = string
  default = "ami-0905a3c97561e0b69"
}

variable "instance_type" {
  type    = string
  default = "t2.micro"
}

variable "aws_s3_bucket_terraform" {
  default = "my-poc-backend-bucket-test"
}

variable "key_id" {
  default = "poc-key"
}
```
remote stste
backend.tf
```jsx
resource "aws_s3_bucket" "poc_bucket" {
  bucket = var.aws_s3_bucket_terraform
}

resource "aws_s3_bucket_server_side_encryption_configuration" "poc" {
  bucket = var.aws_s3_bucket_terraform

  rule {
    apply_server_side_encryption_by_default {
      kms_master_key_id = aws_kms_key.poc-bucket-key.arn
      sse_algorithm     = "aws:kms"
    }
  }
}


resource "aws_kms_key" "poc-bucket-key" {
  description             = "This key is used to encrypt bucket objects"
  deletion_window_in_days = 10
  enable_key_rotation     = true
}


resource "aws_kms_alias" "key-alias" {
  name          = "alias/poc-bucket-key"
  target_key_id = aws_kms_key.poc-bucket-key.key_id
}
```
==remeber to change the bucket name and bucket key name, more than one user cant use the same bucket name so choose personal bucket name of choice if not you ay get an error during bucket creation.

create the instance first, not the alarm

To create the instance
```jsx
terraform init
terraform fmt
terraform plan
terraform apply
```
Run the commands individually and not at once.
==remember to explain what each one does

Once creation is complete, log in to your aws account to see the created instance.

## Create Cloudwatch alarm

Copy the instance id fo your running instance on AWS. In your variable.tf, add the below section at the bottom of your configuration, replacing with your instance id of the just created instance

```jsx
variable "instance_id" {
  default= "i-0842ca4d32c8861fa"
}
```

Now create a `cloudwatch.tf` file in your text editor and paste the below

```jsx
resource "aws_cloudwatch_metric_alarm" "cpu_utilization_high" {
  alarm_name          = "cpu-utilization-high"
  comparison_operator = "GreaterThanOrEqualToThreshold"
  evaluation_periods  = 1
  metric_name         = "CPUUtilization"
  namespace           = "AWS/EC2"
  period              = 60
  statistic           = "Average"
  threshold           = 80
  alarm_description   = "This metric triggers when CPU utilization exceeds 80%"
  alarm_actions       = [aws_sns_topic.alarm.arn]
  dimensions = {
    InstanceId = var.instance_id
  }
}

resource "aws_sns_topic" "alarm" {
  name = "CloudWatch_Alarm_Topic"
}

resource "aws_sns_topic_subscription" "alarm_subscription" {
  topic_arn = aws_sns_topic.alarm.arn
  protocol  = "email"
  endpoint  = "kuberneteslinux@gmail.com"
}
```
Replace the endpoint with your preferred email address.


Create the alarm by running 
```jsx
terraform init
terraform plan
terraform apply
```
Once the alarm and SNS topic have been created, you should immediately receive an email at the email address specified as your endpoint.


The email will ask for you to confirm your subscription.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/469rohnc0te86xfdzvoy.png)


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pee8xxsabb59v2tqp618.png)


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/85kgsyqbdk6k2xawwugj.png)

## Test the alarm
SSH into the created instance using your key pair

remember to first ste permissions on the key
```jsx
chmod 400 "test.pem"
```
then

```jsx
ssh -i "test.pem" ubuntu@ec2-54-170-241-216.eu-west-1.compute.amazonaws.com
```
change the key name to your key name

Once logged in, 
```jsx
sudo apt update
sudo apt install stress
```
Stress is a cli tool used to simulate load on= rewrite

Then, you generate load on the instance using the stress tool just installed.

```jsx
stress --vm-bytes $(awk '/MemAvailable/{printf "%d\n", $2 * 0.8;}' < /proc/meminfo)k --vm-keep -m 1
```
This should cause the CPU utilization of your instance to exceed 80%, thus triggering the alarm.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sly5cziictyvzv2ducdg.png)


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/i6q0g5tkfyfemvjm4kdt.png)

The SNS topic will pick this up and send you an email notification about this.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4qrif7bujs5mv77ef5hr.png)