Skip to content

RELOPS-2345: import and manage all Entra ID groups and role assignments in azure_ad#294

Merged
markcor merged 4 commits into
masterfrom
RELOPS-2345
May 5, 2026
Merged

RELOPS-2345: import and manage all Entra ID groups and role assignments in azure_ad#294
markcor merged 4 commits into
masterfrom
RELOPS-2345

Conversation

@markcor
Copy link
Copy Markdown
Contributor

@markcor markcor commented Apr 28, 2026

Brings the terraform/azure_ad module up to date with the current state of Entra ID, per the RELOPS-2345 audit.

What changed

groups.tf

  • Converts 4 existing data "azuread_group" lookups (Relops, Releng, Taskcluster, InfraSec) to owned azuread_group resources
  • Adds 15 additional groups that existed in Azure but had no Terraform representation: CI Billing, WindowsTesters, Firefox Enterprise/Desktop VMs, Cognitive Services, Data SRE, Passkey_PoC, macOS Windows SSO Testing, Service Desk, WebRTC, Policy Testing, SEIO, MS Store Publishers, MS Store Finance, 0DIN
  • Each group follows the existing 0DIN pattern: azuread_group + data "azuread_user" (UPN → object ID) + azuread_group_member
  • Drops Managed_by_relops tracking group; ownership is now expressed via a "Managed by RelOps — <purpose>" description on each group
  • Security Engineering is intentionally excluded — the group never existed in Azure; to be created in a follow-up ticket

rbac.tf

  • Fixes azuread v3 breaking change: data "azuread_directory_role"resource "azuread_directory_role" for Billing Admin

  • Codifies existing Azure role assignments (built-in roles already granted to these groups in Azure) that were missing from rbac.tf — no new permissions granted:

    Group Role Scope
    Relops Contributor FXCI, Trusted FXCI, 0DIN, FF Non-CI
    Relops Billing Reader FXCI, FF Non-CI
    Relops Security Reader FXCI, FF Non-CI
    Relops User Access Administrator FXCI, FF Non-CI
    Relops Azure Event Hubs Data Sender FF Non-CI
    CI Billing Billing Administrator (directory role) tenant-wide
    CI Billing Cost Management Contributor FXCI, Trusted FXCI, FF Non-CI
    Firefox Enterprise VMs Contributor FF Non-CI
    Cognitive Services Contributor, Cognitive Services Contributor, Cognitive Services Custom Vision Contributor FF Non-CI
    Data SRE Contributor FF Non-CI
    Taskcluster Contributor TCEng
    SEIO Contributor FXCI

tenant_variables.tf

  • Adds a list(string) membership variable for each group

terraform.tfvars

  • Populates UPN lists for all 19 groups with members verified against Entra ID
  • Fixes 4 UPNs that were incorrectly inferred from display names: dkirchner, nfurlan, rbaffourawuah, shong

State

All groups, memberships (62 records), and role assignments have been imported into Terraform state. terraform plan produces 0 to add, 19 to change, 0 to destroy — the 19 changes are description field additions on existing groups.

Test plan

  • All 19 groups imported
  • All 62 group memberships imported
  • All existing role assignments imported
  • UPNs verified against Entra ID
  • terraform plan: 0 to add, 19 to change, 0 to destroy
  • terraform apply

🤖 Generated with Claude Code

markcor and others added 4 commits April 28, 2026 15:00
Brings 20 Entra ID security groups under Terraform management in the
azure_ad module. Converts existing data sources (Relops, Releng,
Taskcluster, InfraSec) to owned resources, adds 16 new groups, and
codifies all RBAC role assignments sourced from the RELOPS-2345 audit.

- groups.tf: adds azuread_group + azuread_user + azuread_group_member
  for each group following the existing 0DIN pattern; ownership marked
  via "Managed by RelOps" description instead of a separate
  Managed_by_relops group
- rbac.tf: drops stale data source blocks; adds missing Relops roles
  (Billing Reader, Security Reader, User Access Admin, Event Hubs Data
  Sender), Taskcluster Contributor on TCEng, and assignments for
  Security Engineering, Cognitive Services, Data SRE, and SEIO
- tenant_variables.tf: membership variables for all 20 groups
- terraform.tfvars: empty membership stubs with az CLI commands and
  known display names; populate UPNs before applying

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Fills in best-guess UPNs from display names recorded in the RELOPS-2345
audit. All entries need verification against actual Azure AD values via
az ad group member list before applying.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Fix 4 incorrect UPNs in terraform.tfvars (dkirchner, nfurlan,
  rbaffourawuah, shong — were inferred from display names incorrectly)
- Fix azuread v3 breaking change: data "azuread_directory_role" ->
  resource "azuread_directory_role" for billing_admin in rbac.tf
- Fix for_each on service_desk_membership for azuread v3 empty-group
  workaround
- Remove security_engineering group/role assignments — group never
  existed in Azure; defer to a separate ticket
- Import all existing role assignments and ms_store group memberships
  into Terraform state (plan now shows 0 to add, 19 to change, 0 to
  destroy — changes are description field updates only)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@markcor markcor changed the title RELOPS-2345: import and manage all Entra ID groups in azure_ad RELOPS-2345: import and manage all Entra ID groups and role assignments in azure_ad May 4, 2026
@markcor markcor requested a review from jwmossmoz May 4, 2026 22:03
@markcor
Copy link
Copy Markdown
Contributor Author

markcor commented May 4, 2026

terraform plan output

Terraform will perform the following actions:

  # azuread_group.ci_billing will be updated in-place
  ~ resource "azuread_group" "ci_billing" {
      ~ description = "Access to Azure Spend" -> "Managed by RelOps — Azure CI billing access"
        id          = "/groups/75c5b6fc-747c-46ba-9a09-75af575ceda0"
        # (29 unchanged attributes hidden)
    }

  # azuread_group.cognitive_services will be updated in-place
  ~ resource "azuread_group" "cognitive_services" {
      + description = "Managed by RelOps — Cognitive Services team (FF Non-CI access)"
        id          = "/groups/40714393-f348-4ea8-9d54-66f7346f3b54"
        # (29 unchanged attributes hidden)
    }

  # azuread_group.data_sre will be updated in-place
  ~ resource "azuread_group" "data_sre" {
      ~ description = "Data SRE" -> "Managed by RelOps — Data SRE team (FF Non-CI access)"
        id          = "/groups/fbb8eb81-16b5-4862-bdff-4f437d74a839"
        # (29 unchanged attributes hidden)
    }

  # azuread_group.firefox_desktop_vms will be updated in-place
  ~ resource "azuread_group" "firefox_desktop_vms" {
      + description = "Managed by RelOps — Firefox Desktop VM access"
        id          = "/groups/f930ffac-0fb8-4bab-acb4-f5c5fb997c65"
        # (29 unchanged attributes hidden)
    }

  # azuread_group.firefox_enterprise_vms will be updated in-place
  ~ resource "azuread_group" "firefox_enterprise_vms" {
      + description = "Managed by RelOps — Firefox Enterprise VM access"
        id          = "/groups/a0a33561-2a64-47a4-b934-5afa6772bb48"
        # (29 unchanged attributes hidden)
    }

  # azuread_group.infrasec will be updated in-place
  ~ resource "azuread_group" "infrasec" {
      + description = "Managed by RelOps — Infrastructure Security Team"
        id          = "/groups/d5f6266b-0286-4181-a8a4-c10d3de583f2"
        # (29 unchanged attributes hidden)
    }

  # azuread_group.macos_windows_sso_testing will be updated in-place
  ~ resource "azuread_group" "macos_windows_sso_testing" {
      + description = "Managed by RelOps — macOS/Windows SSO testing group"
        id          = "/groups/582f38ff-aae7-4595-8d88-e0ef49f66bca"
        # (29 unchanged attributes hidden)
    }

  # azuread_group.ms_store_finance will be updated in-place
  ~ resource "azuread_group" "ms_store_finance" {
      ~ description = "Users are assigned the Finance Contributor role which allows access to MS Store Acquisitions reports." -> "Managed by RelOps — Microsoft Store finance access (Partner Center)"
        id          = "/groups/03a6d47d-3f67-4f74-8be9-16a5ba15d833"
        # (29 unchanged attributes hidden)
    }

  # azuread_group.ms_store_publishers will be updated in-place
  ~ resource "azuread_group" "ms_store_publishers" {
      ~ description = "Users can publish to the Microsoft Store" -> "Managed by RelOps — Microsoft Store publishing access (Partner Center)"
        id          = "/groups/7d6ef4bb-6fb0-46cb-b9c6-f42c0ef1675a"
        # (29 unchanged attributes hidden)
    }

  # azuread_group.passkey_poc will be updated in-place
  ~ resource "azuread_group" "passkey_poc" {
      + description = "Managed by RelOps — Passkey proof-of-concept group"
        id          = "/groups/ca61d3fd-3feb-4ef4-9539-943db3f7605e"
        # (29 unchanged attributes hidden)
    }

  # azuread_group.policy_testing will be updated in-place
  ~ resource "azuread_group" "policy_testing" {
      ~ description = "Used by Michael Kaply for Enterprise Policy Testing" -> "Managed by RelOps — Firefox enterprise policy testing group"
        id          = "/groups/e82044cc-48c8-406f-bd9d-2ac12055725b"
        # (29 unchanged attributes hidden)
    }

  # azuread_group.releng will be updated in-place
  ~ resource "azuread_group" "releng" {
      ~ description = "Release engineering " -> "Managed by RelOps — Release Engineering team"
        id          = "/groups/848f45ae-56a8-45ef-bb46-3f937de8efd1"
        # (29 unchanged attributes hidden)
    }

  # azuread_group.relops will be updated in-place
  ~ resource "azuread_group" "relops" {
      + description = "Managed by RelOps — RelOps team members"
        id          = "/groups/cb79b99f-fdaa-4e0d-a2c8-c5841890fa74"
        # (29 unchanged attributes hidden)
    }

  # azuread_group.seio will be updated in-place
  ~ resource "azuread_group" "seio" {
      + description = "Managed by RelOps — SEIO group"
        id          = "/groups/eb466fea-802a-4e99-bd06-0f64032ae24c"
        # (29 unchanged attributes hidden)
    }

  # azuread_group.service_desk will be updated in-place
  ~ resource "azuread_group" "service_desk" {
      ~ description = "Service Desk / Non-priveldge user administration" -> "Managed by RelOps — Service Desk group"
        id          = "/groups/b43de574-594d-4037-b87a-8184540d5a59"
        # (29 unchanged attributes hidden)
    }

  # azuread_group.tceng will be updated in-place
  ~ resource "azuread_group" "tceng" {
      ~ description = "Taskcluster" -> "Managed by RelOps — Taskcluster Engineering team"
        id          = "/groups/198f2a2b-48bd-423d-92cd-3559ee3f3dd7"
        # (29 unchanged attributes hidden)
    }

  # azuread_group.webrtc_group will be updated in-place
  ~ resource "azuread_group" "webrtc_group" {
      + description = "Managed by RelOps — WebRTC team group"
        id          = "/groups/f9aba857-fb40-4888-b8c0-af97d7cda363"
        # (29 unchanged attributes hidden)
    }

  # azuread_group.windows_testers will be updated in-place
  ~ resource "azuread_group" "windows_testers" {
      ~ description = "Group that contains members who have VMs for manual testing" -> "Managed by RelOps — members with Windows VMs for manual testing"
        id          = "/groups/b99a33cb-637e-4884-8aea-80cf43c530f6"
        # (29 unchanged attributes hidden)
    }

  # azuread_group.zero_din will be updated in-place
  ~ resource "azuread_group" "zero_din" {
      ~ description = "Terraform-managed Azure AD group for 0DIN members" -> "Managed by RelOps — 0DIN project members"
        id          = "/groups/3992d632-1c36-47e2-9d30-46bd9b4ebc01"
        # (29 unchanged attributes hidden)
    }

Plan: 0 to add, 19 to change, 0 to destroy.

Warning: azuread_directory_role_member is deprecated — use azuread_directory_role_assignment instead (cosmetic, does not affect apply).

All 19 changes are description field updates on existing groups. No resources added or destroyed.

@markcor markcor merged commit 5a5085f into master May 5, 2026
1 check passed
@markcor markcor deleted the RELOPS-2345 branch May 5, 2026 16:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants