I have configured CW agent to send disk space metrics and create an alarm based on that metric. I'm using terraform deploy resources in AWS. Below code is working when I only create alarm for a single path like /var.
resource "aws_cloudwatch_metric_alarm" "EC2_DiskSpace_Alert" {
count = terraform.workspace == "prod" ? var.instance_count : 0
alarm_name = "${terraform.workspace}_${var.name}_${count.index}_EC2_DiskSpace_Alert"
alarm_description = "Alert when Disk Space Utilization is above threshold"
alarm_actions = [data.aws_sns_topic.cloudwatch_alerts.arn]
metric_name = "disk_used_percent"
namespace = "CWAgent"
statistic = "Average"
comparison_operator = "GreaterThanOrEqualToThreshold"
threshold = 70
unit = "Percent"
evaluation_periods = 3
period = 5
treat_missing_data = "notBreaching"
tags = {
Environment = terraform.workspace
}
dimensions = {
"InstanceId" = aws_instance.i[count.index].id
}
}
But if I want to create an alarm for each path like /var, / code should be like this.
resource "aws_cloudwatch_metric_alarm" "EC2_DiskSpace_Alert" {
count = terraform.workspace == "prod" ? var.instance_count : 0
alarm_name = "${terraform.workspace}_${var.name}_${count.index}_EC2_DiskSpace_Alert"
alarm_description = "Alert when Disk Space Utilization is above threshold"
alarm_actions = [data.aws_sns_topic.cloudwatch_alerts.arn]
metric_name = "disk_used_percent"
namespace = "CWAgent"
statistic = "Average"
comparison_operator = "GreaterThanOrEqualToThreshold"
threshold = 70
unit = "Percent"
evaluation_periods = 3
period = 5
treat_missing_data = "notBreaching"
tags = {
Environment = terraform.workspace
}
dimensions = {
"InstanceId" = aws_instance.i[count.index].id
"ImageId" = "ami-xx"
"InstanceType" = "t2-micro"
"path" = "/var"
"device" = "mapper"
"fstype" = "xfs"
}
}
resource "aws_cloudwatch_metric_alarm" "EC2_DiskSpace_Alert" {
count = terraform.workspace == "prod" ? var.instance_count : 0
alarm_name = "${terraform.workspace}_${var.name}_${count.index}_EC2_DiskSpace_Alert"
alarm_description = "Alert when Disk Space Utilization is above threshold"
alarm_actions = [data.aws_sns_topic.cloudwatch_alerts.arn]
metric_name = "disk_used_percent"
namespace = "CWAgent"
statistic = "Average"
comparison_operator = "GreaterThanOrEqualToThreshold"
threshold = 70
unit = "Percent"
evaluation_periods = 3
period = 5
treat_missing_data = "notBreaching"
tags = {
Environment = terraform.workspace
}
dimensions = {
"InstanceId" = aws_instance.i[count.index].id
"ImageId" = "ami-xx"
"InstanceType" = "t2-micro"
"path" = "/"
"device" = "mapper"
"fstype" = "xfs"
}
}
Is there a better way to do it without repeating this block for each path that I want to create an alarm? Like creating a dynamic "dimensions" without hardcoding values? Thank you in advance.
Thank all for the suggestions.
I was able to make it work using for_each
and locals
.
locals {
paths = {
"root" : {
"path" = "/",
"device" = "xvda1",
"fstype" = "ext4",
},
"boot_efi" : {
"path" = "/boot/efi",
"device" = "xvda15",
"fstype" = "vfat",
}
}
}
resource "aws_cloudwatch_metric_alarm" "warning_ec2_diskspace_alert" {
for_each = terraform.workspace == "dev" || terraform.workspace == "prod" ? local.paths : {}
alarm_name = "${terraform.workspace}_${each.key}_warning_ec2_diskspace_alert"
alarm_description = "Alert when Disk Space Utilization is above threshold"
metric_name = "disk_used_percent"
namespace = "CWAgent"
statistic = "Average"
comparison_operator = "GreaterThanOrEqualToThreshold"
threshold = 70
unit = "Percent"
evaluation_periods = 3
period = 60
treat_missing_data = "notBreaching"
tags = {
Environment = terraform.workspace
}
dimensions = {
"InstanceId" = aws_instance.web[0].id
"ImageId" = aws_instance.web[0].ami
"InstanceType" = aws_instance.web[0].instance_type
"path" = each.value.path
"device" = each.value.device
"fstype" = each.value.fstype
}
}