Back to all posts

cat posts/bicep-vs-terraform-azure-2026-honest-update.md --category "DevOps & Infrastructure" --views 2,277

Bicep vs Terraform in 2026: Which to Choose for Azure

A 2026 comparison of Bicep and Terraform for Azure — state management, provider coverage, drift detection, module ecosystems, team-scale considerations, and an honest recommendation matrix for different team shapes.

  • --author By Falak Mahmood
  • --date March 5, 2026
  • --read 8 min read
  • --views 2,277 views

Updated 6 September 2026: deployment stacks, AVM's Terraform expansion, the native terraform test framework, azurerm 4.x, and a full decision matrix.

Two years ago the Bicep-vs-Terraform conversation was easier: Terraform won on ecosystem, Bicep on Azure-native ergonomics. In 2026 the picture is more nuanced. Bicep closed most of the tooling gap, Terraform's licensing story is stable, and the OpenTofu fork has given Terraform users more options. This is an honest comparison aimed at teams making the choice for a new Azure workload, or reconsidering an existing one.

Already leaning Bicep? Our follow-up covers the practical move: Migrating from Terraform to Bicep on Azure, including state handling, coexistence patterns and CI/CD changes.

Summary

  • Azure-only, small-to-mid team, no multi-cloud ambition. Bicep is simpler, cheaper to operate, and ergonomically tight with Azure.
  • Multi-cloud or heavy third-party integration. Terraform (or OpenTofu) keeps paying for itself through the ecosystem.
  • Large platform team with existing Terraform investment. The migration cost is rarely worth it.

What Changed Since 2024

Four developments moved the needle, and any comparison that skips them is describing 2023.

  • Deployment stacks went GA. Bicep finally has an answer to "how do I delete everything this template created", historically its weakest point against Terraform's destroy. More below.
  • Azure Verified Modules grew up, in both languages. AVM is often described as a Bicep story. It is not: Microsoft publishes verified modules for Terraform too, which quietly removed one of Bicep's talking points.
  • Terraform shipped a native test framework. Since 1.6, terraform test runs HCL-defined tests without the Go toolchain that Terratest demanded. Testing stopped being an argument for staying away.
  • The azurerm 4.x provider line cleaned house. Resource provider registration became controllable, behavior got more consistent, and some of the naming legacy was retired. The provider-lag complaint is smaller than it was, though not gone.

OpenTofu, meanwhile, settled from fork drama into a boring, stable option under the Linux Foundation, and added client-side state encryption, which Terraform itself still lacks natively. Boring is a compliment in infrastructure tooling.

State Management

Still the single biggest operational difference, so it deserves the most space. Terraform keeps an explicit state file, and everything good and bad about Terraform flows from that decision. The good: plan can diff desired against recorded state without touching the cloud, targeted operations and moved blocks let you refactor safely, and destroy knows exactly what it owns. The bad is operational. On Azure the standard backend is a storage account with blob-lease locking, which means the state store itself becomes a tier-zero asset: state contains secrets in plaintext, so whoever reads the blob reads your connection strings. Busy teams hit lock contention. And when reality and state disagree badly, someone gets to perform state surgery with terraform state rm and mv, a task nobody enjoys and few practice.

Bicep is stateless from the user's perspective: ARM's view of live resources is the source of truth. No backend to provision and secure, no lock contention, no surgery. The historical price was that Bicep had no idea what "everything this deployment created" meant, so cleanup was manual. Deployment stacks change that: a stack groups the resources a deployment created, supports delete-on-unmanage semantics, and can deny writes to managed resources. It is not a full state graph, it is Azure-only, and it is younger than Terraform's equivalents, but the "Bicep cannot destroy" objection is now mostly out of date.

The tradeoff, named: Terraform's state buys you a queryable graph of a large estate at the cost of operating and securing that state. Bicep buys freedom from state operations at the cost of weaker whole-estate introspection. Teams under audit sometimes count the missing state backend as a feature in itself: one less secret store to explain.

Provider and Resource Coverage

Bicep gets day-zero coverage of new Azure services because it compiles to ARM and speaks resource-provider API versions directly. The azurerm provider still lags for some services, by days for mainstream ones and occasionally months for niche ones, though 4.x narrowed the gap. Terraform's escape hatch is the azapi provider, which passes raw ARM payloads through Terraform: it works, and you give up typed schemas and clean plans to get it.

Outside Azure the situation inverts completely. Cloudflare, GitHub, Datadog, Grafana, your SaaS vendors: that is Terraform territory, and Bicep does not pretend otherwise. If your platform definition includes anything beyond the Azure resource manager, Bicep alone cannot express it.

Module Ecosystems

  • Terraform has the larger public registry by an order of magnitude. Quality varies wildly; the surface area is unmatched.
  • Azure Verified Modules is the curated middle path, with Microsoft-maintained modules for common resources, published for both Bicep and Terraform. For Azure-only teams the AVM catalog is often sufficient on its own.

For enterprises, the public registries matter less than they look. Most serious estates converge on a small internal module library either way, and internal module hygiene, versioning, review, ownership, predicts outcomes far better than which registry you started from.

Syntax Matters More Than It Should

Bicep reads cleaner than HCL for Azure resources. It has stronger type inference, user-defined types with compile-time validation, nicer error messages, and an editor experience that feels like writing TypeScript for infrastructure. Terraform's HCL is more mature but shows its age on complex modules: nested dynamic blocks and for-expressions get write-only fast. The same storage account in both:

// Bicep
resource storage 'Microsoft.Storage/storageAccounts@2023-05-01' = {
  name: 'st${uniqueString(resourceGroup().id)}'
  location: location
  sku: { name: 'Standard_LRS' }
  kind: 'StorageV2'
  properties: {
    minimumTlsVersion: 'TLS1_2'
    allowBlobPublicAccess: false
  }
}
# Terraform equivalent
resource "azurerm_storage_account" "this" {
  name                     = "st${random_string.suffix.result}"
  resource_group_name      = azurerm_resource_group.this.name
  location                 = var.location
  account_tier             = "Standard"
  account_replication_type = "LRS"
  min_tls_version          = "TLS1_2"
  allow_nested_items_to_be_public = false
}

Notice the Terraform version needs a separate random_string resource and an explicit resource-group reference for what Bicep expresses inline. Multiply that by three hundred resources and syntax stops being cosmetic: it is review time, onboarding time, and the class of bug a new hire introduces in month one.

Drift Detection

Terraform's plan surfaces drift by diffing state against live, and it sees the whole estate in one pass. Bicep detects drift by running what-if against a deployment. It works, with a caveat worth stating plainly: what-if has a reputation for noise, reporting phantom changes on certain resource types where the API returns properties the template never set. It improved steadily through 2025, and it still occasionally cries wolf. Terraform's drift view is more trustworthy at estate scale; Bicep's failure mode is annoyance rather than a corrupted state file. Neither replaces a scheduled reconciliation job in CI, which mature teams run regardless of tool.

CI/CD and Pipelines

Both integrate cleanly with Azure DevOps and GitHub Actions, and both now authenticate the right way: OIDC workload-identity federation to Entra, no long-lived service-principal secrets in the pipeline. Terraform's pattern of plan as a reviewable artifact, then human approval, then apply of that exact plan, is slightly richer than Bicep's what-if output in a PR comment followed by deploy, because the applied change is byte-identical to the reviewed one. Bicep's pipeline has fewer moving parts: no state backend to reach, no lock to hold, no plan artifact to store.

The cost difference is real but small. Terraform needs a state backend (a storage account is effectively free; HCP Terraform is free to 500 resources and a line item after that; Spacelift and friends likewise). Bicep needs nothing. The bigger cost is attention: one more stateful system in the deployment path is one more thing that pages someone.

Testing

  • Terraform. The native terraform test framework (1.6+) covers module contract tests in plain HCL. Terratest remains the integration-test workhorse, tflint catches provider-specific mistakes, and Trivy absorbed tfsec for static security scanning. Mature, if assembled from parts.
  • Bicep. The linter runs at build, what-if serves as deployment preview, and PSRule for Azure checks templates against the Well-Architected baseline before anything deploys. Thinner than Terraform's stack, and for most Azure estates it covers the failures that actually happen.

Migration Cost

Migrating from Terraform to Bicep (or the reverse) is a multi-month project for anything non-trivial: the templates are the easy part, the cutover of live resources and pipeline habits is not. Unless there is a pressing reason, a team that cannot support state operations, an acquisition forcing standardization, a genuine multi-cloud pivot, the migration is rarely worth it. The better move for most teams is to standardize on one tool for new projects and let old projects attrit. If you do make the move, we wrote up the mechanics: Terraform to Bicep migration on Azure, including coexistence patterns for the years both will run side by side.

The Recommendation Matrix

Your situation Pick Why
Greenfield, Azure-only, small platform teamBicepLeast operational surface; AVM covers the common resources
Greenfield, multi-cloud intent or heavy SaaS providersTerraform / OpenTofuThe ecosystem is the product; Bicep cannot reach past ARM
Brownfield with significant existing TerraformStay on TerraformMigration cost almost never pays back
Brownfield with ARM-template inheritanceBicepDecompile path from ARM JSON is a weekend, not a quarter
Regulated estate, minimal external dependenciesBicepNo state store holding secrets, one less system in audit scope
Org-wide platform team standardizing across cloudsTerraform + AVM's Terraform modulesOne language everywhere, Microsoft-curated modules on the Azure side

The tool matters less than the discipline. A well-run Bicep estate outperforms a neglected Terraform one; the reverse is also true. Pick the one the team will actually keep tidy. For what it is worth, our own default is Bicep for Azure-only builds and Terraform where an estate genuinely spans providers, the same split we apply in migration and platform work.

subscribe # the AI news that matters, minus the noise

Book a Call

Tags

Related posts