Bicep vs ARM Templates

Azure Resource Manager (ARM) templates describe cloud resources in JSON. Bicep describes the same resources in a shorter, friendlier language. Both reach Azure through the same deployment engine, so a Bicep file gains nothing and loses nothing in power compared with its JSON cousin.

Picture two recipe books. One packs every step into dense wording with brackets and quotation marks on every line. The other uses short, plain sentences. Both books produce the same meal. ARM JSON plays the dense book, and Bicep plays the plain one.

A Storage Account in ARM JSON

An ARM template needs a schema link, a version number, and square-bracket expressions wrapped in quotes.

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "storageName": { "type": "string" }
  },
  "resources": [
    {
      "type": "Microsoft.Storage/storageAccounts",
      "apiVersion": "2023-01-01",
      "name": "[parameters('storageName')]",
      "location": "[resourceGroup().location]",
      "sku": { "name": "Standard_LRS" },
      "kind": "StorageV2"
    }
  ]
}

The Same Storage Account in Bicep

Bicep drops the schema line, the quotes around keys, and the bracket syntax. The result fits in a handful of lines.

param storageName string

resource storage 'Microsoft.Storage/storageAccounts@2023-01-01' = {
  name: storageName
  location: resourceGroup().location
  sku: {
    name: 'Standard_LRS'
  }
  kind: 'StorageV2'
}

How a Bicep File Reaches Azure

Azure never reads Bicep directly. The Bicep tools translate the file into ARM JSON, and Azure Resource Manager builds the resources from that JSON.

 main.bicep          Bicep tools           main.json           Azure Resource
 (you write)   ───►  (compile step)  ───►  (ARM template)  ───►  Manager builds
                                                                  your resources

The translation happens automatically during deployment. Developers rarely open the JSON output.

Key Differences at a Glance

AreaARM TemplateBicep
LanguageJSONDeclarative Bicep syntax
LengthLong and nestedShort and flat
CommentsLimited supportSingle-line and multi-line comments
ReferencesFunctions such as reference() and resourceId()Direct symbolic names such as storage.id
DependenciesWritten by hand in dependsOnDetected automatically in most cases
ReuseLinked or nested templatesModules
Editor helpBasicIntelliSense, validation, and hints in Visual Studio Code

Convert Between the Two

Existing ARM templates do not need a rewrite from scratch. The Bicep command line converts both directions.

# Turn a Bicep file into ARM JSON
az bicep build --file main.bicep

# Turn an ARM JSON file into Bicep
az bicep decompile --file template.json

A Note on Decompiling

Decompiling gives a starting point and not a finished product. Review the generated file, rename symbolic names to something meaningful, and replace repeated values with parameters and variables.

Choosing Between Them

Pick Bicep When

New projects benefit from Bicep because the code stays readable and teammates review changes faster. Bicep supports new Azure resource types and API versions as soon as they appear.

Keep ARM JSON When

A large, stable template already runs in production and nobody plans to change it. Rewriting working code adds risk without a clear gain. Teams often convert templates one at a time as they need edits.

What Stays the Same

Resource types, API versions, property names, and deployment commands match in both formats. A developer who knows the Azure portal settings for a storage account recognizes every property in the Bicep file. Role-based access control, deployment history, and the what-if preview behave identically. Skills learned in ARM JSON transfer to Bicep, and the reverse holds as well.

Summary

ARM templates and Bicep share one deployment engine. Bicep adds cleaner syntax, direct references, automatic dependency detection, and modules. The Bicep command line compiles Bicep into JSON and decompiles JSON into Bicep, which makes a gradual move easy.