ARM Templates
An ARM templateA JSON file that declaratively defines the infrastructure and configuration to deploy to Azure. Every ARM template must contain $schema and contentVersion as required top-level fields; parameters, variables, resources, and outputs are optional but commonly used. is a JSON file that declaratively defines the infrastructure and configuration to deploy to Azure, with $schema and contentVersion as the only required top-level fields.
The resources array is where you declare resource types, API versions, names, locations, and properties for each resource to deploy.
Bicep
BicepA domain-specific language (DSL) that compiles down to ARM JSON before deployment — it is not a separate runtime but a cleaner authoring layer on top of ARM. Bicep eliminates JSON verbosity with native string interpolation and no bracket expressions. is a domain-specific language that compiles to ARM JSON before deployment — it is not a separate runtime but a cleaner authoring layer on top of ARM.
Because Bicep compiles to ARM, anything you can do in ARM you can do in Bicep.
Deployment Modes
Incremental modeThe default ARM deployment mode that adds or updates resources declared in the template but leaves existing resources NOT in the template untouched. is the default mode — it adds or updates declared resources but leaves existing resources not in the template untouched. Complete modeAn ARM deployment mode that deletes any resources in the resource group that are NOT declared in the template — use with extreme care as it can delete existing resources. deletes any resources in the resource group that are NOT declared in the template — use with extreme care.
ARM vs. Bicep Comparison
| Aspect | ARM (JSON) | Bicep |
|---|---|---|
| File extension | .json | .bicep |
| Syntax | Verbose JSON, bracket expressions | Clean DSL, string interpolation |
| Compile step | None — native format | Compiles to ARM JSON automatically |
| Tooling | VS Code ARM Tools extension | VS Code Bicep extension |
| Convert ARM → Bicep | N/A | az bicep decompile --file main.json |
| Convert Bicep → ARM | N/A | az bicep build --file main.bicep |
| Deployment command | az deployment group create | az deployment group create (same) |
Required vs. Optional Template Fields
Must Memorize
Only $schema and contentVersion are required top-level fields in an ARM template. parameters, variables, resources, and outputs are all optional in the schema definition (though resources is almost always present).
Deployment Mode Behavior
Exam Trap
"Incremental mode will delete resources not in the template." → Only Complete mode deletes unlisted resources. Incremental mode (the default) leaves existing resources untouched. Complete mode can accidentally delete resources if used carelessly.
Bicep is Not a Separate Runtime
Exam Trap
"Bicep is a completely separate technology from ARM." → Bicep compiles to ARM JSON at deployment time. Azure only ever receives ARM JSON; Bicep is purely an authoring improvement. The deployment command is identical for both.
Deployment Mode is Set at Runtime
Exam Trap
"You can change the deployment mode by editing the template file." → Deployment mode is specified at deployment time via the CLI flag --mode Complete|Incremental, not inside the template itself.
Decompilation is Best-Effort
Exam Trap
"az bicep decompile guarantees a perfect Bicep file." → Decompilation is best-effort. The generated Bicep file may contain warnings and will often need manual edits to follow best practices.
Portal Export
Exam Tip
The Azure portal can export as either ARM JSON or Bicep directly (a portal-only feature for Bicep export). Bicep export via CLI requires exporting JSON first, then running az bicep decompile.
Deploy an ARM Template from the Portal
- Portal → search "Deploy a custom template" → select Deploy a custom template
- Click Build your own template in the editor → paste or upload your JSON → Save
- Fill in subscription, resource group, parameters → Review + create → Create
Export a Template from an Existing Resource
- Portal → navigate to any resource (e.g., a Storage Account)
- Left blade → Export template (under Automation)
- Review the generated JSON or Bicep → Download or Deploy
Decompile ARM JSON to Bicep (CLI)
# Export resource group as ARM JSON
az group export --name myResourceGroup > main.json
# Convert ARM JSON to Bicep
az bicep decompile --file main.json
# Review and edit the resulting main.bicep before deploying
Deploy a Bicep File via CLI
az deployment group create \
--resource-group myRG \
--template-file main.bicep \
--parameters @params.json
Deploy in Complete Mode (Destructive — Use with Care)
az deployment group create \
--resource-group myRG \
--template-file main.json \
--mode Complete
AZ-104 Exam Focus
Exam Trap
"Bicep is a completely separate technology from ARM." → Bicep compiles to ARM JSON at deployment time. Azure always receives and processes ARM JSON; Bicep is purely a developer-facing authoring improvement.
Exam Trap
"Incremental mode will delete resources not in the template." → Only Complete mode deletes unlisted resources. Incremental (default) leaves them untouched.
Exam Trap
"outputs are required in an ARM template." → Only $schema and contentVersion are required. parameters, variables, resources, and outputs are all optional in the schema.
Exam Trap
"You can change the deployment mode by editing the template file." → Deployment mode is a runtime flag (--mode) — it is NOT set inside the template file itself.
Exam Trap
"az bicep decompile guarantees a perfect Bicep file." → Decompilation is best-effort and may require manual cleanup. Generated Bicep files often contain warnings.
Exam Tip
The command to convert ARM JSON to Bicep is az bicep decompile. The reverse (Bicep to ARM) is az bicep build. These are commonly tested in reverse-order trick questions.
Question — click to flip
Q: Which two fields are REQUIRED in every ARM template?
Question — click to flip
Q: What is the command to convert an ARM JSON template to Bicep?
Question — click to flip
Q: What happens to resources NOT in the template when deploying in Complete mode?
Question — click to flip
Q: What does Azure actually receive and process when you deploy a Bicep file?
Question — click to flip
Q: Where is deployment mode (Incremental vs. Complete) specified?
Question — click to flip
Q: What does Incremental deployment mode do to existing resources not in the template?