0
0
Azurecloud~5 mins

ARM vs Bicep vs Terraform decision in Azure - CLI Comparison

Choose your learning style9 modes available
Introduction
When you want to create and manage resources in Azure, you need a way to describe what you want. ARM templates, Bicep, and Terraform are tools that help you do this. Choosing the right one depends on your needs and comfort with each tool.
When you want to use a Microsoft-supported tool that works directly with Azure and prefer JSON format, use ARM templates.
When you want simpler, cleaner code than ARM templates but still want to stay within Azure's native tooling, use Bicep.
When you want to manage resources across multiple clouds or prefer a tool with a large community and simpler syntax, use Terraform.
When you want to reuse and share infrastructure code easily with others, Terraform offers modules and a big ecosystem.
When you want to avoid writing complex JSON and prefer a language that compiles to ARM templates, Bicep is a good choice.
Commands
This command deploys an ARM template named azuredeploy.json to the resource group example-rg. It shows how to apply ARM templates directly in Azure.
Terminal
az deployment group create --resource-group example-rg --template-file azuredeploy.json
Expected OutputExpected
{ "id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/example-rg/providers/Microsoft.Resources/deployments/deployment1", "name": "deployment1", "properties": { "provisioningState": "Succeeded" } }
--resource-group - Specifies the Azure resource group to deploy to
--template-file - Specifies the ARM template file to use
This command compiles a Bicep file named main.bicep into an ARM template JSON file. It shows how Bicep simplifies writing infrastructure code by converting it to ARM JSON.
Terminal
bicep build main.bicep
Expected OutputExpected
The Bicep file main.bicep was successfully compiled to main.json
This command initializes a Terraform working directory. It downloads the Azure provider plugin and prepares Terraform to manage Azure resources.
Terminal
terraform init
Expected OutputExpected
Initializing the backend... Initializing provider plugins... - Finding latest version of hashicorp/azurerm... - Installing hashicorp/azurerm v3.0.0... - Installed hashicorp/azurerm v3.0.0 (signed by HashiCorp) Terraform has been successfully initialized!
This command applies the Terraform configuration to create or update Azure resources without asking for confirmation. It shows how Terraform manages infrastructure changes.
Terminal
terraform apply -auto-approve
Expected OutputExpected
azurerm_resource_group.example: Creating... azurerm_resource_group.example: Creation complete after 2s [id=/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/example-rg] Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
-auto-approve - Skips interactive approval before applying changes
Key Concept

If you remember nothing else, remember: ARM templates are native but complex JSON, Bicep is simpler and compiles to ARM, and Terraform is cloud-agnostic with a friendly syntax.

Common Mistakes
Trying to write ARM templates directly without using Bicep or tools
ARM templates are complex JSON and hard to maintain by hand
Use Bicep to write simpler code that compiles to ARM templates
Using Terraform without initializing the directory first
Terraform needs to download providers and set up before applying changes
Always run 'terraform init' before 'terraform apply'
Mixing ARM template deployment commands with Terraform commands
They are different tools with different workflows and files
Choose one tool per project and follow its workflow consistently
Summary
Use 'az deployment group create' to deploy ARM templates directly to Azure.
Use 'bicep build' to convert Bicep files into ARM templates for simpler authoring.
Use 'terraform init' and 'terraform apply' to manage Azure resources with Terraform's cloud-agnostic approach.