0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

terraformリソースでcountとfor_eachを併用して簡単にリソースを作成したかった話

Last updated at Posted at 2024-09-13

はじめに

業務の中でterraformを触る機会がありこの書き方いいなと思ったので備忘録です。

背景&課題

今回はdatadogでprd, pilot以外の環境で、hogehoge-api-web, hogehoge-api-appのような末尾のprefixだけが異なるサービスに対してダウンタイムを作成したいタイミングがありました。
それぞれ冗長にダウンタイムを作成してもいいですが、冗長になってしまうため、1つの定義で2つのマイクロサービスに対してのダウンタイムを作成したいという課題がありました。

いつもは、countで作成する環境を限定。for_eachで末尾のprefixが異なるサービスのモニターを作成しており、countとfor_eachは併用できるものと考えていました。

しかし、以下のようにcountとfor_eachは併用することができません

resource "datadog_downtime_schedule" "downtime-template" {
 // count と for_eachは併用できない
  count                            = "${local.env}" == "prd" || "${local.env}" == "pilot" ? 0 : 1
  for_each                         = local.application_name
  // 以下省略
}

エラー

併用した場合以下のようなエラーが発生してしまいます。

│ Error: Invalid combination of "count" and "for_each"
│ 
│   on downtime.tf line 4, in resource "datadog_downtime_schedule" "downtime_template":
│    4:   for_each                         = local.application_name
│ 
│ The "count" and "for_each" meta-arguments are mutually-exclusive, only one should be used to be explicit about the number of
│ resources to be created.

解決策

先輩社員からアドバイスをいただき、以下のような感じで、環境に該当する場合は空配列を返すようにしました。(こういう書き方もできるんですね〜)

for_each                         = "${local.env}" == "prd" || "${local.env}" == "pilot" ? {} : local.application_name

完成系

locals {
  service_name     = "hogehoge-api"
  application_name = {
    web = {
      fugahoge = xxx
    },
    app = {
      fugahoge = xxx
    }
  }
}

resource "datadog_downtime_schedule" "downtime-template" {
  for_each                         = "${local.env}" == "prd" || "${local.env}" == "pilot" ? {} : local.application_name
  scope                            = "*"
  message                          = "[${local.env}] ${local.service_name}-${each.key} scheduled downtime"
  mute_first_recovery_notification = false
  notify_end_states                = ["no data", "alert", "warn"]
  notify_end_types                 = ["expired"]
  recurring_schedule {
    recurrence {
      duration = "450m" # Everyday 0:00 - 7:30 JST (specified in UTC)
      rrule    = "FREQ=DAILY;INTERVAL=1"
      start    = "2024-09-16T15:00:00" # JST 2024-09-17 00:00
    }
    recurrence {
      duration = "3330m" # SAT 0:00 - MON 7:30 JST (specified in UTC)
      rrule    = "FREQ=WEEKLY;INTERVAL=1"
      start    = "2024-09-13T15:00:00" # JST 2024-09-14 00:00
    }
  }
  monitor_identifier {
    monitor_tags = [
      "env:${local.env}",
      "service:${local.service_name}-${each.key}",
      "downtime-for-cost:true"
    ]
  }
}
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?