3.1.5.1. IaC Foundations: Bicep, Terraform, and DSC
3.1.5.1. IaC Foundations: Bicep, Terraform, and DSC
Infrastructure as Code (IaC) manages computing infrastructure through declarative configuration files rather than manual processes. The core principle: infrastructure definitions are versioned, reviewed, and deployed through the same pipeline as application code. Bicep — Azure's domain-specific IaC language — compiles to ARM templates with dramatically better syntax, no state file management, and same-day Azure API support. Terraform offers multi-cloud portability with its HCL syntax and state-based resource tracking, but requires remote backend configuration to avoid state loss on ephemeral CI agents. Desired State Configuration (DSC) through Azure Automanage Machine Configuration continuously checks VM configuration against declared policy, reporting or remediating drift automatically. The choice depends on scope: Bicep for Azure-only teams with ARM experience, Terraform for multi-cloud or teams already invested in HCL.
Terraform state management is the critical operational concern for teams adopting Terraform. Local state on ephemeral CI agents means state loss — the next pipeline run recreates all resources because it doesn't know what already exists. Remote backend configuration with Azure Blob Storage and state locking prevents this: backend "azurerm" with a storage account, container, and state key. State locking prevents concurrent modifications from corrupting state.
Bicep's advantage for Azure-only teams is the absence of state management. Azure Resource Manager IS the state — Bicep compiles to ARM templates that Azure evaluates against its existing resource inventory. No separate state file to protect, no state corruption risk, no state import/migration challenges.
Terraform modules encapsulate reusable patterns — an AKS module that standardizes networking, monitoring, and RBAC across teams. Module versioning through Git tags (not branch references) ensures consumers control when they adopt changes. The Terraform Registry provides community modules, but enterprise teams should maintain internal registries with approved, security-reviewed modules.
DSC (Desired State Configuration) through Azure Machine Configuration bridges the gap between infrastructure provisioning (Terraform/Bicep) and ongoing configuration management. Terraform creates the VM; DSC ensures the VM maintains its desired configuration (TLS version, installed software, registry keys) continuously, reporting or remediating drift every 15 minutes.
State management patterns for Terraform at scale include state file partitioning: one state file per environment per component. A monolithic state file for an entire subscription creates contention (only one pipeline can modify at a time) and blast radius (a mistake in networking affects compute resources). Partition by: terraform/networking/prod.tfstate, terraform/aks/prod.tfstate, terraform/databases/prod.tfstate.
Import workflows handle "brownfield" environments where resources already exist in Azure but aren't yet managed by IaC. terraform import adds existing resources to state, and az deployment group export generates ARM templates from existing resources. The systematic approach: import resources → generate matching IaC → verify with plan → establish IaC as source of truth.
State management is Terraform's most critical concern. State files contain sensitive information — resource IDs, connection strings, and sometimes passwords. Azure Blob Storage backend with encryption at rest, state locking via Azure Storage lease, and access restricted to pipeline service principals prevents both data exposure and concurrent modification. Always use terraform plan in CI and terraform apply only after human review of the plan output. State drift detection (terraform plan showing unexpected changes) reveals manual portal modifications that should be codified. Import existing resources with terraform import rather than recreating them, preserving operational continuity.
Bicep modules encapsulate reusable resource patterns — a standardized AKS module with organization-approved networking, monitoring, and RBAC configuration. Teams consume modules by reference (module aks 'br:myacr.azurecr.io/bicep/aks:v2.1') without understanding the underlying ARM template complexity. Module registries in ACR enable versioned, pull-based consumption with the same dependency management patterns as container images and NuGet packages.
Terraform workspaces separate state files for different environments (dev, staging, production) within the same configuration directory. Each workspace maintains independent state, enabling environment-specific resource counts and configurations while sharing the same module definitions. Combined with remote backend in Azure Blob Storage, workspaces provide isolated state management without duplicating configuration files across environment-specific directories.