Help using dynamic block for cloudwatch alarm dimensions

Hello guys,

I’m running into an issue using dynamic blocks for the cloudwatch alarm dimensions. The way I’m creating this alarms is through modules and each of the properties are supplied via a config variable I made that looks like this:

locals {
  alarms = {
    GroupName = [
      {
        friendly_name = "name"
        namespace = "EC2"
        evaluation_periods = 1
        datapoints_to_alarm = 1
        period = 60
        comparison_operator = "GreaterThanOrEqualToThreshold"
        metric_name = "CPUUtilization"
        threshold = 80
        statistic = "Average"
        dimensions = [
          {
            InstanceId = "id"
          }
        ]
      }
    ]
  }
}

The dimension part of this is dynamic, meaning that it can be anything (keys and values can by anything). This local variable is passed to the module and inside the module it looks like this:

resource "aws_cloudwatch_metric_alarm" "main" {
  alarm_name = "${var.service_name}-${var.env}-${var.alarm_group_name}-${var.alarm_config.friendly_name}"
  namespace = var.alarm_config.namespace

  evaluation_periods = var.alarm_config.evaluation_periods
  period = var.alarm_config.period
  comparison_operator = var.alarm_config.comparison_operator
  metric_name = var.alarm_config.metric_name
  threshold = var.alarm_config.threshold
  statistic = var.alarm_config.statistic
  datapoints_to_alarm = var.alarm_config.datapoints_to_alarm

  dynamic dimensions {
    for_each = var.alarm_config.dimensions
    iterator = "dim"

    content { // cannot set key for this block since "key" is variable

    }
  }

  actions_enabled = true
  alarm_actions = [
    var.sns_topic_arn
  ]
}

As you can see here, i cannot set the content of the dynamic block “dimensions”. I want the ability to dynamically create dimensions based on that local variable.

How can I achieve this ?

Ok, I found my solution by doing more research.

So it turns out you don’t need to use dynamic on the dimensions block. You can supply a variable of type map(string) like so:

        dimensions = {
          InstanceId = "id"
        }

and then in the resource dimensions = var.dimensions