Val Berthe
Val Berthe

Reputation: 2054

How to link an AWS CloudWatch Alarm to an AWS Route53 Health Check using Terraform?

I am currently setting up an AWS CloudWatch Alarm detecting the health status of my server with Terraform. The health status is checked with an AWS Route 53 Health Check. My .tf file is :

resource "aws_cloudwatch_metric_alarm" "val1-alarm" {
  alarm_name = "val-alarm"
  comparison_operator = "LessThanOrEqualToThreshold"
  evaluation_periods = "2"
  metric_name = "HealthCheckStatus"
  namespace = "AWS/Route53"
  period = "60"
  statistic = "Minimum"
  threshold = "0"
  dimensions {
    HealthCheckId = "${aws_route53_health_check.val1-hc.id}"
  }
  alarm_description = "This metric monitor whether the server is down or not."
  insufficient_data_actions = []
}

resource "aws_route53_health_check" "val1-hc" {
  fqdn = "${aws_route53_record.val1-record.name}"
  port = 27017
  type = "TCP"
  failure_threshold = "3"
  request_interval = "30"
  measure_latency = 1
  cloudwatch_alarm_name = "${aws_cloudwatch_metric_alarm.val1-alarm.alarm_name}"
  cloudwatch_alarm_region = "eu-central-1"
}

I have this error when applying :

Cycle: aws_route53_health_check.val1-hc, aws_cloudwatch_metric_alarm.val1-alarm

Cycle means that each resource calls the other. When I try to remove cloudwatch_alarm_name and cloudwatch_alarm_region from the health check, a terraform error prompts that i need those two arguments (even though the doc specifies that those two are optional). How to fix that ?

Any help or suggestions are highly appreciated !

Upvotes: 1

Views: 3418

Answers (4)

null
null

Reputation: 4360

Note that you need to have your resources in US East (N. Virginia) since:

Amazon Route 53 metrics are not available if you select any other region as the current region.

Source: Monitoring Health Check Status and Getting Notifications.

I managed to make it work with eu-west-1 with this module:

variable "environment" {}
variable "domain_name" {}
variable "resource_path" {}

provider "aws" {
  alias  = "use1"
  region = "us-east-1"
}

resource "aws_route53_health_check" "health_check" {
  fqdn              = "${var.domain_name}"
  port              = 443
  type              = "HTTPS"
  resource_path     = "${var.resource_path}"
  measure_latency   = true
  request_interval  = 30
  failure_threshold = 3

  tags = {
    Name        = "${var.environment}"
    Origin      = "terraform"
    Environment = "${var.environment}"
  }
}

resource "aws_sns_topic" "topic" {
  name     = "${var.environment}-healthcheck"
  provider = "aws.use1"
}

resource "aws_cloudwatch_metric_alarm" "metric_alarm" {
  provider                  = "aws.use1"
  alarm_name                = "${var.environment}-alarm-health-check"
  comparison_operator       = "LessThanThreshold"
  evaluation_periods        = "1"
  metric_name               = "HealthCheckStatus"
  namespace                 = "AWS/Route53"
  period                    = "60"
  statistic                 = "Minimum"
  threshold                 = "1"
  insufficient_data_actions = []
  alarm_actions             = ["${aws_sns_topic.topic.arn}"]
  alarm_description         = "Send an alarm if ${var.environment} is down"

  dimensions {
    HealthCheckId = "${aws_route53_health_check.health_check.id}"
  }
}

Upvotes: 7

prowla
prowla

Reputation: 191

namespace = "AWS/Route53"

Upvotes: 0

Michael Peterson
Michael Peterson

Reputation: 11

On Terraform 0.9.3, I had to do the opposite and remove cloudwatch_alarm_name and cloudwatch_alarm_region from the aws_route53_health_check resource to get the alarm to connect to the health check. It felt backwards. The HealthCheckId dimension was enough to wire them together.

resource "aws_cloudwatch_metric_alarm" "val1-alarm" {
  alarm_name = "val-alarm"
  comparison_operator = "LessThanOrEqualToThreshold"
  evaluation_periods = "2"
  metric_name = "HealthCheckStatus"
  namespace = "AWS/Route53"
  period = "60"
  statistic = "Minimum"
  threshold = "0"
  dimensions {
    HealthCheckId = "${aws_route53_health_check.val1-hc.id}"
  }
  alarm_description = "This metric monitor whether the server is down or not."
  insufficient_data_actions = []
}

resource "aws_route53_health_check" "val1-hc" {
  fqdn = "${aws_route53_record.val1-record.name}"
  port = 27017
  type = "TCP"
  failure_threshold = "3"
  request_interval = "30"
  measure_latency = 1
}

Upvotes: 1

Marc Young
Marc Young

Reputation: 4012

You can't ref A from B and B from A.

Remove the reference from aws_cloudwatch_metric_alarm.val1-alarm such:

resource "aws_cloudwatch_metric_alarm" "val1-alarm" {
  alarm_name = "val-alarm"
  comparison_operator = "LessThanOrEqualToThreshold"
  evaluation_periods = "2"
  metric_name = "HealthCheckStatus"
  namespace = "AWS/Route53"
  period = "60"
  statistic = "Minimum"
  threshold = "0"
  alarm_description = "This metric monitor whether the server is down or not."
  insufficient_data_actions = []
}

resource "aws_route53_health_check" "val1-hc" {
  fqdn = "${aws_route53_record.val1-record.name}"
  port = 27017
  type = "TCP"
  failure_threshold = "3"
  request_interval = "30"
  measure_latency = 1
  cloudwatch_alarm_name = "${aws_cloudwatch_metric_alarm.val1-alarm.alarm_name}"
  cloudwatch_alarm_region = "eu-central-1"
}

See CloudWatch Alarm Example from here

Upvotes: 1

Related Questions