TerraformでPagerDuty設定入門 その2 - ユーザーとTeamを設定

# PagerDutyの設定をTerraformでやってみる

PagerDuty Advent Calendarの14日目！ 今回は実際にPagerDutyの設定をTerraformで行ってみます。

## なにはともあれTerraform Registryをみる

PagerDutyをTerraformで設定したい場合、まず見るべきサイトがTerraform Registryです。

https://registry.terraform.io/providers/PagerDuty/pagerduty/latest/docs

Terraform Registryは、Terraform Providerが管理されている場所であり、ドキュメント置き場でもあります。HashiCorpが提供するオフィシャルProviderから、パートナーが提供するPartner Provider、そしてコミュニティが提供するCommunity Providerまで、Terraform Providerの9割9分はここに集まります。

PagerDuty ProviderはPartner Providerの扱いです。開発はPagerDutyが中心になって行っています。ライセンスはMozilla Public License 2.0のOSSです。

正直なところ、**自分のこの記事を読まなくとも、Terraform RegistryにあるDocsを読めば大体分かります**。

といいつつ、それではさすがに投げっぱなしがすぎるので、今回はよく使うリソースについて解説をしていきます。

## ユーザー

PagerDuty上のユーザーを作成する場合は、 `pagerduty_user` リソースを作成します。

```terraform
resource "pagerduty_user" "jacopen" {
  name  = "Kazuto Kusama"
  email = "jacopen@example.com"
  color = "green"
  role  = "admin"
  time_zone = "Asia/Tokyo"
}
```

`name` と `email` は必須項目です。他はオプションです。

`color` は設定したことない人も多いかと思いますが、スケジュール上に表示される際の色を指定できます。
UI上だとUser SettingsのSchedule Colorとして表示されているものです。
![CleanShot 2024-12-15 at 23.00.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17840/525b931d-e59b-5bd5-501b-4f007db015db.png)

roleはそのユーザーに割り振られるロールを指定します。ただ、ここで指定する値はAPIで指定する値である必要があります。たとえば、UI上の `Global Admin`は、ここでは `admin`と指定します。 `Full Stakeholder`の場合は `read_only_user` となります。
このあたりのUIとAPIの値の対応表は[こちらをご覧ください](https://support.pagerduty.com/main/docs/advanced-permissions#roles-in-the-rest-api-and-saml)。

time_zoneではそのユーザーのタイムゾーンを指定できます。

## チーム

チームを作成する場合は、 `pagerduty_team` リソースを作成します。

```terraform
resource "pagerduty_team" "platform" {
  name        = "Platform Team"
  description = "Platform Team"
}
```

## チームにユーザーを追加

チームにユーザーを割り当てたい場合、 `pagerduty_team_membership` リソースを作成します。

たとえば、先ほど作成した `jacopen` ユーザーを `platform` チームに割り当てたい場合、次のようにします。

```terraform
resource "pagerduty_team_membership" "platform_jacopen" {
  user_id = pagerduty_user.jacopen.id
  team_id = pagerduty_team.platform.id
  role    = "manager"
}
```

## 個別に宣言するのではなくまとめて設定したい場合

User, Team, Team membershipを淡々と設定していっても良いのですが、組み合わせが増えるとちょっとコード量が増えすぎて面倒くさくなるかもしれません。

その場合はTerraformコードのfor_eachを使ってループさせることで記述量を減らせます。

```terraform
locals {
  users = [
    { name = "yusuke", email = "yusuke@example.com", team = ["infra", "k8s"] },
    { name = "kazuki", email = "kazuki@example.com", team = ["infra", "k8s"] },
  ]
  teams = [
    { name = "infra", description = "Infra Team" },
    { name = "k8s", description = "Kubernetes Team" },
  ]

  team_memberships = flatten([
    for user in local.users : [
      for team in user.team : {
        user_name = user.name
        team_name = team
      }
    ]
  ])
}

resource "pagerduty_user" "users" {
  for_each = { for u in local.users : u.name => u }
  name  = each.value.name
  email = each.value.email
}

resource "pagerduty_team" "teams" {
  for_each = { for t in local.teams : t.name => t }
  name        = each.value.name
  description = each.value.description
}

resource "pagerduty_team_membership" "team_membership" {
  for_each = {
    for m in local.team_memberships : "${m.user_name}-${m.team_name}" => m
  }
  user_id = pagerduty_user.users[each.value.user_name].id
  team_id = pagerduty_team.teams[each.value.team_name].id
  role    = "manager"
}
```

localsの中でusersとteamsを設定できるようにしています。各userはteamを設定出来るようにしてあります。
こうすることで、ユーザーやチームを追加した場合でもlocalsの中に項目を追加するだけで、個別にリソースを宣言しなくても良くなります。