Okta の Application の グループ割り当てに Terraform を使うとこれだけ楽になる話

2021/12/16に公開

こんにちは

世のすべての SaaS は Terraform で管理できるようになってほしいと思ってるしもしゃん(@shimosyan)です。

こちらは 、Okta Advent Calendar 2021 16日目の記事となります!

今回は、先日 Okta を Terraform と GitHub Actions を使ってコード管理するチュートリアル で書いた Okta の管理を Terraform を使って管理しやすくする方法で「こんな使い方もできるよ!」といった Tips を紹介できたらと思います。

Okta でミスると怖いところ、Terraform で解決したいところ

Okta と SaaS を連携しようとすると、Okta 側では Application で対象の SaaS を誰がどう使えるかに関する設定を行うと思います。

このとき、Okta のユーザーと Application を紐付けるときは、Application の中にある Assignments にユーザーもしくはグループを紐付けると思います。

特に、その SaaS が Provisioning にも対応している場合はこの Assignments ユーザー・グループを紐付けるときに適用するライセンスやロールを設定することができます。
この場合は、グループ単位で割り当てたほうが遥かに楽になるのでそれをする人が多いと思います。

このグループでの割り当ては優先度の概念があり、ライセンスやロールを当てる設定もこの優先度を活用して行われるかと思いますが、この優先度の変え方はドラッグアンドドロップで行われます。

Okta の Assignments 画面

割り当てるグループ数が数個程度だったら大きな問題はなかったのですが、作り込まれてくると数十のグループが登録されなかなかカオスな状態になってきました。

並び替えに画面のスクロールを要して操作しづらい、並び位置が違う、うっかり操作ミスで並び替えを変えてしまう、並び替えのたびに SaaS にプロビジョニング処理されて意図しない同期がされるなど、手作業では大変辛くなってきたので、これを解決したいと思います。

そこで本記事はこの Assignments の割り当てを Terraform で実装する方法をご紹介します!

準備

環境の準備は以下の記事をご覧ください。

実装

Terraform のサンプルコード全体です。Terraform の配列や繰り返し処理をふんだんに使っています。

./app_assignments.tf
# 割り当てるグループを作成
resource "okta_group" "priority_high" {
  name        = "優先度が高いグループ"
  description = ""
}

resource "okta_group" "priority_low" {
  name        = "優先度が低いグループ"
  description = ""
}

# 割り当てるグループを配列を使って指定
locals {
  test_app_group_assignments = [
    {
      id = okta_group.priority_high.id # 優先度が高いグループ
    },
    {
      id = okta_group.priority_low.id  # 優先度が低いグループ
    },
  ]
}

# Okta の Application を参照
data "okta_app" "test" {
  label = "Test"
}

# Application の Assignment を設定
resource "okta_app_group_assignments" "test" {
  app_id = data.okta_app.test.id

  # group ブロックを配列から展開
  dynamic "group" {
    for_each = local.test_app_group_assignments

    content {
      id       = group.value["id"]
      priority = group.key + 1
      # profile = プロビジョニングに必要な追加パラメータ(JSON形式)
    }
  }
}

以降はこれを要素ごとに解説していきます。

グループの作成

resource "okta_group" "priority_high" {
  name        = "優先度が高いグループ"
  description = ""
}

resource "okta_group" "priority_low" {
  name        = "優先度が低いグループ"
  description = ""
}

Okta のグループを作成しています。

割り当てるグループを配列を使って指定

locals {
  test_app_group_assignments = [
    {
      id = okta_group.priority_high.id # 優先度が高いグループ
    },
    {
      id = okta_group.priority_low.id  # 優先度が低いグループ
    },
  ]
}

Terraform の locals 句を使って、Assignments に割り当てるグループを指定する配列を生成しています。

Okta の Application を参照

data "okta_app" "test" {
  label = "Test"
}

今回は Applications の設定そのものは Terraform ではなく Okta で手動で作成した想定です。

このあと記述する okta_app_group_assignments にて割り当てる Applications app_id を指定する必要がありますが、Terraform から作成していないため ID を Okta から取得する必要があります。

そのため、data 句を使うことで Okta にある Applications から、Application 名が label に指定した文字列に一致するものをルックアップしてそれらのプロパティを Terraform で使えるようにします。

Application の Assignment を設定

resource "okta_app_group_assignments" "test" {
  app_id = data.okta_app.test.id

  # group ブロックを配列から展開
  dynamic "group" {
    for_each = local.test_app_group_assignments

    content {
      id       = group.value["id"]
      priority = group.key + 1
      # profile = プロビジョニングに必要な追加パラメータ(JSON形式)
    }
  }
}

Application に グループを割り当てる定義です。

本来、okta_app_group_assignments は以下のように割当グループのアサインを行います

resource "okta_app_group_assignments" "test" {
  app_id = data.okta_app.test.id

  group {
    id       = okta_group.priority_high.id
    priority = 1
  }
  group {
    id       = okta_group.priority_low.id
    priority = 2
  }
}

しかし、途中に別のグループが追加されると、priority の値が振り直しになってしまい保守しにくくなっています。

そのためグループ情報を配列に格納し group ブロックの定義は配列から自動展開するように工夫しています。

配列の index がそのまま priority の値になるので、配列の順序は注意しなければなりません。

また、該当の Application が Provisioning に対応している場合、ライセンスやロールの情報が追加で必要になることがあります。

その場合は、profile プロパティに JSON 形式でパラメータを埋め込んでください。

必要な JSON は Application ごとに異なるため、仕様を調べる必要があります。

最後に

今回は Terraform を使って、Okta の Assignments のコード化を実現しました!

特に、Organization Units が大量にある Google Workspace や ライセンス、ロールが複数組み合わせがある Microsoft 365 の Provisioning に大きく貢献できるかと思います!

Terraform を使うと、手作業では大変な作業を確実に行えることができます。
手作業で辛い思いをしている方の助けとなれば幸いです!

GitHubで編集を提案

Discussion