ADR-002: Infrastructure as Code Tool¶
Context and Problem Statement¶
All Azure infrastructure for the portfolio (Container Apps, Container Registry, Key Vault, DNS zone, Static Web App) needed to be defined as code to enable repeatable, auditable deployments through CI/CD. A choice was required between the available IaC tools for Azure.
Considered Options¶
-
Bicep — Microsoft's domain-specific language for deploying Azure resources. Compiles directly to ARM templates. First-class Azure support, no external state management, and native IDE tooling in VS Code. Azure-only.
-
Terraform — a cloud-agnostic IaC tool with a large provider ecosystem. Supports Azure via the
azurermprovider. Requires a remote state backend (e.g. Azure Storage) and a state lock mechanism. Better suited for multi-cloud or cross-provider infrastructure. -
ARM Templates — the underlying JSON format that Bicep compiles to. Verbose, difficult to maintain directly, superseded by Bicep.
Decision Outcome¶
Chosen option: "Bicep". All infrastructure in this project runs exclusively on Azure. Bicep has first-class support for every Azure resource used (Container Apps, ACR, Key Vault, DNS, Static Web Apps) and does not require managing a state file or a storage account for locking. The Bicep VS Code extension provides inline validation and completion. Since there is no cross-cloud requirement, the portability advantage of Terraform does not apply here.
Consequences¶
- Good, because there is no state file to manage, no remote backend to provision, and no lock contention between concurrent pipeline runs.
- Good, because Bicep receives Azure feature support at the same time as ARM, ahead of the Terraform
azurermprovider in some cases. - Bad, because the choice is Azure-specific — moving workloads to another cloud provider would require rewriting all IaC in a different tool.
- Bad, because the Bicep module ecosystem is smaller than Terraform's registry of community modules.
Page history
| Field | Value |
|---|---|
| Last updated | — |