What is an ARM template? The JSON engine under every Azure deployment
You may never write one by hand — Bicep and Terraform mostly spared you — but ARM templates are the native language Azure deployments actually speak. Knowing what they are makes everything above them make sense.
New to cloud? CAMPUX is a free, build-first course. Start here →
Every time you deploy infrastructure to Azure — through the portal, a Bicep file, a pipeline — something underneath turns your intent into resources in the right order. That something is Azure Resource Manager, and its native, declarative input is the ARM template. Even if you spend your days in friendlier tools, understanding the layer they compile down to is what turns "the deploy worked" into "I know why the deploy worked."
The definition
Microsoft is precise: an ARM template "is a JavaScript Object Notation (JSON) file that defines the infrastructure and configuration for your project. The template uses declarative syntax, which lets you state what you intend to deploy without having to write the sequence of programming commands to create it." That word — declarative — is the heart of it. You describe the end state ("a storage account named X, in this region, with this SKU"), and Resource Manager figures out the how. You are writing a specification, not a script.
A template is a JSON object with a few known sections — parameters (values you pass in per environment), variables, resources (what to deploy), and outputs (values to return). A minimal one that creates a storage account:
{
"$schema": "...deploymentTemplate.json#",
"resources": [
{
"type": "Microsoft.Storage/storageAccounts",
"apiVersion": "2025-06-01",
"name": "mystorageaccount",
"location": "centralus",
"sku": { "name": "Standard_LRS" },
"kind": "StorageV2"
}
]
}
The properties that matter
The docs list what you actually get from templates, and three traits are worth carrying:
- Idempotent. "You can deploy the same template many times and get the same resource types in the same state." Deploy it once or a hundred times; if the resource already matches, nothing changes. That is what makes infrastructure as code safe to re-run.
- Orchestrated. "You don't have to worry about the complexities of ordering operations." Resource Manager works out dependencies, creates interdependent resources in the correct order, and deploys in parallel where it can.
- Previewable and validated. The
what-ifoperation shows you exactly what will create, update, or delete before you commit, and Resource Manager validates the template before it starts — so a deploy is less likely to stop half-finished.
How a template becomes real
Here is the part that demystifies the whole platform. When you deploy a template, Resource Manager converts each resource into a REST API call to the matching resource provider. Your Microsoft.Storage/storageAccounts block becomes a PUT to the storage provider's REST endpoint. This is why the portal, the CLI, Bicep, and a template are all "the same thing" underneath: they all end up as Resource Manager REST operations. The template is just a declarative front end to the API that runs Azure.
You describe the destination. Resource Manager plans the route, in the right order, and calls the API for you.
So should you write ARM JSON by hand?
Usually not — and Microsoft says so itself. The docs point you at Bicep: "a syntax that's easier to use," where "each Bicep file is automatically converted to an ARM template during deployment." So Bicep is the concise language you author; ARM JSON is the compiled output Azure actually deploys. Terraform sits alongside as the multi-cloud option. Knowing ARM templates exist, and that they are just declarative JSON turned into REST calls, is what makes Bicep click — you are not learning magic, you are learning a nicer way to write the thing Azure has always understood. Say "Bicep compiles to an ARM template, which Resource Manager turns into REST calls" in an interview and you have shown you see all the way down.
Questions people also ask
What is an ARM template used for?
It defines Azure infrastructure as a declarative JSON file, so Resource Manager can deploy it. You state the end state you want - a storage account, a VNet, a set of role assignments - and Resource Manager works out the sequence of API calls that gets you there, in the right order.
Is ARM template the same as Bicep?
No. Bicep is the language you write; ARM JSON is what Azure actually deploys. Every Bicep file is automatically converted to an ARM template during deployment. Microsoft recommends Bicep for the syntax, but the template underneath is still the same JSON Resource Manager has always understood.
Are ARM templates being deprecated?
No. Bicep is the recommended way to author templates going forward, but it compiles to ARM JSON before every deployment, so the format is not going away. Some older tooling built around raw ARM JSON is being retired in favor of Bicep-aware equivalents, but Resource Manager's native input stays ARM JSON.
What does it mean that ARM templates are idempotent?
You can deploy the same template many times and get the same resource types in the same state. If a resource already matches what the template describes, Resource Manager leaves it alone instead of duplicating it. That is what lets you re-run a deployment safely instead of tracking what already exists.
What language is an ARM template written in?
JSON. An ARM template is a JavaScript Object Notation file with a few known sections - parameters, variables, resources, and outputs. That verbosity is the reason Bicep exists: it gives you a shorter syntax for the same resources, then compiles down to this JSON before deployment.