👻

CSVファイルでCloudWatch Alarmを設定 with Terraform

2024/04/24に公開

初めに

本ページでは、CSVファイルを用いてCloudWatch Alarm(以下、「CW alarm」)を設定する方法について記述する。 CW AlarmをTerraformのコード上で管理しようとすると、莫大な量のコードを記述する必要がある。そのため、対象リソースや閾値の設定を確認がしづらい。
そこで、エクセル等(CSVファイル)で管理されたCW Alarm一覧をTerraformに読み込み、CW Alarmを設定するmoduleの作成手順を説明する。
アラームの設定自体は以下のGitHubのmoduleを呼び出すことで簡単にセットアップできるが、本ページでは、moduleの作成手順を示すことで、各コードの説明をしている。
https://github.com/proyogram/aws-terraform-monitor/tree/main/modules/cw_alarm_settting_by_csv

やること

手順1. CSVファイルを作成
手順2. TerraformでCSVファイルを読み込む
手順3. TerraformでCW Alarmを設定

作成手順

手順1. CSVファイルを作成

  1. csvというディレクトリを作成する。(任意であるが、管理性を考慮して作成)
  2. リポジトリを参考に以下2つのCSVファイルを作成し、csv配下に格納する。
    • cw_alarm.csv : 通常のアラーム設定
    • cw_math_alarm.csv : Metric Mathを用いたアラーム設定
  3. これらのCSVファイルは、用意した スプレッドシート から簡単に生成できる。各値の意味もスプレッドシートに記載しているので適宜参照する。

手順2. TerraformでCSVファイルを読み込む

  1. 作成したCSVファイルは以下のTerraformコード(csvと同階層に配置)で読み込み、localsに格納する。
locals.tf
locals {
  alarm = csvdecode(file("${path.module}/csv/cw_alarm.csv"))
}

locals {
  math_alarm = csvdecode(file("${path.module}/csv/cw_math_alarm.csv"))
}

手順3. GitHubからTerraformのコードを取得し、リソースを作成

  1. (事前準備)CW Alarm用のSNSもTerraform(csvと同階層に配置)で作成しておく。以下のコードによって作成する。
cw_sns.tf
resource "aws_sns_topic" "main" {
  name = "${var.prefix}-topic"
}

resource "aws_sns_topic_policy" "main" {
  arn    = aws_sns_topic.main.arn
  policy = data.aws_iam_policy_document.sns_topic_policy.json
}
  1. localsの値は以下のTerraformコード(csvと同階層に配置)によって一行ずつ読み込まれ、CW Alarmに設定される。
main_cw.tf
resource "aws_cloudwatch_metric_alarm" "alarm" {
  for_each = { for alarm in local.alarm : alarm.id => alarm }

  alarm_name          = each.value.alarm_name
  comparison_operator = each.value.comparison_operator
  evaluation_periods  = each.value.evaluation_periods
  metric_name         = each.value.metric_name
  namespace           = each.value.namespace
  period              = each.value.period
  statistic           = each.value.statistic
  threshold           = each.value.threshold
  alarm_description   = each.value.alarm_description
  dimensions          = jsondecode("${each.value.dimensions}")
  alarm_actions       = [aws_sns_topic.main.arn]
}

resource "aws_cloudwatch_metric_alarm" "math_alarm" {
  for_each = { for math_alarm in local.math_alarm : math_alarm.id => math_alarm }

  alarm_name          = each.value.name
  comparison_operator = each.value.comparison_operator
  evaluation_periods  = each.value.evaluation_periods
  threshold           = each.value.threshold
  alarm_description   = each.value.alarm_description
  alarm_actions       = [aws_sns_topic.main.arn]

  metric_query {
    id          = "e1"
    expression  = each.value.expression
    label       = each.value.label
    return_data = "true"
  }

  metric_query {
    id = "m1"

    metric {
      metric_name = each.value.metric_name_m1
      namespace   = each.value.namespace_m1
      period      = each.value.period_m1
      stat        = each.value.stat_m1

      dimensions = jsondecode("${each.value.dimensions_m1}")
    }
  }

  metric_query {
    id = "m2"

    metric {
      metric_name = each.value.metric_name_m2
      namespace   = each.value.namespace_m2
      period      = each.value.period_m2
      stat        = each.value.stat_m2

      dimensions = jsondecode("${each.value.dimensions_m2}")
    }
  }
}

※ 本Terraformコードでは、1~2個のmetricにおけるCW Alarmを想定している。3つ以上のmetricを設定したい場合、 resource "aws_cloudwatch_metric_alarm" "math_alarm" の下の行に新たにresource "aws_cloudwatch_metric_alarm" "math_alarm_02" といったresourceを作成し、metric_queryを追加する必要がある。このとき、locals.tfやCSVファイルも修正する必要がある。

以上がCSVファイルでCW Alarmを設定する手順である。
$ terraform plan を実行すると、CSVファイルの値がCW Alarmに設定されたplan結果が確認できる。

まとめ

今回は、CW Alarmを設定する方法を紹介した。AWSでの監視対象が増えるたびに(対象サービス×リソース)個のCW Alarmを作成する必要があるため、IaCで管理するよりエクセル等(CSVファイル)で管理する方がレビューや管理性の観点から良いケースがある。その際に本ページを参考に設定すると良い。

Discussion