Entra ID user and group management, least-privilege RBAC assignments, custom role definitions, Azure Policy initiatives, resource locks, and cost management — the security and compliance layer that everything else runs on top of.
Simulated enterprise user onboarding by provisioning four Entra ID accounts across three security groups, assigning built-in roles at resource group scope using the principle of least privilege, and creating a custom role definition for a Storage Blob Reader Plus permission set that didn't exist in the built-in catalog. Verified the assignments by signing in as each test user and confirming the access boundaries held. Enabled MFA on all accounts and reviewed Entra ID sign-in audit logs.
| Group | Role | Scope |
|---|---|---|
| grp-developers | Contributor | RG |
| grp-ops | VM Contributor | RG |
| grp-readonly | Reader | RG |
| dev1 | Storage Blob Reader Plus (custom) | RG |
grp-developers — no new
role assignments required. This is the correct enterprise pattern: manage group membership, not role
assignments, as the team evolves.rg-phase1-lab only. Scoping to subscription would give grp-developers
Contributor access to every resource in the subscription — a significant blast radius for a lab.
Narrowest scope that satisfies the requirement.
An organization with 200 Azure resources and 50 engineers can't maintain individual role assignments — the combination count grows faster than anyone can manage. Group-based RBAC means access is controlled in one place (group membership) and role assignments are stable infrastructure. New hire: add to group. Offboarding: remove from group. All access changes flow from that one action.
Built a governance baseline using Azure Policy — three policies bundled into an initiative, deployed with Deny effect to prevent out-of-region resources and enforce required tags, and Audit effect for non-destructive compliance reporting. Verified the controls by deliberately triggering the location policy denial and the resource lock block, capturing both as evidence. Configured budget alerts at 80% actual and 100% forecast to prevent cost overruns. The governance pattern established here was extended in Phase 4: the lab resource group carried 10 active policy assignments throughout all subsequent projects.
| Assignment | Effect |
|---|---|
| require-tag-env | Deny |
| require-tag-owner | Deny |
| allowed-locations-wus3 | Deny |
| appsvc-https-only | Deny |
| appsvc-managed-identity | Deny |
| appsvc-no-remote-debug | Deny |
| inherit-tag-env | Inherit |
| inherit-tag-owner | Inherit |
| inherit-tag-project | Inherit |
| inherit-tag-phase | Inherit |
inherit-tag-* policy assignments. Manual
tagging is inconsistent and breaks. Policy-enforced inheritance is the only reliable approach at
scale.az policy definition list --query "[?displayName=='Allowed locations'].name" -o tsv. One
character difference caused significant debugging time.
{
"name": "initiative-baseline-governance",
"properties": {
"displayName": "Baseline Governance Initiative",
"description": "Location, tagging, and disk compliance",
"policyDefinitions": [
{
"policyDefinitionId": "/providers/Microsoft.Authorization/
policyDefinitions/e56962a6-4747-49cd-b67b-bf8b01975c4f",
"parameters": {
"listOfAllowedLocations": {
"value": ["westus3"]
}
}
},
{
"policyDefinitionId": "/providers/Microsoft.Authorization/
policyDefinitions/96670d01-0a4d-4649-9c89-2d3abc0a5025",
"parameters": {
"tagName": { "value": "environment" }
}
},
{
"policyDefinitionId": "/providers/Microsoft.Authorization/
policyDefinitions/06a78e20-9358-41c9-923c-fb736d382a4d"
}
]
}
}
Remediation tasks fail immediately after policy assignment because the managed identity needs 30–60
seconds to propagate through Entra ID. Wait 60 seconds and use unique names for retry attempts.
Fallback: az resource tag --is-incremental for immediate tagging without waiting on
remediation.
az policy state trigger-scan rather than assuming misconfiguration.