Skip to main content

Getting Started with Microsoft Entra ID

Entra ID is the identity plane for everything Azure. Before networking, before policy, before workloads — the tenant configuration shapes what's possible everywhere else. I've spent a disproportionate amount of time in engagements fixing identity decisions made early that nobody thought would matter. Getting the foundation right here pays dividends for years.

Initial tenant setup

Every subscription has a tenant. My first steps:

  1. Navigate to Microsoft Entra ID in Azure Portal
  2. Note your Tenant ID and Primary Domain (e.g., contoso.onmicrosoft.com)
  3. Optionally add a custom domain (requires DNS verification)

Managing Users and Groups

Create Users via Azure Portal

  1. Go to Microsoft Entra ID > Users
  2. Click + New user
  3. Choose Create user or Invite external user
  4. Fill in user details (name, username, password)
  5. Assign licenses and roles

Using Azure CLI

# Create a new user
az ad user create \
--display-name "Jane Doe" \
--user-principal-name jane.doe@contoso.com \
--password "TempP@ssw0rd!" \
--force-change-password-next-sign-in true

# Create a security group
az ad group create \
--display-name "DevOps Engineers" \
--mail-nickname devops-engineers \
--description "DevOps team members"

# Add user to group
az ad group member add \
--group "DevOps Engineers" \
--member-id <user-object-id>

Configuring Multi-Factor Authentication (MFA)

  1. Go to Microsoft Entra ID > Security > MFA
  2. Click Additional cloud-based MFA settings
  3. Select users or create Conditional Access policy (modern approach)

Modern Approach: Conditional Access Policy

# Requires Azure AD Premium P1 or P2
# Create via Portal:
# Entra ID > Security > Conditional Access > New Policy

Policy Example:

  • Users: All users
  • Cloud apps: All cloud apps
  • Conditions: Any location
  • Grant: Require MFA

Implementing Conditional Access

Conditional Access policies provide intelligent access control based on signals:

Common Policies:

  1. Require MFA for Administrators

    • Users: Directory role = Global Administrator
    • Grant: Require MFA
  2. Block Access from Untrusted Locations

    • Users: All users
    • Locations: Not in "Corporate Network" named location
    • Apps: Office 365
    • Block access
  3. Require Compliant Device

    • Users: All users
    • Apps: All cloud apps
    • Grant: Require device to be marked as compliant (Intune)

Terraform Example

# Entra ID is managed via AzureAD provider (not azurerm)
terraform {
required_providers {
azuread = {
source = "hashicorp/azuread"
version = "~> 2.47"
}
}
}

# Create a security group
resource "azuread_group" "developers" {
display_name = "Developers"
description = "Developer team members"
security_enabled = true

members = [
azuread_user.developer1.object_id,
azuread_user.developer2.object_id,
]
}

# Create a user
resource "azuread_user" "developer1" {
user_principal_name = "john.developer@contoso.com"
display_name = "John Developer"
mail_nickname = "john.developer"
password = "SecureP@ssw0rd123!"
force_password_change = true
}

# Register an application
resource "azuread_application" "app" {
display_name = "my-api-app"

web {
redirect_uris = ["https://app.contoso.com/auth/callback"]
implicit_grant {
access_token_issuance_enabled = true
id_token_issuance_enabled = true
}
}

required_resource_access {
resource_app_id = "00000003-0000-0000-c000-000000000000" # Microsoft Graph

resource_access {
id = "e1fe6dd8-ba31-4d61-89e7-88639da4683d" # User.Read
type = "Scope"
}
}
}

# Create service principal for the app
resource "azuread_service_principal" "app" {
application_id = azuread_application.app.application_id
}

CI/CD Integration

Application Registration for Service Principals

# Create app registration
az ad app create \
--display-name "github-actions-sp" \
--sign-in-audience AzureADMyOrg

# Create service principal
az ad sp create \
--id <app-id-from-above>

# Create credentials (client secret)
az ad app credential reset \
--id <app-id> \
--append \
--years 1

GitHub Actions with Entra ID

name: Deploy to Azure

on: [push]

jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Azure Login with Service Principal
uses: azure/login@v1
with:
creds: ${{ secrets.AZURE_CREDENTIALS }}
# AZURE_CREDENTIALS format:
# {
# "clientId": "<service-principal-app-id>",
# "clientSecret": "<service-principal-password>",
# "subscriptionId": "<subscription-id>",
# "tenantId": "<tenant-id>"
# }

- name: Deploy resources
run: |
az group create --name rg-app --location eastus

Using Managed Identities (Preferred over Service Principals)

For Azure-hosted workloads, use managed identities instead of service principals:

# Azure DevOps with Managed Identity
pool:
vmImage: 'ubuntu-latest'

steps:
- task: AzureCLI@2
inputs:
azureSubscription: 'ManagedIdentityConnection'
scriptType: 'bash'
scriptLocation: 'inlineScript'
inlineScript: |
az account show
addSpnToEnvironment: false
useGlobalConfig: true

Best Practices

Use Conditional Access Policies

I avoid: Per-user MFA settings (legacy method) ✅ I use: Conditional Access policies for centralized, context-aware access control

Benefits:

  • Risk-based authentication
  • Location-based access
  • Device compliance requirements
  • Sign-in risk detection

Implement Least Privilege with Azure RBAC

# Assign minimal required role
az role assignment create \
--role "Reader" \
--assignee user@contoso.com \
--scope /subscriptions/{subscription-id}/resourceGroups/rg-prod

Enable Identity Protection

Requires Azure AD Premium P2:

  • User risk policy: Detect compromised credentials
  • Sign-in risk policy: Detect suspicious sign-in attempts
  • MFA registration policy: Ensure all users register for MFA

Use Security Defaults (For Small Organizations)

If I don't have Azure AD Premium, I enable Security Defaults:

  1. Go to Entra ID > Properties
  2. Click Manage Security defaults
  3. Enable

Security Defaults provide:

  • MFA for all users
  • Block legacy authentication
  • Require MFA for administrative tasks

Regularly Review Guest Users

# List all guest users
az ad user list --filter "userType eq 'Guest'" -o table

# Remove inactive guests
az ad user delete --id <user-object-id>

Monitor Sign-in Logs

  • Review failed sign-ins weekly
  • Investigate unfamiliar locations
  • Check for legacy authentication attempts
  • Monitor service principal sign-ins

Things to Avoid

❌ I don't use the global administrator role for daily tasks ❌ I never allow password-only authentication for admin accounts ❌ I don't grant "User Access Administrator" role unnecessarily ❌ I don't leave unused app registrations and service principals around ❌ I never use long-lived secrets (>1 year) for service principals ❌ I never skip emergency access accounts ("break glass") ❌ I never allow legacy authentication protocols (SMTP, IMAP, POP3) ❌ I never ignore risky sign-ins and user risk detections

✅ I use Privileged Identity Management (PIM) for admin roles ✅ I implement Conditional Access policies ✅ I use managed identities instead of service principals when possible ✅ I enforce MFA for all users ✅ I regularly audit app permissions and consents ✅ I create 2-3 emergency access accounts ✅ I monitor and investigate Identity Protection alerts ✅ I use Azure AD Premium features for enhanced security

Common Use Cases

  1. Employee Identity Management: Centralized directory for all employees
  2. B2B Collaboration: Invite external partners while maintaining security
  3. Application SSO: Single sign-on to SaaS apps (Salesforce, Google Workspace, etc.)
  4. API Protection: Secure APIs with OAuth 2.0 and OpenID Connect
  5. Hybrid Identity: Sync on-premises AD with Azure AD using Azure AD Connect
  6. Customer Facing Apps: Use Azure AD B2C for customer identities

Licensing Tiers

The licensing question comes up in every engagement. Here's the breakdown I use:

FeatureFreeP1P2
Users and Groups
SSO (Unlimited apps)
Self-service password reset
Conditional Access
Identity Protection
Privileged Identity Management
Price (per user/month)Free~$6~$9

Monitoring & Troubleshooting

Key Logs to Monitor

  1. Sign-in logs: Track user and service principal authentications
  2. Audit logs: Changes to users, groups, and applications
  3. Provisioning logs: User provisioning to SaaS apps
  4. Risk detections: Identity Protection findings

Export Logs to SIEM

# Create diagnostic settings
az monitor diagnostic-settings create \
--name EntraIDLogs \
--resource /providers/Microsoft.aadiam/diagnosticSettings/EntraIDLogs \
--logs '[
{"category": "SignInLogs", "enabled": true},
{"category": "AuditLogs", "enabled": true},
{"category": "RiskyUsers", "enabled": true}
]' \
--workspace <log-analytics-workspace-id>