Building an Azure Landing Zone touches every layer of the tenant — management groups, subscriptions, Entra ID, and policies. Before any deployment can begin, the right access needs to be in place.
The Quick Version#
The simplest way to get started is to grant two things:
- Global Administrator on the Entra ID tenant — this covers identity management (service principals, security groups, app registrations).
- Elevate access to Azure resources — this extends control to all subscriptions and management groups, which Global Administrator alone does not cover.
Once the deployment service principal is set up and tested, both can be revoked. The service principal takes over from there.
Step 1: Grant Global Administrator#
Run the following in Azure Cloud Shell (Bash):
# Replace with the actual user's email address
USER_ID=$(az ad user show --id "<user-email>" --query id -o tsv)
# Assign Global Administrator role
az rest --method POST \
--uri "https://graph.microsoft.com/v1.0/directoryRoles/roleTemplateId=62e90394-69f5-4237-9190-012177145e10/members/\$ref" \
--headers "Content-Type=application/json" \
--body "{\"@odata.id\":\"https://graph.microsoft.com/v1.0/users/${USER_ID}\"}"Step 2: Elevate Access to Azure Resources#
This must be done by a Global Administrator in the Azure portal:
- Go to Entra ID > Properties
- Set Access management for Azure resources to Yes
This grants the User Access Administrator role at the tenant root scope, which allows managing RBAC across all subscriptions and management groups.
That’s it. If this works for your organization, you can skip ahead to Revoking Access when the initial setup is complete.
Detailed Access Breakdown#
If Global Administrator isn’t an option, the following granular permissions cover what’s needed to deploy a Landing Zone.
Entra ID Permissions#
A service principal (app registration) is required for the CI/CD pipeline. Creating and configuring it requires the following Microsoft Graph API permissions with admin consent:
| Permission | Why |
|---|---|
Application.ReadWrite.All | Create the deployment service principal and app registration |
Group.ReadWrite.All | Create and manage security groups for RBAC |
GroupMember.ReadWrite.All | Manage group memberships |
Application.Read.All | Look up existing service principals |
These are application permissions, granted under App registrations > API permissions in the Entra ID portal.
Subscription-Level Roles#
The deployment service principal needs Owner on every subscription in scope.
| Role | Why |
|---|---|
| Owner | Deploy resources and assign RBAC roles to other principals |
Why not just Contributor? Landing Zone deployments create role assignments (
azurerm_role_assignmentin Terraform). Contributor cannot assign roles — Owner (or Contributor + User Access Administrator) is required.
Management Group Roles#
These roles are assigned at the tenant root management group level:
| Role | Why |
|---|---|
| Management Group Contributor | Create and organize the management group hierarchy |
| Resource Policy Contributor | Assign Azure Policies at management group scope |
Note: Before assigning roles at the tenant root management group, Access management for Azure resources must be enabled in Entra ID. Go to Entra ID > Properties > Access management for Azure resources > Yes.
CI/CD Platform#
The deployment pipeline runs from Azure DevOps or GitHub. What’s needed:
- Azure DevOps: A project with permissions to create pipelines and variable groups
- GitHub: A repository with permissions to configure Actions and secrets
If creating a new project or repository isn’t possible, the project/repo needs to be created beforehand and access granted to the person running the deployment.
Quick Commands#
Run these in Azure Cloud Shell (Bash) to grant the granular access described above.
# Set your values
SP_NAME="<service-principal-name>"
TENANT_ROOT_MG="/providers/Microsoft.Management/managementGroups/<your-tenant-id>"
# Get the service principal's object ID
SP_OBJECT_ID=$(az ad sp show --id "$SP_NAME" --query id -o tsv)
# Owner on each subscription in scope
az role assignment create --assignee "$SP_OBJECT_ID" --role "Owner" \
--scope "/subscriptions/<subscription-id>"
# Management group roles at tenant root
az role assignment create --assignee "$SP_OBJECT_ID" \
--role "Management Group Contributor" --scope "$TENANT_ROOT_MG"
az role assignment create --assignee "$SP_OBJECT_ID" \
--role "Resource Policy Contributor" --scope "$TENANT_ROOT_MG"Repeat the Owner assignment for each subscription in scope.
Revoking Access#
Once the Landing Zone is deployed and the service principal is handling ongoing operations, temporary access should be revoked:
Disable elevated access: Go to Entra ID > Properties and set Access management for Azure resources back to No.
Remove Global Administrator role:
USER_ID=$(az ad user show --id "<user-email>" --query id -o tsv)
ROLE_ID=$(az rest --method GET \
--uri "https://graph.microsoft.com/v1.0/directoryRoles" \
--query "value[?roleTemplateId=='62e90394-69f5-4237-9190-012177145e10'].id" \
-o tsv)
az rest --method DELETE \
--uri "https://graph.microsoft.com/v1.0/directoryRoles/${ROLE_ID}/members/${USER_ID}/\$ref"- Remove specific role assignments (if granted individually):
az role assignment delete --assignee "<user-or-sp>" --role "Owner" \
--scope "/subscriptions/<subscription-id>"Questions?#
If any of this doesn’t fit your organization’s requirements or policies, get in touch and we’ll work through it together.
