Five bullets in the AZ-900 skills outline sit under the heading Describe features and tools for managing and deploying Azure resources. In the skills measured as of July 20, 2026 they read:
- Describe the Azure portal
- Describe Azure Cloud Shell, Azure CLI, and Azure PowerShell
- Describe the purpose of Azure Arc
- Describe infrastructure as code (IaC)
- Describe Azure Resource Manager (ARM) and ARM templates
Our AZ-900 management and governance guide gives this group one table and three short paragraphs, because that post has to cover cost management, Azure Policy, locks, Purview and the monitoring tools as well. That survey is enough to answer “which tool is a browser-based shell”. It is not enough to answer the questions that actually appear: why a resource group has a location when its resources can live anywhere, what happens to a resource that is in the resource group but not in the template you redeploy, whether the CLI can do something the portal cannot, what Azure Arc projects into, and why Microsoft keeps saying “declarative” as if it were a feature.
This article is the deep dive those five bullets deserve. It stays at AZ-900 altitude (you will not write a Bicep module on the exam) but it explains the mechanism underneath each tool, because the exam’s distractors are built from people who only learned the names.
The One Diagram That Explains Everything: Azure Resource Manager
Azure Resource Manager (ARM) is the deployment and management service for Azure. Every request to create, update or delete a resource, from any tool, goes through it:
- You click a button in the portal, run
az vm createin the Azure CLI, runNew-AzVMin Azure PowerShell, call the REST API from an SDK, or deploy a template. - The request arrives at Resource Manager (the endpoint is
management.azure.com). - Resource Manager authenticates the caller with Microsoft Entra ID and authorises the request with Azure role-based access control (RBAC), then evaluates Azure Policy and resource locks.
- It forwards the request to the right resource provider, which does the actual work.
Because every tool uses the same API, you get consistent results and capabilities everywhere. The documentation makes a stronger promise: everything available in the portal is also available through PowerShell, the CLI, REST and the SDKs, and new API functionality appears in the portal within 180 days of release. So the answer to “which tool can do X that the others cannot” is almost always “none of them; they all call ARM”. The tools differ in ergonomics, not in power.
Resource providers and resource types
A resource provider is a service that supplies resources. Microsoft.Compute supplies virtual machines, Microsoft.Storage supplies storage accounts, Microsoft.Network supplies virtual networks. A resource type is written as provider plus type: Microsoft.Storage/storageAccounts, Microsoft.Compute/virtualMachines. You see both in every resource ID:
/subscriptions/<subscription-id>/resourceGroups/prod-rg/providers/Microsoft.Storage/storageAccounts/prodstorage01
Reading that ID left to right gives you the scope hierarchy (subscription, resource group), the provider, the type and the name. When a template deploys a storage account, Resource Manager literally converts the resource definition into an HTTP PUT to the Microsoft.Storage provider at that path, using the apiVersion in the template as the API version. That is why templates remain stable over time: the API version is pinned in the file.
A resource provider must be registered in a subscription before you can use its types. The portal registers most common providers automatically; the CLI and PowerShell do too for most operations, but “the deployment fails with a message that the namespace is not registered” is a recognisable scenario, fixed with az provider register --namespace Microsoft.Something.
The four management scopes
Azure has four levels of management scope, and settings applied at a higher level are inherited by everything below:
| Scope | Contains | Typical settings applied here |
|---|---|---|
| Management group | Subscriptions (and other management groups) | Organisation-wide Azure Policy, RBAC for platform teams |
| Subscription | Resource groups | Billing boundary, subscription-wide policy and RBAC |
| Resource group | Resources | Team- or workload-level RBAC, locks, tags |
| Resource | Itself | Resource-specific RBAC, locks |
A policy assigned at the subscription applies to every resource group and resource in it; a policy assigned at one resource group does not touch another. Our AZ-900 core architecture guide covers the hierarchy itself; the point here is that Resource Manager is the thing that evaluates scope on every request.
Templates and Bicep files can be deployed at any of these scopes and at the tenant scope as well, which is how you create management groups or subscriptions from code.
What a resource group really is
The exam asks several questions whose answers are rules about resource groups, so here are the ones that matter, taken from the Resource Manager documentation:
- Every resource lives in exactly one resource group, and you can move resources between groups (and subscriptions).
- Resources in a group can be in different regions from the group and from each other, although Microsoft recommends keeping them together.
- The group’s location is where its metadata is stored, and control-plane operations for its resources are routed through that location. If the group’s region is temporarily unavailable, Resource Manager transparently reroutes control-plane requests to a backup region. Data-plane access to the resources themselves is unaffected by the group’s location.
- Deleting a resource group deletes everything in it.
- Tags on a resource group are not inherited by its resources (Azure Policy can enforce inheritance if you want it).
- Resources in different groups can still connect to each other; a web app in one group can use a database in another.
- A group can hold up to 800 instances of a given resource type.
- Design rule: group resources that share a lifecycle, because you deploy, update and delete a group’s contents together.
Control plane vs data plane
This distinction explains half the trick questions in this domain. The control plane is everything that goes through Resource Manager: creating a storage account, resizing a VM, assigning a role, deleting a resource group. The data plane is operations against a resource’s own endpoint: uploading a blob to https://prodstorage01.blob.core.windows.net, running a query against a SQL database, an HTTP request to a web app.
RBAC “control plane” roles, Azure Policy, resource locks and the deny settings of deployment stacks act on the control plane. A CanNotDelete lock stops someone deleting the storage account; it does not stop anyone deleting blobs inside it, because that is a data-plane operation governed by the storage account’s own authorisation (data-plane RBAC roles such as Storage Blob Data Contributor, keys or SAS tokens). When a question says “prevent accidental deletion of the storage account” the lock is right; when it says “prevent deletion of the files” it is not.
Two more Resource Manager behaviours worth a sentence each
- Concurrency: if two requests try to update the same resource at the same time, one wins and the other receives an HTTP 409 conflict. Retry after reading the new state.
- Resiliency: Resource Manager runs a separate instance in every region, spread across availability zones, and is never taken down for maintenance. The control plane is therefore more available than many of the regional services behind it.
The Four Ways to Talk to Azure
Every one of these is a client of Resource Manager. The exam wants you to know what each is, when you would reach for it, and the one or two facts that distinguish it.
Azure portal
The portal (portal.azure.com) is the web-based graphical console. Beyond “click to create”, it offers dashboards you can customise and share, the Cloud Shell icon in the top bar, resource visualisers, deployment history for every resource group (template, parameters and outputs of each deployment), the ability to export a template from any existing resource group, and Copilot in Azure for natural-language help. There is also an Azure mobile app that shows resource health, alerts and a Cloud Shell.
Portal cues on the exam: “one-off”, “explore”, “visual”, “no scripting experience”, “build a dashboard for the operations team”. Anti-cues: “repeatable”, “100 identical environments”, “version-controlled”, which all point to scripting or IaC.
Azure Cloud Shell
Azure Cloud Shell is an interactive, authenticated, browser-accessible terminal. You pick Bash or PowerShell, and both the Azure CLI and the Az PowerShell module are pre-installed and already signed in as you. The facts that appear in questions:
| Fact | Detail |
|---|---|
| Where it runs | A temporary host provided per user, per session; you have the permissions of a regular Linux user |
| Idle timeout | The session ends after 20 minutes without interactive activity |
| Persistent files | Your $HOME is stored as a 5 GB disk image in an Azure Files share, mounted at clouddrive, so scripts, SSH keys and config survive between sessions |
| Ephemeral option | You can instead choose a session with no storage account; files are lost when the session ends |
| Pricing | The machine is free; you pay only for the Azure Files share if you chose persistent storage |
| Access points | The portal, shell.azure.com, the Azure mobile app, Visual Studio Code, Windows Terminal, and the “Try it” buttons in the CLI and PowerShell documentation |
| Tools included | Azure CLI, Azure PowerShell, Git, kubectl, Terraform, the Bicep CLI, Python, Node.js, .NET, an integrated file editor and more |
| Security | All Cloud Shell infrastructure is double-encrypted at rest; remember the home share can hold tokens and keys, so lock down its storage account |
Cloud Shell cues: “without installing anything”, “from any browser or device”, “needs to run a script but the admin is on a locked-down machine”, “quick command from a tablet”. The classic distractor pairs Cloud Shell with “offline access” or “runs on-premises”; it does neither.
Azure CLI
The Azure CLI is the cross-platform command-line tool whose commands start with az. It runs on Windows, macOS and Linux, speaks the same way in Bash, zsh and Windows Command Prompt, returns JSON by default (with --output table and JMESPath --query filters), and is the natural fit for Linux-centric automation and CI pipelines.
az login
az group create --name demo-rg --location eastus
az vm create --resource-group demo-rg --name web01 \
--image Ubuntu2204 --size Standard_B1s --generate-ssh-keys
az vm list --output table
az group delete --name demo-rg --yes --no-wait
Azure PowerShell
Azure PowerShell is the Az module for PowerShell (the earlier AzureRM module was retired in February 2024 and only Az is current). Its cmdlets follow the PowerShell Verb-Noun convention (New-AzResourceGroup, Get-AzVM), and because PowerShell passes objects rather than text between commands, it is the natural fit for teams already managing Windows estates with PowerShell. It runs on PowerShell 7 on Windows, macOS and Linux as well.
Connect-AzAccount
New-AzResourceGroup -Name demo-rg -Location eastus
New-AzVM -ResourceGroupName demo-rg -Name web01 -Image Ubuntu2204 -Size Standard_B1s
Get-AzVM | Select-Object Name, Location, ProvisioningState
Remove-AzResourceGroup -Name demo-rg -Force -AsJob
Side by side
| Task | Azure CLI | Azure PowerShell |
|---|---|---|
| Sign in | az login | Connect-AzAccount |
| Create resource group | az group create -n demo-rg -l eastus | New-AzResourceGroup -Name demo-rg -Location eastus |
| List VMs | az vm list -o table | Get-AzVM |
| Deploy a Bicep/ARM file | az deployment group create -g demo-rg -f main.bicep | New-AzResourceGroupDeployment -ResourceGroupName demo-rg -TemplateFile main.bicep |
| Preview a deployment | az deployment group what-if ... | New-AzResourceGroupDeployment -WhatIf ... |
| Delete resource group | az group delete -n demo-rg | Remove-AzResourceGroup -Name demo-rg |
| Output style | JSON by default, --output table | PowerShell objects, pipe to Format-Table |
| Natural home | Bash, Linux, CI/CD | Windows admin teams, PowerShell pipelines |
The AZ-900 position is simply that these two are functionally equivalent scripting interfaces; neither can do something the other cannot, because both call Resource Manager. Questions that try to make you pick between them do it with team cues (“Windows administrators familiar with PowerShell”, “Linux engineers who use Bash”) rather than capability cues.
REST API and SDKs
Not named in the skills outline but worth knowing as the fifth door: every tool above ultimately sends REST calls to management.azure.com, and the Azure SDKs (.NET, Python, Java, JavaScript, Go) wrap those calls for application code.
Infrastructure as Code
Infrastructure as code (IaC) means describing the infrastructure you want in files that are stored in version control, reviewed like application code, and deployed repeatedly to produce identical environments. The alternative is clicking through the portal or running a sequence of commands by hand, which is slow, error-prone and impossible to audit.
The exam frames IaC through two words:
| Style | Meaning | Example |
|---|---|---|
| Imperative | A sequence of commands that say how to build it | A Bash script of twelve az commands run in order |
| Declarative | A description of what the end state should be; the engine works out the steps | An ARM template or Bicep file listing the resources and their properties |
ARM templates and Bicep are declarative. The benefits the documentation lists, and that reappear as answer options:
- Repeatable results: the same file deploys the same state every time.
- Idempotent: deploying a file whose resources already exist with the same properties changes nothing. You keep one file for the desired state rather than one file per update.
- Orchestration: Resource Manager works out dependencies, creates resources in the right order and deploys independent resources in parallel. You run one command instead of twelve.
- Modular: break big deployments into linked or nested templates (ARM) or modules (Bicep).
- Validated before deployment and tracked in deployment history.
- Testable with the what-if operation before anything changes.
AZ-900 scenario cues for IaC: “deploy the same environment to development, test and production”, “ensure environments are consistent”, “store infrastructure definitions in source control”, “deploy repeatedly with no manual steps”. If a question offers a declarative template versus an imperative script, the template is the IaC answer; if it offers IaC versus “document the portal steps”, IaC wins.
ARM Templates: Anatomy and Behaviour
An ARM template is a JSON file. Its sections:
| Section | Purpose |
|---|---|
$schema and contentVersion | Which template language version this is, and your own version number for the file |
parameters | Values supplied at deployment time (environment name, SKU, location) |
variables | Values computed once and reused inside the template |
functions | User-defined functions to simplify expressions |
resources | The resources to deploy, each with type, apiVersion, name, location and properties |
outputs | Values returned after deployment (a connection string, a public IP) |
The storage account example from the documentation:
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"location": { "type": "string", "defaultValue": "[resourceGroup().location]" }
},
"resources": [
{
"type": "Microsoft.Storage/storageAccounts",
"apiVersion": "2025-06-01",
"name": "mystorageaccount",
"location": "[parameters('location')]",
"sku": { "name": "Standard_LRS" },
"kind": "StorageV2"
}
]
}
Notice the bracketed expressions such as [parameters('location')]; that syntax is the main reason Bicep exists.
Deployment scopes
A template targets one of four scopes, and the CLI command names follow the scope:
| Scope | CLI | What you deploy there |
|---|---|---|
| Resource group | az deployment group create | Almost everything: VMs, storage, networks |
| Subscription | az deployment sub create | Resource groups themselves, subscription-level policy and role assignments |
| Management group | az deployment mg create | Policy definitions and assignments across subscriptions |
| Tenant | az deployment tenant create | Management groups, subscription creation |
Incremental vs complete mode
A resource-group deployment runs in one of two modes, and the difference is what happens to resources that already exist in the group but are not in the template:
| Mode | Resources in the group but not in the template | Default? | Scope support |
|---|---|---|---|
| Incremental | Left unchanged; template resources are added or updated | Yes | All scopes, linked and nested templates |
| Complete | Deleted | No | Root-level resource-group deployments only; not subscription scope; not the portal |
The documentation’s example: a group holds A, B and C; the template holds A, B and D. Incremental leaves A, B, C, D. Complete leaves A, B, D and deletes C. Complete mode respects resource locks (a locked group’s resources are not deleted), is now marked not recommended, and is being phased out in favour of deployment stacks. The documentation tells you to always run what-if before a complete-mode deployment.
The trap inside incremental mode is subtler and shows up in real life more than on the exam: when you redeploy an existing resource, all of its properties are reapplied, not merged. Properties you leave out of the template are reset to their defaults. The template describes the final state of the resource, never a partial update.
What-if, validation and history
- What-if (
az deployment group what-if,-WhatIfin PowerShell) previews which resources would be created, modified or deleted and which properties would change, by comparing the template to the live environment. Because Azure holds the state, there is no state file for you to manage. - Validation runs before every deployment; a template that fails validation never starts, which is why deployments rarely end half-finished.
- Deployment history in the portal records the template, parameters and outputs of every deployment to a group, and the portal’s Export template turns any existing resource group into a starting template.
Template specs
A template spec stores a template (ARM or Bicep) as an Azure resource of type Microsoft.Resources/templateSpecs, with versions, so you can share it across the organisation and control who may deploy it with RBAC. Users with read access can deploy it but not change it. Template specs, together with deployment stacks, are the migration target for Azure Blueprints (see below).
Bicep: The Same Engine, a Better Language
Bicep is a domain-specific language for deploying Azure resources declaratively. The one-sentence summary for the exam: a Bicep file is converted into an ARM JSON template during deployment, so it can do everything an ARM template can, with far less syntax. Resource types, API versions and properties that are valid in ARM JSON are valid in Bicep on the same day a resource provider releases them.
The same storage account in Bicep:
param location string = resourceGroup().location
param storageAccountName string = 'toylaunch${uniqueString(resourceGroup().id)}'
resource storageAccount 'Microsoft.Storage/storageAccounts@2023-05-01' = {
name: storageAccountName
location: location
sku: {
name: 'Standard_LRS'
}
kind: 'StorageV2'
properties: {
accessTier: 'Hot'
}
}
| ARM JSON | Bicep | |
|---|---|---|
| Syntax | Verbose JSON with [bracketed()] expressions | Concise DSL; call functions directly |
| Dependencies | Often explicit dependsOn | Inferred automatically when one resource references another’s symbolic name |
| Structure | Parameters, variables, resources, outputs must each be in their section | Declare them anywhere in the file |
| Reuse | Linked or nested templates | Modules |
| Tooling | JSON editors, arm-ttk test kit | VS Code extension with IntelliSense and type checking; Bicep CLI bundled with the Azure CLI |
| State | None (Azure holds it) | None (Azure holds it) |
| Cost | Free | Free and open source |
| Conversion | az bicep decompile turns JSON into Bicep | az bicep build turns Bicep into JSON |
Bicep still supports what-if, modules, template specs and every deployment scope, because the engine behind it is the same Resource Manager. Microsoft’s recommendation in the ARM template documentation is to look at Bicep first for any new IaC work.
Third-party IaC tools such as Terraform also deploy Azure resources, through their own provider plugins and their own state files. They are outside the AZ-900 outline; if a question names “a Microsoft-native, declarative language with no state file to manage”, it is describing Bicep.
Deployment Stacks and the End of Blueprints
A deployment stack (resource type Microsoft.Resources/deploymentStacks) wraps a Bicep file or ARM template so that the resources it creates are managed as a single unit, at resource group, subscription or management group scope. Two capabilities make it the modern replacement for complete mode:
actionOnUnmanage: when a resource is removed from the template (or the stack is deleted), choosedeleteAll,deleteResourcesordetachAll. This is the controlled form of “delete what is no longer in the template”.denySettingsMode:none,denyDeleteordenyWriteAndDelete, which creates a deny assignment on the managed resources so that even owners cannot delete or change them outside the stack. Up to five principals and 200 actions can be excluded.
az stack group create \
--name web-stack \
--resource-group demo-rg \
--template-file main.bicep \
--action-on-unmanage deleteResources \
--deny-settings-mode denyDelete
Why this matters for an AZ-900 candidate in 2026: older study material lists Azure Blueprints as the governance tool for “deploying a repeatable set of resource groups, policies, role assignments and templates to new subscriptions”. Blueprints never left preview and is being retired: a phased retirement began on July 31, 2026 and the service is retired on January 31, 2027, with Microsoft directing customers to deployment stacks (recommended) and template specs. If a question still offers Blueprints, treat it as the legacy answer and look for the template spec or deployment stack option; if neither exists, Blueprints is what the question intends.
Azure Arc: Managing What Is Not in Azure
The outline asks you to describe the purpose of Azure Arc, and the purpose is one sentence: Azure Arc projects resources that live outside Azure into Azure Resource Manager so you can manage and govern them with the same tools as native Azure resources. “Outside Azure” means on-premises data centres, other public clouds and edge locations.
What it actually does
When you connect a machine, the Azure Connected Machine agent installed on it registers the machine with Azure. The machine becomes a resource of type Microsoft.HybridCompute/machines with an Azure resource ID, lives in a resource group, carries tags, appears in the portal under Azure Arc, and can be found with Azure Resource Graph. The agent sends a heartbeat every five minutes; a machine that stops reporting is shown as Disconnected within 15 to 30 minutes and may become Expired after 45 days. It needs only outbound HTTPS to Azure; nothing inbound.
Resource types Azure Arc can manage:
| Arc-enabled resource | What you get |
|---|---|
| Servers (Windows and Linux, physical or virtual, anywhere) | Azure Policy machine configuration, Azure Update Manager, Azure Monitor and VM insights, Microsoft Defender for Cloud and Defender for Endpoint, Microsoft Sentinel, Azure Automation runbooks and change tracking, VM extensions, RBAC and tags |
| Kubernetes clusters (any CNCF-conformant distribution) | GitOps configuration with Flux, Azure Policy for Kubernetes, Azure Monitor for containers, Defender for Containers, custom locations for hosting Azure services on the cluster |
| Data services | Azure SQL Managed Instance running on your own Kubernetes infrastructure, with Azure-managed upgrades and monitoring |
| SQL Server | Azure services (Defender, Best Practices Assessment, pay-as-you-go licensing) for SQL Server instances outside Azure |
| VMware vSphere and System Center VMM | Inventory, lifecycle and power operations on those VMs from the Azure portal, with self-service through RBAC |
| Azure Local (formerly Azure Stack HCI) | VM management on Microsoft’s hyperconverged on-premises platform, which itself is Arc-registered |
Pricing and positioning
The Arc control plane for servers (resource organisation, Resource Graph, RBAC, templates and extensions) costs nothing extra. The Azure services you attach to Arc resources (Defender for Cloud, Azure Monitor, Update Manager and so on) are billed at their usual rates. Microsoft calls this the adaptive cloud approach: one management plane across Azure, other clouds, on-premises and edge.
The distractors around Arc
| It is… | It is not… |
|---|---|
| A way to manage non-Azure resources with Azure tools | A way to migrate them (that is Azure Migrate; see our moving data into Azure guide) |
| A control-plane projection that needs only outbound HTTPS | A network connection to Azure (that is VPN Gateway or ExpressRoute; see the AZ-900 networking guide) |
| The bridge that lets Defender for Cloud protect on-premises and other-cloud servers | A security product itself (see the Defender for Cloud guide) |
| Able to run some Azure services (SQL MI, Container Apps) on your Kubernetes clusters | Azure hardware in your data centre (that is Azure Local) |
| For machines outside Azure | Supported for managing Azure VMs (it is explicitly not designed for that) |
Arc cues: “servers in another cloud provider”, “on-premises machines must comply with the same Azure Policy”, “single inventory across AWS, on-premises and Azure”, “apply Azure RBAC and tags to non-Azure servers”. If the cue is “move”, “assess”, “connect the network” or “run Azure in our building”, Arc is the distractor.
Decision Table: Cue to Tool
| Cue in the question | Tool |
|---|---|
| ”No installation”, “from a browser”, “already authenticated”, “on a tablet” | Azure Cloud Shell |
| ”Windows administrators”, “existing PowerShell scripts”, “object pipeline” | Azure PowerShell (Az module) |
| “Linux engineers”, “Bash scripts”, “cross-platform CLI”, “CI pipeline on Linux” | Azure CLI |
| ”Visual”, “one-off”, “explore”, “dashboard for the team” | Azure portal |
| ”Repeatable”, “identical environments”, “version control”, “declarative” | ARM template or Bicep (IaC) |
| “Easier to read than JSON”, “Microsoft-native DSL”, “no state file” | Bicep |
| ”Share a standard template with RBAC control over who deploys it” | Template spec |
| ”Preview the changes before deploying” | What-if |
| ”Remove resources that are no longer in the template, safely” | Deployment stack (not complete mode) |
| “Prevent anyone deleting the resources a template created” | Deployment stack deny settings (or a resource lock for a single resource) |
| “Manage on-premises or other-cloud servers with Azure Policy, Monitor, Defender” | Azure Arc |
| ”The engine every tool uses”, “authenticates and authorises every request” | Azure Resource Manager |
| ”Container for resources that share a lifecycle” | Resource group |
| ”Deployment failed: namespace not registered” | Register the resource provider |
A Worked Exam Scenario
A company runs 40 Windows servers in its own data centre and 60 VMs in Azure. The operations team, who are PowerShell specialists, must apply the same Azure Policy compliance rules to all 100 machines, deploy a standard monitoring configuration to every new Azure environment from version-controlled files, and allow a junior engineer to run scripts from a managed laptop without installing tools.
Three requirements, three tools:
- Same policy on all 100 machines. The 60 Azure VMs are already Resource Manager resources. The 40 on-premises servers need Azure Arc (Connected Machine agent) so they become
Microsoft.HybridCompute/machinesresources that Azure Policy machine configuration can evaluate. Nothing else makes a non-Azure server visible to Azure Policy. - Standard monitoring configuration from version-controlled files. That is infrastructure as code: a Bicep file (or ARM template) deployed with
New-AzResourceGroupDeployment, since the team prefers PowerShell, and stored as a template spec if other teams must deploy it without editing it. - Scripts with no installation. Azure Cloud Shell in the PowerShell experience, which is pre-authenticated and has the Az module ready; the junior engineer’s role assignments still limit what the scripts can do, because Cloud Shell changes nothing about authorisation.
The distractors the question will offer: Azure Migrate for requirement 1 (it assesses and moves; it does not govern), the portal’s export-template feature for requirement 2 (useful to start a template, not a deployment method), and “install Azure PowerShell on the laptop” for requirement 3 (contradicts “without installing tools”).
A 15-Minute Lab You Can Run for Free
The fastest way to make this domain stick is to see each layer once. Everything below runs in Cloud Shell (Bash) on a free account and deletes itself at the end.
# 1. The CLI talks to Resource Manager; this creates a resource group (control plane)
az group create --name az900-lab-rg --location eastus
# 2. Write a tiny Bicep file (declarative, idempotent)
cat > main.bicep <<'BICEP'
param location string = resourceGroup().location
param name string = 'az900lab${uniqueString(resourceGroup().id)}'
resource sa 'Microsoft.Storage/storageAccounts@2023-05-01' = {
name: name
location: location
sku: { name: 'Standard_LRS' }
kind: 'StorageV2'
}
output storageName string = sa.name
BICEP
# 3. Preview: what-if compares the file with the live state
az deployment group what-if --resource-group az900-lab-rg --template-file main.bicep
# 4. Deploy (incremental mode is the default), then deploy again to see idempotence
az deployment group create --resource-group az900-lab-rg --template-file main.bicep
az deployment group create --resource-group az900-lab-rg --template-file main.bicep
# 5. Deployment history and the resource ID (provider + type visible in the path)
az deployment group list --resource-group az900-lab-rg --output table
az storage account list --resource-group az900-lab-rg --query "[].id" --output tsv
# 6. The same thing from Azure PowerShell, to prove the tools are equivalent
pwsh -c "Get-AzResourceGroup -Name az900-lab-rg | Select-Object ResourceGroupName, Location, ProvisioningState"
# 7. Clean up: deleting the group deletes everything in it
az group delete --name az900-lab-rg --yes --no-wait
Watch for three things while it runs: the second deployment reports no changes (idempotence), the resource ID contains providers/Microsoft.Storage/storageAccounts (resource provider and type), and the group deletion removes the storage account without you naming it (lifecycle container).
Scenario Drill
| # | Scenario | Answer |
|---|---|---|
| 1 | Which service receives and authorises every create, update and delete request from any Azure tool? | Azure Resource Manager |
| 2 | Microsoft.Compute is an example of what? | A resource provider |
| 3 | A policy is assigned to a subscription; does it apply to a new resource group created next week? | Yes, inheritance from the subscription scope |
| 4 | Can a resource group in West Europe contain a VM in East US? | Yes; the group location only stores metadata |
| 5 | Delete a resource group; what happens to its 12 resources? | All deleted |
| 6 | Tag a resource group env=prod; do its VMs now carry the tag? | No, tags are not inherited (use Azure Policy to enforce) |
| 7 | A lock prevents deleting a storage account; can a user still delete blobs inside it? | Yes; locks act on the control plane, blobs are data plane |
| 8 | Which capability exists in the portal but not in the CLI or PowerShell? | None; all tools use the same Resource Manager API |
| 9 | Engineer must run az commands from a locked-down kiosk with nothing installed | Azure Cloud Shell |
| 10 | Cloud Shell session unused for 25 minutes | It has timed out (20-minute idle limit) |
| 11 | Scripts must survive between Cloud Shell sessions | Persistent storage: Azure Files share holding the 5 GB home image |
| 12 | Team of Windows administrators wants object-based scripting | Azure PowerShell (Az module) |
| 13 | Team writes Bash on Linux and wants JSON output they can filter | Azure CLI with --query |
| 14 | ”Deploy the same three-tier environment to dev, test and prod with no manual steps” | Infrastructure as code: ARM template or Bicep |
| 15 | Template describes what to build, not the steps | Declarative |
| 16 | Deploying the same Bicep file twice produces no changes the second time | Idempotence |
| 17 | Group holds resources A, B, C; template holds A, B, D; incremental deployment | A, B, C, D remain |
| 18 | Same as 17 but complete mode | C is deleted; A, B, D remain |
| 19 | Need to see which resources a deployment would delete before running it | What-if |
| 20 | Share an approved template so other teams can deploy but not modify it | Template spec |
| 21 | Legacy question offers “Azure Blueprints” for packaging policies, roles and templates for new subscriptions | Blueprints is being retired (January 31, 2027); the modern answer is deployment stacks plus template specs |
| 22 | On-premises and AWS servers must appear in Azure inventory and be governed by Azure Policy | Azure Arc with the Connected Machine agent |
Mistakes to Avoid
- Thinking the portal, CLI and PowerShell have different capabilities. They are different front ends for one API. Choose by team skills and repeatability, not by features.
- Describing Cloud Shell as a local tool. It is a browser-accessible terminal on a temporary Azure-hosted machine, pre-authenticated, with a 20-minute idle timeout.
- Equating Azure Arc with migration or connectivity. Arc manages resources where they are. Azure Migrate moves them; VPN Gateway and ExpressRoute connect networks.
- Assuming resource group location constrains resource location. It does not; it is the metadata and control-plane routing location.
- Expecting a lock to protect data-plane contents. Locks, Policy and deny settings act on Resource Manager operations only.
- Confusing incremental mode with “merge”. Redeploying a resource reapplies every property; omitted ones reset to defaults.
- Reaching for complete mode to delete resources. It is not recommended and is being deprecated; deployment stacks are the current answer.
- Treating Bicep as a different engine. It transpiles to ARM JSON; same resource types, same scopes, same what-if, same deployment history.
- Carrying Azure Blueprints into 2027. It retires on January 31, 2027; template specs and deployment stacks replace it.
Where This Fits in Your AZ-900 Prep
This skill group is one quarter of the “Describe Azure management and governance” domain, which carries 30 to 35 percent of the exam. Pair it with the management and governance guide for cost management, Policy, locks and Purview, the monitoring tools guide for Advisor, Service Health and Azure Monitor, and the core architecture guide for the scope hierarchy itself.
Then test the reflexes. Our free AZ-900 practice questions include tooling items, and the AZ-900 mock exam bundle runs you through full-length timed exams where these cues are mixed in with the rest of the syllabus, which is the only realistic test of whether “Arc” and “Migrate” still blur together under pressure. If you are planning the whole run-up, the 30-day AZ-900 study plan slots this material into week three.
Frequently Asked Questions
What is Azure Resource Manager in simple terms?
It is the management layer that every Azure tool talks to. The portal, Azure CLI, Azure PowerShell, SDKs and templates all send requests to Resource Manager, which authenticates them with Microsoft Entra ID, authorises them with RBAC, checks Azure Policy and locks, and forwards them to the resource provider (such as Microsoft.Compute) that creates or changes the resource.
Is there anything the Azure portal can do that the Azure CLI cannot?
No. All capabilities in the portal are also available through PowerShell, the Azure CLI, REST and the SDKs, because they share one API. New API features reach the portal within 180 days. The practical exception runs the other way: a few advanced operations, such as complete-mode deployments, are not exposed in the portal at all.
What is the difference between Azure CLI and Azure PowerShell?
Both are cross-platform scripting interfaces to Resource Manager with equivalent capabilities. The Azure CLI uses az commands with JSON output and fits Bash-style scripting; Azure PowerShell uses Az module cmdlets (New-AzVM) that pass objects through the PowerShell pipeline and fits teams already invested in PowerShell. The AZ-900 exam distinguishes them by the team’s skills, not by features.
What is Azure Cloud Shell and does it cost anything?
A browser-accessible terminal, in Bash or PowerShell, running on a temporary Azure-hosted machine with the Azure CLI and Azure PowerShell pre-installed and already signed in as you. The machine is free; if you choose persistent storage, your home directory is kept in an Azure Files share (5 GB image) and you pay standard storage rates. Sessions time out after 20 minutes of inactivity. You can also run it with no storage account in an ephemeral session.
What is the difference between an ARM template and Bicep?
Both are declarative descriptions of Azure resources deployed by Resource Manager. An ARM template is JSON with bracketed expressions; Bicep is a cleaner domain-specific language that is converted into an ARM JSON template at deployment time, infers dependencies automatically and supports modules. Anything valid in ARM JSON is valid in Bicep, and Microsoft recommends Bicep for new work.
What happens in complete mode versus incremental mode?
Incremental mode (the default) adds or updates the resources in the template and leaves other resources in the resource group alone. Complete mode also deletes resources in the group that are not in the template. Complete mode works only for root-level resource-group deployments, is not available in the portal, respects locks, and is being phased out in favour of deployment stacks.
What is the purpose of Azure Arc?
To extend Azure management and governance to resources outside Azure. Installing the Connected Machine agent makes an on-premises or other-cloud server an Azure resource with its own resource ID, so Azure Policy, Azure Monitor, Update Manager, Defender for Cloud, RBAC and tags apply to it exactly as they do to native Azure resources. Arc also manages Kubernetes clusters, SQL Server and data services, VMware and System Center VMs, and Azure Local. It does not migrate workloads or connect networks.
Conclusion
The five bullets in this skill group describe one engine and its doors. Azure Resource Manager authenticates, authorises and routes every request to a resource provider; the portal, Cloud Shell, the Azure CLI and Azure PowerShell are interchangeable ways to send those requests; ARM templates and Bicep send them declaratively so environments are repeatable and idempotent; and Azure Arc widens the set of resources the engine can see to include servers and clusters that are not in Azure at all.
Hold on to the handful of rules the distractors are built from: tools are equal in capability and differ in ergonomics, resource group location is metadata, locks and Policy act on the control plane, incremental leaves and complete deletes, Bicep transpiles to ARM JSON, deployment stacks replace both complete mode and Blueprints, and Arc manages rather than migrates. With those in place, this quarter of the management and governance domain becomes the easiest part of the AZ-900 to score full marks on.