Skip to content

3.8.6

Release Date: September 1, 2026


🐛 Bug Fixes

Terraform Modules

Fix Spurious 409 RoleAssignmentExists Errors in saif-resources External Identity 🔧

Module: saif-resources (external-identity module — main.tf)

PRs: #1075, #1077 (backport of fixes already on main)

Fixes a Terraform apply failure:

Error: unexpected status 409 (409 Conflict) with error: RoleAssignmentExists: The role assignment already exists. The ID of the existing role assignment is <guid>.

  with module.saif-appservices.module.external_identity.azurerm_role_assignment.okta_secret_reader["External"],
  on .terraform/modules/saif-appservices.external_identity/modules/external-identity/main.tf line 74, in resource "azurerm_role_assignment" "okta_secret_reader":
  74: resource "azurerm_role_assignment" "okta_secret_reader" {

azurerm_role_assignment.okta_secret_reader and azurerm_role_assignment.oidc_secret_reader had no lifecycle block. The AzureRM provider normalises resource group names to PascalCase in resource_versionless_id (e.g. Shared-Services), but Azure's RBAC API returns the casing used when the assignment was first created (e.g. shared-services). That casing-only diff forced a replacement on every subsequent apply, and the replacement's create collided with the still-existing original assignment, producing the 409. This is the same casing-drift pattern fixed for other role assignments in 3.6.6/3.6.7 and PR #1075, which had not yet reached okta_secret_reader/oidc_secret_reader on this release branch.

Changes:

  • Added lifecycle { ignore_changes = [scope] } to azurerm_role_assignment.okta_secret_reader and azurerm_role_assignment.oidc_secret_reader, suppressing the casing-only diff
  • Added replace_triggered_by = [<the Key Vault secret resource>] alongside it, so a genuine secret replacement (rename or move to a different vault) still forces the role assignment to re-create at the new scope, instead of silently pointing at a stale one

Benefits:

  • 🚫 Eliminates 409 RoleAssignmentExists errors on workspaces using the Okta/OIDC external-identity secrets
  • 🔄 Prevents unnecessary role assignment replacement cycles caused purely by casing drift
  • ✅ Consistent with the guard already applied to client_secret_reader, cookie_secret_user, and cookie_secret_readers

🔄 Breaking Changes

None in this release ✅


📋 Additional Notes

  • Total commits: 2 (backported from main)
  • Contributors: Emmitt Johnson

Support

  • 📧 Teams Support Channel: Support