opsgenie / terraform-provider-opsgenie

Terraform OpsGenie provider
https://registry.terraform.io/providers/opsgenie/opsgenie/latest/docs
Mozilla Public License 2.0
105 stars 137 forks source link

[feature request] allow explicit ordering for rotation participants #215

Open n-oden opened 3 years ago

n-oden commented 3 years ago

Presently, the members of an opsgenie_schedule_rotation are defined using participant{} blocks, and the order of the rotation is the order in which the participant blocks are added.

This meshes poorly with terraform dynamic blocks, which use the for_each meta-argument to iterate over a set or map of resources and create an instance of the dynamic block for each.

Unfortunately, for_each currently does not support ordered data types: the source variable must be a map or a set of strings. This makes it basically impossible to do what would otherwise seem fairly desirable: auto-populate a rotation based on an externally defined set of users, e.g.:

variable "opsgenie_org" {
  type = map(map(string))
  default = {
    "platform" = {
      "user1@example.com"  = "admin"
      "user2@example.com"  = "admin"
      "user3@example.com" = "user"
    }
    "mgmt" = {
      "mgmt1@example.com" = "admin"
    }
  }
}

locals {
  all_users = toset(flatten([
    for team, userlist in var.opsgenie_org : [
      for user, role in var.opsgenie_org[team] : user
    ]
  ]))
}

data "opsgenie_user" "sso_login" {
  for_each = local.all_users
  username = each.value
}

resource "opsgenie_schedule_rotation" "all-eng-rotation" {
  schedule_id = opsgenie_schedule.all-eng-schedule.id
  name        = "all-eng rotation"
  start_date  = "2020-01-01T17:00:00Z"
  type        = "weekly"
  length      = 1

  dynamic "participant" {
    for_each = local.all_users
    content {
      type = "user"
      id   = data.opsgenie_user.sso_login[participant.key].id
    }
  }
}

There are probably a few ways to skin this cat: I might suggest adding an explicit order attribute to the participant block and have the provider sort on that attribute before making the API request.

This sorta dovetails with https://github.com/opsgenie/terraform-provider-opsgenie/issues/185 -- they're both getting at the fact that presently it's not really possible (or at least unnecessarily difficult) to manage a schedule rotation without resorting to the web UI.

zonArt commented 3 years ago

It's not only an issue of dict ordering but also and mostly the issue with the starting date which you need to set and messes up the whole ordering once you try to add a new participant

bnjns commented 2 years ago

You should be able to workaround this in Terraform by avoiding the toset and instead creating a map, where the key is the stringified index, although it would still be good for the provider to support this natively:

locals {
  user_list = flatten([
    for team, userlist in var.opsgenie_org : [
      for user, role in var.opsgenie_org[team] : user
    ]
  ])
  all_users = { for i, user in local.user_list: i => user }
}

I have to do this quite often with other Terraform providers.