AdvancedLesson 10 of 16

Bicep vs Terraform Decision Guide

Learn when Bicep is the right choice, when Terraform is, and how to frame the tradeoff in interviews and architecture reviews.

Simple Explanation (ELI5)

Think of Bicep as a built-in app on your phone — it works perfectly for everything that phone does natively and is always up-to-date. Terraform is like a universal remote that controls your whole home entertainment system across many brands — powerful, but you need to maintain its batteries (state file) yourself. The right choice depends entirely on whether you are managing one Azure-native home or a multi-brand house.

Why This Decision Matters

Deep Comparison

DimensionBicepTerraform
Cloud scopeAzure-native onlyMulti-cloud (Azure, AWS, GCP, and 1000+ providers)
State modelARM owns the deployment state; no external file to manageExternal state file; you manage storage, locking, access, and encryption
API version controlYou explicitly declare the API version per resource — full control, always currentProvider abstracts the API version; some lag on new Azure features until provider updates
New Azure feature availabilityAvailable same day as ARM API update (direct ARM compilation)Available after the AzureRM provider adds support — often weeks to months later
Module ecosystemAzure Verified Modules (AVM) in Bicep RegistryTerraform Registry with thousands of community and vendor modules
Learning curveModerate — Azure-specific; easier for Azure-native teamsHigher — HCL, provider management, state operations
Drift detectionBuilt into ARM; what-if shows drift before every deployterraform plan shows drift; requires state to be current to be accurate
CI/CD integrationDirect with Azure DevOps and GitHub Actions (no extra tools)Requires Terraform binary, backend config, and often a wrapper like Atlantis or TFC
Governance and policyTight native integration with Azure Policy and BlueprintsGovernance possible via Sentinel (TFC only) or custom pipeline enforcement
Secrets handling@secure() params never logged; Key Vault integration built-inState file can contain secrets; must encrypt backend and restrict access

Decision Framework

💡
Quick Decision Rule

If you answer YES to any of these, lean toward Terraform: (1) multi-cloud or multi-platform IaC is required now or planned within 2 years, (2) the team already operates Terraform at scale, (3) you need a unified state model across non-Azure resources. If all answers are NO and the team is Azure-native, Bicep removes operational overhead with no capability sacrifice.

Scenario Decision Table

ScenarioRecommendationReason
Azure-only startup, two engineers, small platformBicepNo state overhead, native tooling, quick onboarding
Enterprise with Azure + AWS workloadsTerraformSingle IaC workflow across cloud boundaries
Azure-only platform but team already knows TerraformTerraform or BicepTeam skill is a real cost; evaluate migration vs consistency
Needs latest Azure features (e.g. new AKS version same week)BicepARM API is always current; no provider lag
Governance-heavy org requiring Azure Policy enforcementBicepTighter native integration with Azure Policy and Blueprints
Platform team manages Kubernetes across cloud providersTerraformCross-provider consistency for cluster config and RBAC
Dev teams want self-service Azure environmentsBicep (as modules in AVM)Vended through Azure Verified Modules, no Terraform operator required

State Model: The Core Difference

The most important architectural difference is the state model. Understanding it clearly wins interviews.

AspectBicep (ARM model)Terraform (tfstate model)
Where state livesInside Azure Resource Manager — no external fileIn a storage backend you provision and secure
Drift detection triggerEvery deploy runs what-if implicitly through ARMOnly when you run terraform plan against current state
Concurrent run safetyAzure serialises deployments per resource group nativelyRequires backend locking (e.g. Blob lease or DynamoDB) to prevent corruption
State corruption riskARM owns it — very low risk of corruptionPossible if locking is missing or state is edited manually
Resource importUse existing keyword for existing resourcesterraform import to bring unmanaged resources under state
⚠️
Common Mistake

Teams sometimes run both Bicep and Terraform against the same resources, creating conflicting ownership. Establish tool ownership per resource boundary before adoption. Mixed tool use requires explicit team agreement on who owns what.

Hands-on Parallel Example

bicep
// Bicep: Deploy a storage account — ARM API version explicit, no state file
resource storage 'Microsoft.Storage/storageAccounts@2023-01-01' = {
  name: 'stplatformdev001'
  location: resourceGroup().location
  sku: { name: 'Standard_LRS' }
  kind: 'StorageV2'
  properties: {
    allowBlobPublicAccess: false
    minimumTlsVersion: 'TLS1_2'
  }
}
hcl
# Terraform: Same storage account — provider abstracts API version, tfstate required
resource "azurerm_storage_account" "platform" {
  name                     = "stplatformdev001"
  resource_group_name      = azurerm_resource_group.platform.name
  location                 = azurerm_resource_group.platform.location
  account_tier             = "Standard"
  account_replication_type = "LRS"
  allow_nested_items_to_be_public = false
  min_tls_version          = "TLS1_2"
}

Interview Questions

Beginner

What is the most important difference between Bicep and Terraform?

Bicep is Azure-native and manages deployment state inside ARM. Terraform is multi-cloud and requires an external state file that the team provisions, secures, and operates.

Is Bicep always better than Terraform for Azure?

Not always. Bicep removes state overhead and provides same-day access to new Azure APIs. But if the organisation uses multiple cloud providers or already operates Terraform at scale, Terraform's unified workflow may have more total value.

Can you use Bicep and Terraform together?

Yes, but you need clear ownership boundaries. A common pattern is Terraform for platform-level subscriptions and policies, Bicep for team-level application infrastructure. Mixing them on the same resources creates conflicting state and operational confusion.

Intermediate

What does ARM-managed state mean in practice?

Azure Resource Manager tracks what each deployment created and manages idempotency. You do not need to store, lock, or back up a state file. Every deployment get a pre-flight what-if comparison against the live state automatically.

Why does Terraform sometimes lag behind new Azure features?

The Terraform AzureRM provider must implement a new resource type or property before you can use it. Bicep compiles directly to ARM JSON and can use any ARM API version immediately when Azure publishes it.

How does Bicep handle existing resources that were created outside of Bicep?

Use the existing keyword. This tells Bicep to read the resource from Azure without creating or modifying it, so you can reference its properties (like subnet ID) in your template without taking ownership.

What is Azure Verified Modules (AVM) and how does it compare to the Terraform Registry?

AVM is Microsoft-maintained reusable Bicep modules for common Azure resources, similar to official Terraform modules. AVM modules follow a consistent interface and are tested by Microsoft. The Terraform Registry is broader with thousands of community and vendor modules spanning all providers.

Scenario-based

Your company is Azure-only today but evaluating AWS for a new product line. Which IaC tool do you recommend?

I would recommend planning for Terraform if AWS adoption is likely within 1-2 years. Migration cost is real but so is the cost of running two incompatible IaC workflows. If AWS is uncertain, Bicep now with a migration path defined is a reasonable middle ground.

A team argues that Terraform is better because it has more community modules. How do you evaluate this?

Module availability is one dimension. I would weigh it against state operational overhead, API currency for new Azure features, team Azure expertise, and governance requirements. A larger module ecosystem does not automatically make a tool better for a specific operating context.

An auditor asks how you ensure IaC compliance when teams use both Bicep and Terraform. What controls do you describe?

I describe Azure Policy for resource-level guardrails that apply regardless of the IaC tool, and pipeline gates that enforce what-if review for Bicep and plan approval for Terraform before any apply reaches production. Tool-agnostic Azure Policy is the safest compliance layer.

Real-world Usage

Many enterprise Azure platform teams operate Terraform for foundational infrastructure (subscriptions, networking hub, DNS, management groups) because it integrates with non-Azure systems in their automation stack. Individual product teams use Bicep for application-level Azure resources because it requires no state setup and new Azure capabilities are available immediately. Both tools coexist when ownership boundaries are clearly defined.

Summary

The Bicep vs Terraform decision is not about which tool is better. It is about which tool fits the cloud scope, state complexity tolerance, team skills, and governance model of your organisation. Bicep wins on simplicity, API currency, and Azure-native integration. Terraform wins on multi-cloud reach, ecosystem breadth, and unified cross-platform workflows. The answer that wins interviews is the one that matches the tool to the operating model, not the one that picks a favourite.