joana
joana

Reputation: 23

Repeated GCP alert conditions terraform block - how to extract them into a constant?

I am setting up several alarms in terraform and several have the same policy. Can I extract it into some kind of variable so that I don't have to hardcode it into every alarm? Alarms will have other conditions besides that common one.

Example:

resource "google_monitoring_alert_policy" "alert_policy_1" {
  display_name = "My Alert Policy 1"
  combiner     = "OR"
  conditions {
    display_name = "test condition"
    condition_threshold {
      filter     = "metric.type=\"compute.googleapis.com/instance/disk/write_bytes_count\" AND resource.type=\"gce_instance\""
      duration   = "60s"
      comparison = "COMPARISON_GT"
      aggregations {
        alignment_period   = "60s"
        per_series_aligner = "ALIGN_RATE"
      }
    }
  }

conditions {
    display_name = "test condition 2"
    condition_threshold {
      filter     = "metric.type=\"compute.googleapis.com/instance/disk/write_bytes_count\" AND resource.type=\"gce_instance\""
      duration   = "60s"
      comparison = "COMPARISON_GT"
      aggregations {
        alignment_period   = "60s"
        per_series_aligner = "ALIGN_RATE"
      }
    }
  }

  user_labels = {
    foo = "bar"
  }
}

resource "google_monitoring_alert_policy" "alert_policy_2" {
  display_name = "My Alert Policy 2"
  combiner     = "OR"
  conditions {
    display_name = "test condition"
    condition_threshold {
      filter     = "metric.type=\"compute.googleapis.com/instance/disk/write_bytes_count\" AND resource.type=\"gce_instance\""
      duration   = "60s"
      comparison = "COMPARISON_GT"
      aggregations {
        alignment_period   = "60s"
        per_series_aligner = "ALIGN_RATE"
      }
    }
  }

  user_labels = {
    foo = "bar"
  }
}

Can I avoid repeating test condition here?

Upvotes: 0

Views: 609

Answers (1)

Jake Nelson
Jake Nelson

Reputation: 2043

You can use a combination of local values and nested dynamic blocks to achieve this but to be honest, you'd end up with far more code than just putting in the values as you have them.

An alternative would be to use Terraform templating but then it's not as clear or declarative.

Another alternative would be to abstract with a module and within the module documentation provide a list of common conditions you're providing with the abstraction.

The module then handles all the messy nested dynamic blocks and loops that might be required.

After writing the module, your calling/config code in this case might be something like:

module "alert_policy_1" {
  source = ../modules/common-alerts

  display_name = "My Alert Policy 1"
  combiner     = "OR"
  
  # use dynamic blocks within the module to handle nested values in for an array of custom conditions
  custom_conditions = [
    {
      display_name = "test condition"
      condition_threshold {
        filter     = "metric.type=\"some different and unique metric" AND resource.type=\"gce_instance\""
        duration   = "60s"
        comparison = "COMPARISON_GT"
        aggregations {
          alignment_period   = "60s"
          per_series_aligner = "ALIGN_RATE"
        }
      }
    }
  ]

  # the module then has a documented list of common policies to consume
  common_conditions = [
    "google_compute_write_bytes_count"
  ]

  user_labels = {
    foo = "bar"
  }
}

module "alert_policy_2" {
  source = ../modules/common-alerts

  display_name = "My Alert Policy 2"
  combiner     = "OR"
  common_conditions = [
    "google_compute_write_bytes_count"
  ]

  user_labels = {
    foo = "bar"
  }
}

# if OR is common and as are the user labels they could be provided by module variable defaults.

module "alert_policy_3" {
  source = ../modules/common-alerts

  display_name = "My Alert Policy 3"  
  common_conditions = [
    "google_compute_write_bytes_count"
  ]
}

Upvotes: 1

Related Questions