The Underrated Power of the azuread Terraform Provider
When working with Azure infrastructure, there’s one provider that consistently flies under the radar: the azuread provider. It’s powerful. It’s elegant. And it’s absolutely essential if you care about clean, maintainable Terraform code—especially when dealing with Azure’s identity model.
The Problem: GUID Soup in Terraform
Lukas asked me the other day, “How do people implement RBAC without the azuread provider?”
The answer? Raw GUIDs. In all their opaque, contextless glory.
Can you sense the sarcasm? I hope so.
Anyone who’s spent time building RBAC roles and managing identities in Azure with Terraform knows the pain. You start off with a simple idea: assign roles, define access, move fast. But before you know it, your code is littered with long, unreadable GUIDs. Object IDs here, principal IDs there — raw identifiers scattered like confetti across your infrastructure definitions.
This chaos isn’t limited to just the .tf files either. GUIDs often end up hardcoded in *.tfvars files—the lifeblood of environment configuration in Terraform. These files provide the input values that allow teams to manage multiple environments (e.g., dev, test, prod) using a shared codebase. As you can imagine, access control often varies between these environments. So now you’ve got environment-specific identity GUIDs sprinkled throughout your variable definitions, making them brittle, hard to understand, and a nightmare to maintain.
The Reality: Azure Identity Is Built on Entra ID
This is the part that baffles me the most. Azure’s entire identity and access model — whether you’re assigning roles, granting permissions, or managing enterprise apps — is powered by Entra ID, formerly known as Azure Active Directory. It’s not just a side component. It is the identity layer of Azure.
And yet, many engineers act like the azuread provider doesn’t exist. I’m always shocked at how many folks are unaware of it, or worse—actively avoid using it—preferring instead to hardcode Object IDs and pretend it’s “good enough.”
To be fair, maybe it’s not just ignorance or oversight. In some organizations, there may be structural barriers. Teams might avoid using the azuread provider because their organization isn’t set up to support this workflow—or actively thwarts it out of concern that granting any level of access to the directory is tantamount to handing over the golden goose. In some cases, this reluctance might stem from a lack of granularity in Entra ID’s built-in role definitions. When the only available permission is something like Group.ReadWrite.All, it’s understandable why organizations might hesitate to grant it.
The azuread Provider: Your Identity-Driven Toolkit
Using the azuread provider means you can reference identities by name, not by cryptic Object IDs. It lets you:
- Manage Entra ID applications, groups, and service principals in a human-readable way.
- Integrate seamlessly with Terraform without having to jump through ARM API hoops.
- Write infrastructure code that makes sense to both your team and your future self.
This is especially critical when implementing a comprehensive RBAC strategy that includes both human and machine identities.
Sure, Managed Identities (system- or user-assigned) work smoothly because Azure pokes a hole through the ARM control plane to handle Entra ID behind the scenes. But once you start touching anything beyond that — especially when assigning roles to users or groups — you need to interact directly with the Entra ID control plane. That’s where azuread shines.
And let’s be clear: Infrastructure-as-Code doesn’t have to replace traditional ClickOps-style user management practices. User onboarding and offboarding can still follow established manual or automated workflows. But group creation, lifecycle management, and membership — these are perfect candidates for codification. Unfortunately, the current permission model makes this hard. We shouldn’t have to settle for Group.ReadWrite.All when what we really need is a more scoped permission like Group.ReadWrite.Mine or even Group.ReadWrite.Members. More granular roles would empower teams to build safer automation without sacrificing control.
Breaking Down the Barriers to Adoption
Whatever the current challenges or friction to using the azuread provider—whether it’s policy, process, or platform limitations—we need to come together to remove them. Because the alternative is worse: a sprawling mess of unmanaged permissions and untraceable access paths. Without the ability to manage Entra ID resources declaratively, teams are blocked from fully implementing the principle of least privilege through Infrastructure-as-Code.
This isn’t just a tooling issue. It’s a governance issue. It’s a maturity issue. It’s a blocker to security and scale.
Clean Code, Happy Team
Let’s be real: clean infrastructure code is easier to audit, easier to debug, and easier to maintain. Using the azureadprovider helps you escape the GUID soup and move toward a more intentional, identity-driven infrastructure model.
So do yourself (and your team) a favor. Use it. Love it. Share it.
Work with your organization to safely grant your machine identities the access they need. Invest in managing human identities properly. Push for better permission granularity from Entra ID. And embrace the full potential of identity as code.