Skip to content

Use Terraform with Azure Developer CLI (azd) for Infrastructure

Context and Problem Statement

The CIMPL platform needs an infrastructure-as-code (IaC) tool and deployment orchestrator for provisioning Azure resources and managing deployment lifecycle. The choice of IaC tooling is foundational — it determines provider ecosystem, state management, CI/CD pipeline design, and the developer experience for azd up deployments. The reference CIMPL implementation (cimpl-azd) already uses Terraform with azd, and alignment with that project reduces onboarding friction.

Decision Drivers

  • Single-command deployment experience (azd up / azd down)
  • Mature provider ecosystem for Azure, Kubernetes, and Helm resources
  • Lifecycle hooks for multi-layer orchestration (pre-provision, post-provision, pre-down)
  • State management flexibility (local for development, remote for CI/CD)
  • Alignment with reference implementation (cimpl-azd) for knowledge transfer
  • Team familiarity and existing tooling investment

Considered Options

  • Terraform with Azure Developer CLI (azd)
  • Bicep with Azure Developer CLI (azd)
  • Pulumi with Azure Developer CLI (azd)
  • Terraform without azd (standalone CLI)

Decision Outcome

Chosen option: "Terraform with Azure Developer CLI (azd)", because it provides the best combination of mature multi-provider support, lifecycle orchestration, and direct alignment with the reference implementation.

Consequences

  • Good, because azd up provides a single-command deployment that orchestrates Terraform init, plan, and apply with lifecycle hooks
  • Good, because Terraform's azurerm, kubernetes, and helm providers allow managing all three deployment layers (infra, platform, software) with one toolchain
  • Good, because lifecycle hooks (pre-provision, post-provision, pre-down) enable multi-layer teardown ordering and validation gates
  • Good, because direct alignment with cimpl-azd reference means ADRs, patterns, and modules can be ported with minimal translation
  • Good, because azd manages environment configuration (.azure/<env>/) and variable injection (main.tfvars.json with ${AZURE_*} substitution)
  • Bad, because Terraform requires explicit state management — local state works for development but remote backend is needed for CI/CD and team collaboration
  • Bad, because azd's Terraform integration is less mature than its Bicep integration (fewer azd templates use Terraform)
  • Bad, because PowerShell is required for lifecycle hook scripts to maintain cross-platform compatibility with azd

Pros and Cons of the Options

Terraform with Azure Developer CLI (azd)

HashiCorp Terraform orchestrated by Microsoft's Azure Developer CLI for environment and lifecycle management.

  • Good, because multi-provider support (azurerm, kubernetes, helm, azapi) covers all deployment layers
  • Good, because HCL is widely known and well-documented
  • Good, because reference implementation uses identical toolchain
  • Good, because azd handles environment isolation and variable injection
  • Neutral, because Terraform state must be managed (local or remote backend)
  • Bad, because azd + Terraform has fewer community templates than azd + Bicep

Bicep with Azure Developer CLI (azd)

Azure-native IaC language with first-class azd support.

  • Good, because first-class azd integration (most azd templates use Bicep)
  • Good, because no state file management — ARM handles state
  • Good, because Azure-native tooling with direct ARM API compilation
  • Bad, because no Kubernetes or Helm provider — cannot manage platform/software layers
  • Bad, because would require a second tool (Helm CLI, kubectl) for Kubernetes workloads
  • Bad, because no alignment with reference implementation

Pulumi with Azure Developer CLI (azd)

General-purpose IaC using programming languages (TypeScript, Python, Go).

  • Good, because real programming language with loops, conditionals, and type safety
  • Good, because multi-provider support similar to Terraform
  • Bad, because no azd integration — would need custom orchestration
  • Bad, because no alignment with reference implementation
  • Bad, because smaller community and fewer Azure-specific examples

Terraform without azd (standalone CLI)

Terraform with custom scripts for environment management and deployment orchestration.

  • Good, because full control over workflow without azd abstractions
  • Good, because no dependency on azd release cadence
  • Bad, because must build environment management, variable injection, and lifecycle orchestration from scratch
  • Bad, because loses azd up / azd down single-command experience
  • Bad, because CI/CD pipeline must handle all orchestration that azd provides for free

More Information