Cloudwatch alarm creation fails due to heredoc
Asked Answered
A

3

5

I am trying to create a composite cloudwatch alarm using terraform. But unfortunately my terraform code breaks with the following error:

Error: error creating CloudWatch Composite Alarm (node-count-office-time-composite-alarm-DP-1474-desert): ValidationError: AlarmRule must not contain leading or trailing whitespace or be null status code: 400, request id: 272b14ae-e6bd-4e65-8bb8-25372d9a5f7c

Following is my terraform code:

resource "aws_cloudwatch_composite_alarm" "node_count_office_time_alarm" {
  depends_on = [aws_cloudwatch_metric_alarm.node_count, aws_cloudwatch_metric_alarm.office_time]
  alarm_description = "Composite alarm for node count & office time"
  alarm_name        = "node-count-office-time-composite-alarm-${local.postfix}"
  alarm_actions = [var.sns_topic_arn]
  ok_actions    = [var.sns_topic_arn]
alarm_rule =<<-EOF
ALARM(${aws_cloudwatch_metric_alarm.node_count.alarm_name}) AND
ALARM(${aws_cloudwatch_metric_alarm.office_time.alarm_name})
EOF
}

I checked many times and there are no leading or trailing spaces in my alarm_rule. Only new line after AND operator. I am using terraform 0.15.3 version. Anyone faces similar issues and how can I resolve this issue? thanks

Arlberg answered 17/5, 2021 at 23:19 Comment(0)
A
7

I did not find the solution to how to make the heredoc working. But I fixed it for the time being using direct string expression instead of heredoc block. Following is the string expression:

alarm_rule        = "ALARM(${aws_cloudwatch_metric_alarm.node_count.alarm_name}) AND ALARM(${aws_cloudwatch_metric_alarm.office_time.alarm_name})"

I hope it is useful for others if they face the same issue. thanks

Arlberg answered 18/5, 2021 at 7:52 Comment(0)
A
3

Terraform instructions https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_composite_alarm are not accurate as of this writing in 2021.

alarm_rule accepts a single string argument, EOF/heredoc has to be processed to create a literal string:

locals {
  alarm_rule_with_newlines = <<-EOF
    ALARM(${aws_cloudwatch_metric_alarm.alpha.alarm_name}) OR
    ALARM(${aws_cloudwatch_metric_alarm.bravo.alarm_name})
  EOF
}

[...]

alarm_rule = trimspace(replace(local.alarm_rule_with_newlines, "/\n+/", " "))
Affra answered 28/5, 2021 at 1:16 Comment(0)
M
0

I was not satisfied with neither of proposed answers so I have another solution. Move your composite alert rules to separate file and just read it:

alarm_rule = file("./composite-alert-rule")

or

alarm_rule = templatefile("./composite-alert-rule", { arg = ... })

if you need to pass some dynamic args. Check terraform docs for reference: https://www.terraform.io/language/functions/templatefile
https://www.terraform.io/language/functions/file

Materialist answered 11/7, 2022 at 15:57 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.