Azure / Guide 2

Structure and access

Management groups, subscriptions, resource groups, naming, RBAC and resource locks.

The way subscriptions, resource groups and permissions are laid out decides how easy Azure is to govern, secure and pay for. It's much easier to get right at the start than to fix after a few hundred resources.

The hierarchy

Level What it's for
Microsoft Entra tenant Identity: users, groups, apps. One per organisation, usually.
Management groups Apply policy and access to many subscriptions at once. Up to six levels deep below the root.
Subscriptions The billing boundary and a limits (quota) boundary. Good for separating environments and workloads.
Resource groups Resources that share a lifecycle: deployed, managed and deleted together.
Resources VMs, storage accounts, databases and everything else.

Anything assigned at a higher level (a policy, a role, a budget) applies to everything underneath.

A practical layout

Microsoft's Cloud Adoption Framework "landing zone" design is a good default, even for smaller estates:

Tenant Root Group
└── mg-ravindran
    ├── mg-platform          shared services run by IT
    │   ├── sub-identity         domain controllers, identity services
    │   ├── sub-management       monitoring, automation, backup
    │   └── sub-connectivity     hub network, firewall, VPN / ExpressRoute
    ├── mg-landingzones      application workloads
    │   ├── mg-corp              internal apps, connected to the hub
    │   └── mg-online            internet-facing apps
    └── mg-sandbox           experiments, strict budgets, no connection to production

Guidelines that hold up in practice:

  • Separate production and non-production subscriptions. Different policies, different access, clear cost split.
  • One resource group per application per environment, for example rg-payroll-prod and rg-payroll-test.
  • Don't design around the org chart. Teams reorganise; workloads and environments don't change as often.

Naming conventions

Pick a convention and enforce it. The Cloud Adoption Framework pattern is widely used:

<resource type>-<workload>-<environment>-<region>-<instance>
rg-notes-test-eastus-001
vm-notes-test-01

Common abbreviations: rg resource group, vm virtual machine, vnet virtual network, snet subnet, nsg network security group, nic network interface, pip public IP, kv key vault, rsv Recovery Services vault, log Log Analytics workspace, st storage account.

Watch the limits: storage account names are 3–24 lowercase letters and numbers only (no dashes), and a Windows VM's computer name is limited to 15 characters.

Access with Azure RBAC

Azure role-based access control (RBAC) grants a role to a principal (user, group, service principal or managed identity) at a scope (management group, subscription, resource group or resource).

Rules that prevent most access problems:

  1. Assign roles to groups, not individual users. Access follows group membership, and reviews are simpler.
  2. Use the least privileged role. Reader, Virtual Machine Contributor or Backup Operator are often enough; Owner and Contributor rarely are.
  3. Assign at the narrowest scope that works, usually the resource group.
  4. Make high-privilege roles just-in-time with Privileged Identity Management (PIM), so people activate Owner or Contributor for a few hours when needed instead of holding it permanently.
  5. Review regularly. Get-AzRoleAssignmentReport.ps1 flags privileged roles, guest accounts, direct user assignments and assignments left behind by deleted accounts.
# Who has what on a resource group
Get-AzRoleAssignment -ResourceGroupName rg-notes-test |
    Select-Object DisplayName, SignInName, RoleDefinitionName, ObjectType

# Grant a group a role at resource group scope
$group = Get-AzADGroup -DisplayName 'Notes Test Operators'
New-AzRoleAssignment -ObjectId $group.Id -RoleDefinitionName 'Virtual Machine Contributor' -ResourceGroupName rg-notes-test

The old "classic administrator" roles (Co-Administrator and Service Administrator) have been retired; use Azure RBAC roles only.

Protect important resources with locks

A CanNotDelete lock stops anyone (even Owners) from deleting a resource or resource group until the lock is removed. It's cheap insurance for things like the hub network, Recovery Services vaults and production databases.

New-AzResourceLock -LockName 'do-not-delete' -LockLevel CanNotDelete -ResourceGroupName rg-notes-test -Force
Get-AzResourceLock -ResourceGroupName rg-notes-test

Be careful with ReadOnly locks: they block more than people expect, including some operations that only read data, such as listing storage account keys.