3.8.5¶
Release Date: August 28, 2026
🐛 Bug Fixes¶
Terraform Modules¶
Avoid A Depends_on Cycle In Saif-Application-Permissions 🔗¶
Module: saif-application-permissions
PR: #1080
Fixes a Terraform Error: Cycle on terraform apply:
Error: Cycle:
module.saif-appservices (close)
module.saif-appservices.module.external_identity (close)
module.application_permissions.local.application_name (expand)
...
saif-application-permissions looked up its target Entra application by display name via a data source, so callers added a coarse module-level depends_on = [module.saif-appservices] to sequence the apply. That forces Terraform to fully settle every resource inside saif-appservices — including unrelated ones, like external-identity's Okta Key Vault secret role assignments — before touching anything in application_permissions. When resources in both module trees are being replaced (destroy+create) in the same apply, Terraform cannot linearize the graph across that coarse boundary and reports a cycle.
The module now accepts optional application ({ id, client_id }) and service_principal ({ object_id, client_id }) identity objects so callers can pass the identity directly (e.g. module.saif-appservices.application_id), creating a precise attribute-level dependency instead of the module-level depends_on, and skipping the display-name/service-principal lookups when provided. Identity is modeled as a single nullable object per concept, rather than separate string and boolean inputs, so count can safely branch on the object being null even when its attribute values are unknown at plan time — an object literal with unknown attributes is still a known, non-null value, avoiding an "Invalid count argument" error. A validation block on each variable rejects an incomplete identity (e.g. { id = null, client_id = null }) with an actionable error instead of letting a null reach the nested permissions submodule.
The fix also closes an ID-format bug caught during review: the AzureAD data source's .id attribute is the Graph resource path /applications/{object_id}, not the bare object GUID (.object_id). Mixing the two formats between the fallback (data source) and passthrough (var.application.id) code paths would have changed the uuidv5 seeds used to derive existing app role and scope GUIDs on the next apply, forcing DeleteThenCreate of every app role/scope and breaking anything pinned to the old GUIDs (e.g. role assignments, pre-authorizations).
src/templates/saif-feature-api, the aspire-config and aspire-blobstorage Foundry examples, and the forge-v2-to-v3 migration guide now pass the new application/service_principal objects from module.saif-appservices and drop the depends_on = [module.saif-appservices] block.
Action required: the application-permissions module version constraint must be >= 3.8.5, < 4.0.0 to use the new application/service_principal inputs. Projects with an older 3.x version of the module already initialized should run terraform init -upgrade after updating the constraint.
🔄 Breaking Changes¶
None in this release ✅
📋 Additional Notes¶
- Total commits: 1
- Contributors: Brian Sheridan, Emmitt Johnson
Support¶
- 📧 Teams Support Channel: Support