This chapter covers the Azure Resource Manager (ARM) REST API, the foundational control plane for managing Azure resources programmatically. As an Azure developer, you will use ARM REST API to automate deployment, configuration, and management of resources. On the AZ-204 exam, approximately 10-15% of questions touch on ARM REST API, especially in the context of deploying resources, managing resource groups, and implementing role-based access control (RBAC). Understanding the ARM REST API is critical for developing robust automation scripts and integrating Azure management into custom applications.
Jump to a section
Imagine you are building a large office complex. You have a project manager (Azure Resource Manager) who does not do any physical construction but coordinates everything. You submit a blueprint (an ARM template) that specifies exactly what rooms, wiring, and plumbing you need, and their dependencies—for example, you cannot install electrical wiring until the walls are framed. The project manager validates your blueprint against building codes (Azure policies) and then breaks it into individual work orders (REST API calls). Each work order is sent to the appropriate trade (resource provider) like electricians (Microsoft.Compute) or plumbers (Microsoft.Network). The project manager tracks the status of every work order, ensuring they are executed in the correct order. If a work order fails (e.g., electricians find a conflict), the project manager can roll back all completed work orders to avoid a partially built, unstable structure. The project manager also keeps a log of every change (audit log) so you can see who requested what and when. Importantly, you can query the project manager at any time to see the current state of the building (GET requests) or submit change orders (PATCH requests) to modify specific parts without rebuilding everything.
What is the Azure Resource Manager REST API?
The Azure Resource Manager (ARM) REST API is a set of HTTP-based endpoints that allow you to create, read, update, and delete (CRUD) Azure resources. It is the programmatic interface to the Azure Resource Manager, the deployment and management service for Azure. The API is RESTful, meaning it uses standard HTTP methods (GET, PUT, POST, DELETE, PATCH) and returns JSON responses. Every action you perform in the Azure portal, Azure CLI, or PowerShell ultimately calls the ARM REST API.
Why ARM REST API Exists
Before ARM, Azure had a classic deployment model that was less flexible and did not support resource grouping or declarative templates. ARM introduced a unified API that allows you to manage resources as a group, apply policies, and use role-based access control. The ARM REST API provides a consistent way to interact with any Azure resource, regardless of the resource provider (e.g., Microsoft.Compute, Microsoft.Network, Microsoft.Storage).
How It Works Internally
When you make a request to the ARM REST API, the flow is:
Authentication: You must include a valid OAuth 2.0 bearer token in the Authorization header. The token is obtained from Azure Active Directory (Azure AD).
Request Routing: The request URL includes the subscription, resource group, resource provider, and resource name. For example: https://management.azure.com/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/virtualMachines/{vmName}?api-version=2023-03-01.
Validation: ARM validates the request against Azure policies, RBAC permissions, and the resource provider's schema.
Resource Provider Execution: ARM forwards the request to the appropriate resource provider (e.g., Microsoft.Compute). The resource provider performs the actual operation on the resource (e.g., creating a VM).
Response: ARM returns a JSON response with the resource properties, status, and any error messages.
Key Components, Values, Defaults, and Timers
- API Version: Every resource type has a specific API version (e.g., 2023-03-01). You must include the api-version query parameter in every request. Using the wrong version can cause unexpected behavior or errors.
- HTTP Methods:
- GET: Retrieve resource properties or list resources.
- PUT: Create or update a resource (idempotent).
- PATCH: Partial update of a resource.
- DELETE: Delete a resource.
- POST: Perform an action (e.g., start a VM).
- Status Codes:
- 200 OK: Success.
- 201 Created: Resource created.
- 202 Accepted: Operation accepted (for async operations).
- 204 No Content: Success with no response body.
- 400 Bad Request: Invalid input.
- 401 Unauthorized: Missing or invalid authentication.
- 403 Forbidden: Insufficient permissions.
- 404 Not Found: Resource not found.
- 409 Conflict: Resource state conflict.
- Async Operations: Some operations (like creating a VM) are asynchronous. ARM returns 202 Accepted with a Location header pointing to a status URL. You must poll this URL until the operation completes (status Succeeded or Failed).
- Throttling: ARM has rate limits: 12,000 read requests per hour and 1,200 write requests per hour per subscription. Exceeding these limits returns 429 Too Many Requests.
Configuration and Verification Commands
To call the ARM REST API, you need to authenticate. Using Azure CLI, you can obtain a token:
az account get-access-token --resource https://management.azure.com --query accessToken -o tsvThen, use curl or any HTTP client to make requests. For example, to list all resource groups:
curl -X GET "https://management.azure.com/subscriptions/{subscriptionId}/resourcegroups?api-version=2021-04-01" \
-H "Authorization: Bearer {token}"To create a resource group:
curl -X PUT "https://management.azure.com/subscriptions/{subscriptionId}/resourcegroups/{resourceGroupName}?api-version=2021-04-01" \
-H "Authorization: Bearer {token}" \
-H "Content-Type: application/json" \
-d '{"location": "eastus"}'To deploy an ARM template:
curl -X PUT "https://management.azure.com/subscriptions/{subscriptionId}/resourcegroups/{resourceGroupName}/providers/Microsoft.Resources/deployments/{deploymentName}?api-version=2021-04-01" \
-H "Authorization: Bearer {token}" \
-H "Content-Type: application/json" \
-d @template.jsonInteraction with Related Technologies
Azure CLI and PowerShell: Both tools are wrappers around the ARM REST API. Any command you run in CLI or PowerShell ultimately makes REST API calls.
ARM Templates: These are JSON files that define resources and their dependencies. When you deploy a template, ARM translates it into REST API calls.
Azure Policy: Policies are evaluated during PUT requests. If a resource violates a policy, the request is denied.
Role-Based Access Control (RBAC): Permissions are checked on every request. The caller must have the appropriate role assignment at the relevant scope (management group, subscription, resource group, or resource).
Azure Resource Graph: This service uses a different endpoint (https://management.azure.com/providers/Microsoft.ResourceGraph/resources?api-version=2021-03-01) to query resources across subscriptions using Kusto Query Language (KQL). It is read-only and complements ARM REST API for complex queries.
Error Handling and Troubleshooting
Common errors and their resolutions:
401 Unauthorized: Token expired or invalid. Refresh the token.
403 Forbidden: Insufficient permissions. Check RBAC assignments.
404 Not Found: Resource does not exist or URL is incorrect. Verify subscription, resource group, and resource names.
409 Conflict: Resource is in a state that cannot be modified (e.g., deleting a VM that is still running). Ensure the resource is in the correct state.
429 Too Many Requests: Throttling. Implement exponential backoff with retry logic.
Best Practices
Use the lowest API version that supports the features you need for stability.
Implement retry logic with exponential backoff for transient failures and throttling.
Use managed identities for Azure resources to avoid storing credentials.
For long-running operations, poll the status URL and handle timeouts (default timeout for async operations is 1 hour).
When deploying templates, use incremental mode (default) to add resources without deleting existing ones. Use complete mode only when you want to replace the entire resource group.
Security Considerations
Always use HTTPS.
Store tokens securely; never hardcode them.
Use Azure Key Vault to store secrets that need to be accessed during deployments.
Implement least privilege by assigning custom roles with only the necessary permissions.
Obtain an Azure AD token
Before any ARM REST API call, you must authenticate with Azure AD. Use OAuth 2.0 client credentials flow or authorization code flow. For automation, use a service principal. Request a token for resource `https://management.azure.com`. The token is a JWT that includes claims like `aud` (audience) and `exp` (expiration). The token is valid for typically 1 hour. Use Azure CLI command `az account get-access-token --resource https://management.azure.com` to get a token for testing.
Construct the REST API URL
The URL follows a specific pattern: `https://management.azure.com/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/{resourceProviderNamespace}/{resourceType}/{resourceName}?api-version={apiVersion}`. For example, to get a virtual machine, use `https://management.azure.com/subscriptions/12345/resourceGroups/myRG/providers/Microsoft.Compute/virtualMachines/myVM?api-version=2023-03-01`. The `api-version` parameter is mandatory and must match the resource provider's supported versions.
Set HTTP headers
Include the `Authorization` header with the bearer token from step 1. For PUT and POST requests, include `Content-Type: application/json`. Optionally, include `x-ms-client-request-id` for tracing. The request body, if any, must be JSON. For example: `Authorization: Bearer eyJ0eXAiOi...`.
Send the HTTP request
Use an HTTP client (curl, Postman, or HttpClient in .NET) to send the request. For GET requests, no body is needed. For PUT, the body contains the resource properties. For DELETE, no body. The request is routed to the ARM endpoint, which validates the token, checks RBAC permissions, and forwards to the resource provider.
Handle the response
ARM returns an HTTP status code and a JSON response body. For synchronous operations (e.g., GET), the response contains the resource properties. For async operations (e.g., PUT to create a VM), status 202 Accepted is returned with a `Location` header pointing to a status URL. Poll this URL with GET requests until the status changes to 'Succeeded' or 'Failed'. The polling interval should be at least 5 seconds to avoid throttling.
Handle errors and retry
If the response is 429 (Too Many Requests) or 5xx server errors, implement retry logic with exponential backoff. For example, wait 2 seconds, then 4, then 8, up to a maximum of 60 seconds. Check the `Retry-After` header if present. For 4xx errors (except 429), do not retry; fix the request. Log the `x-ms-request-id` for support tickets.
Enterprise Scenario 1: Automated Deployment of Multi-Tier Application
A large e-commerce company uses ARM REST API to deploy their application stack across multiple environments (dev, test, prod) consistently. They have a CI/CD pipeline that triggers a PowerShell script, which calls the ARM REST API to deploy an ARM template. The template includes a virtual network, subnets, network security groups, VMs, and a load balancer. The script uses a service principal with contributor rights on the target resource group. The deployment is idempotent; if a resource already exists, it is updated. The team uses the What-If operation (POST to /deployments/{name}/whatIf) to preview changes before actual deployment. Common issues include API version mismatches (template uses an older version than the resource provider supports) and RBAC permissions (service principal missing write permission on a resource type). They mitigate by using the Azure Resource Graph to validate existing resources before deployment.
Enterprise Scenario 2: Custom Dashboard for Resource Monitoring
A managed services provider (MSP) monitors hundreds of Azure subscriptions for their clients. They built a custom web application that uses ARM REST API to fetch resource metadata (e.g., VM sizes, disk states, tags) every 15 minutes. The app uses multiple service principals, each with Reader role on a set of subscriptions, to avoid throttling. They implemented pagination handling because list operations return only 1000 resources per page (via $top and $skipToken). They also use the ARM REST API to trigger actions like starting/stopping VMs based on schedules. The major challenge is token expiration; they refresh tokens proactively every 50 minutes. They also handle 429 errors by queuing requests and retrying with a 30-second delay.
Enterprise Scenario 3: Policy Enforcement and Compliance Auditing
A financial institution uses Azure Policy to enforce tagging and resource location restrictions. Their compliance team uses ARM REST API to audit resources. They run a daily script that calls the ARM REST API to list all resources and their tags, then cross-references with a database of required tags. Resources missing tags are flagged. They also use the ARM REST API to query Azure Policy states (/providers/Microsoft.PolicyInsights/policyStates/latest/queryResults). Misconfiguration example: a developer created a VM with a deprecated API version, causing the PUT request to fail with 400 Bad Request. The team now validates the API version against a list of supported versions before making calls.
What AZ-204 Tests on ARM REST API (Objective 1.3)
The exam focuses on your ability to:
Authenticate to ARM using Azure AD (service principals, managed identities).
Construct correct REST API URLs with required parameters (api-version, subscription, resource group).
Interpret HTTP status codes and handle async operations.
Implement retry logic for throttling (429) and transient failures.
Use ARM templates and understand the difference between incremental and complete deployment modes.
Interact with Azure Resource Graph for cross-subscription queries.
Common Wrong Answers and Why Candidates Choose Them
Using `api-version` as a header instead of query parameter: Many candidates assume api-version is passed as a header because other APIs do that. The ARM REST API requires it as a query parameter. The exam may present a URL without api-version or with it in the header; the correct answer will include ?api-version=2021-04-01 in the URL.
Assuming all operations are synchronous: Candidates often forget that PUT, DELETE, and POST can be async. They might expect a 200 OK immediately. The correct behavior is to check for 202 Accepted and poll the Location header.
Confusing ARM REST API with Azure Service Management (ASM) API: The classic deployment model uses a different endpoint (https://management.core.windows.net). Exam questions will specify 'Azure Resource Manager' or 'ARM'; any reference to classic management should be rejected.
Using the wrong HTTP method for partial updates: Some candidates use PUT for partial updates, which replaces the entire resource. The correct method is PATCH. The exam may test this by asking how to update a single property of a VM without affecting others.
Specific Numbers, Values, and Terms
Throttle limits: 12,000 reads/hour, 1,200 writes/hour per subscription.
Default polling interval: No official default; best practice is 5-10 seconds.
Token lifetime: 1 hour default for Azure AD tokens.
API version format: YYYY-MM-DD or YYYY-MM-DD-preview.
Location header: Used for async operation status.
What-If operation: POST to /deployments/{name}/whatIf.
Edge Cases and Exceptions
Deleting a resource that is in a failed state: The DELETE may succeed even if the resource is in a failed state. The exam might ask if you can delete a VM that failed to create; the answer is yes.
Resource move: Moving a resource across resource groups or subscriptions requires a POST to the move endpoint (/moveResources). The operation is async.
Tagging: Updating tags on a resource uses PATCH, but you must include all existing tags to avoid losing them.
How to Eliminate Wrong Answers
If the question involves authentication, look for 'bearer token' and 'Azure AD'.
If the question involves deployment modes, 'incremental' is the default and safer; 'complete' deletes resources not in the template.
If the question involves error handling, look for 'Retry-After' header and exponential backoff.
If the question involves listing resources, look for pagination parameters $top and $skipToken.
ARM REST API is the control plane for managing Azure resources; all management tools use it under the hood.
Always include the api-version query parameter in every request; use the latest stable version for new projects.
Authenticate with a bearer token from Azure AD; tokens expire after 1 hour by default.
Handle async operations by polling the Location header until status is 'Succeeded' or 'Failed'.
Implement retry logic with exponential backoff for 429 (throttling) and 5xx errors.
Use PATCH for partial updates; PUT replaces the entire resource.
Throttle limits: 12,000 reads/hour and 1,200 writes/hour per subscription.
Azure Resource Graph provides a separate query API for cross-subscription resource discovery.
These come up on the exam all the time. Here's how to tell them apart.
ARM REST API
Direct HTTP calls; requires token management.
Full control over HTTP methods, headers, and body.
Suitable for custom automation and integration.
Requires handling of async operations and polling.
Can be used from any programming language with HTTP support.
Azure CLI
High-level commands; handles authentication automatically.
Limited to predefined commands; may not support all API features.
Suitable for interactive use and simple scripting.
Handles async operations automatically with --no-wait flag.
Only available in shell environments (bash, PowerShell).
Mistake
ARM REST API requires the api-version parameter in the HTTP header.
Correct
The api-version is a query parameter, not a header. For example: `?api-version=2021-04-01`. Using it as a header will result in a 400 Bad Request.
Mistake
All ARM REST API operations are synchronous and return immediately.
Correct
Many operations (especially creates, deletes, and actions) are asynchronous. They return 202 Accepted with a Location header for status polling.
Mistake
You can use any HTTP client without authentication to call ARM REST API.
Correct
Every request must include an OAuth 2.0 bearer token from Azure AD. Unauthenticated requests return 401 Unauthorized.
Mistake
The ARM REST API endpoint is https://management.core.windows.net.
Correct
That endpoint is for the classic deployment model (Azure Service Management). The ARM endpoint is https://management.azure.com.
Mistake
You can update a single property of a resource using PUT with only that property in the body.
Correct
PUT replaces the entire resource. For partial updates, use PATCH. Using PUT with missing properties will set them to default values or null.
Reveal each answer, then mark whether you got it right. Score 60%+ to unlock the next chapter.
Use the `Azure.Identity` library with `DefaultAzureCredential` or `ClientSecretCredential` for service principals. First, install the `Azure.Identity` and `Azure.ResourceManager` NuGet packages. Then, create a `ArmClient` object with the credential. For example: `var credential = new DefaultAzureCredential(); var client = new ArmClient(credential);`. From there, you can use the `ArmClient` to get subscription and resource group objects. The library handles token acquisition and renewal automatically.
In incremental mode (default), the deployment adds resources to the resource group without deleting existing resources that are not in the template. Properties of existing resources are updated only if specified. In complete mode, the deployment deletes any resources in the resource group that are not defined in the template. Use complete mode with caution, especially in production, as it can delete resources unintentionally. The mode is specified in the `properties.mode` field of the deployment request.
List operations return a maximum of 1000 resources per page. The response includes a `nextLink` property (or `$skipToken` in some APIs) that you use to fetch the next page. For example, after the first GET request, check if `nextLink` is present; if so, make a GET request to that URL. Continue until `nextLink` is null. In Azure CLI, the `--output table` automatically handles pagination.
Yes, but you need a token from each tenant. You can use a multi-tenant application or acquire tokens individually. The REST API calls are scoped to a specific tenant; you must include the correct token for the tenant that owns the subscription. Use the `tenantId` claim in the token to verify.
A 409 Conflict usually means the resource already exists or is in a state that prevents the operation. For example, trying to create a VM with a name that already exists. Check if the resource exists with a GET request. If it exists, you may need to update it (PUT) or delete it first. Also, some resources have dependencies; ensure dependent resources are in a 'Succeeded' state.
The What-If operation previews the changes that a deployment will make without actually applying them. Send a POST request to the deployment endpoint with the `whatIf` action: `POST https://management.azure.com/subscriptions/{subId}/resourcegroups/{rg}/providers/Microsoft.Resources/deployments/{deployName}/whatIf?api-version=2021-04-01`. The request body is the same as a normal deployment. The response includes a list of changes (create, update, delete) with resource properties.
An ARM template can contain up to 800 resources. If you need more, you can use nested or linked templates. Each deployment can have up to 256 linked templates. Also, the total template size (including linked templates) cannot exceed 4 MB.
You've just covered Azure Resource Manager REST API — now see how well it sticks with free AZ-204 practice questions. Full explanations included, no account needed.
Done with this chapter?