Skip to main content
Cloud DevOps Solutions
Get a quote Talk to an engineer

Terraform for Azure

We implement production-grade Terraform for Azure, modular resource design, Azure Storage remote state, Workload Identity Federation for CI/CD authentication, and Azure Policy deployment, bringing your entire Azure estate under version-controlled IaC.

Problems we solve

  • Azure resources provisioned via Portal, no IaC, no audit trail, no reproducibility
  • AzureRM provider without version pinning, plan output changes after every terraform init
  • State stored in Azure Storage without locking, concurrent applies corrupt state
  • No tagging strategy, Cost Management shows undifferentiated spend across subscriptions
  • Terraform code mixed with Bicep templates, two IaC languages causing confusion

What's included

Terraform project structure aligned with Azure Management Group and Subscription hierarchy
Azure Storage Account backend with blob leasing for state locking
AzureRM provider version pinning and dependency lock file committed to Git
Module library: Resource Groups, Virtual Networks, AKS, Azure SQL, Key Vault, Storage
OIDC-based Azure authentication for CI/CD (Workload Identity Federation, no client secrets)
Azure Policy equivalents via azurerm_policy_definition and assignment resources
Bicep-to-Terraform migration plan (if applicable)
Atlantis or GitHub Actions pipeline for PR-based plan/apply

Our approach

  1. 01

    Azure estate review

    We review your Management Group structure, subscriptions, existing Terraform code (if any), and resources currently managed via Portal or Bicep.

  2. 02

    Module and workspace design

    We design the module hierarchy: platform modules (networking, identity) separate from workload modules (AKS, databases). Environment separation via separate state files per subscription/environment pair.

  3. 03

    State backend setup

    A storage account and container are provisioned for state (bootstrapped via a minimal shell script or ARM template). Soft-delete is enabled on the storage account for state recovery.

  4. 04

    CI/CD integration

    GitHub Actions or Atlantis runs terraform plan on PRs using Workload Identity Federation, no client secrets or service principal keys stored in CI. terraform apply runs post-merge with environment gates for production.

  5. 05

    Policy and governance

    Azure Policy initiatives for required tags and allowed regions are deployed via Terraform. tflint with the azurerm ruleset enforces naming conventions locally.

Tech stack

TerraformAzureRM ProviderAzure Storage (state)AtlantisGitHub ActionsWorkload Identity FederationAzure PolicytflintcheckovTerragrunt (optional)

Results

We publish results only when a client has approved them. See how we publish case studies and a sample report.

FAQ

Should I use Terraform or Bicep for Azure?
Terraform if you want multi-cloud portability and a consistent toolchain across AWS and Azure. Bicep if you want first-party Azure support with no abstraction layer. Note that Terraform is source-available under the BSL; OpenTofu is the open-source fork, and the azurerm provider can be used with either. For multi-cloud teams, Terraform or OpenTofu is a common choice.
What is Workload Identity Federation for Azure?
Workload Identity Federation lets CI/CD pipelines (GitHub Actions, GitLab CI) authenticate to Azure via OIDC tokens without storing service principal client secrets. GitHub actions exchange a JWT for a short-lived Azure access token. This is the equivalent of OIDC on AWS and is strongly preferred over client secrets.
How do I handle multiple Azure subscriptions in Terraform?
Use provider aliases: one azurerm provider block per subscription, referenced by alias in resource blocks. State is split per subscription. We use a Management Group-aligned directory structure: one root module per environment tier.
Can Terraform manage Azure Policy?
Yes. azurerm_policy_definition, azurerm_policy_set_definition, and the scope-specific policy assignment resources (for example azurerm_subscription_policy_assignment) manage policy lifecycle. This gives you version-controlled, reviewable policy configuration rather than Portal-only changes.
How do I import existing Azure resources?
Use terraform import for targeted resources or the import block (Terraform 1.5+). We also use aztfexport (Microsoft open-source tool) to generate Terraform configuration from existing resource groups, then refactor the output into clean modules.

Ready to get started?

Book a free technical consultation. No commitment, just an honest conversation about your goals.

Written by Saddique Khan, AWS & Azure Certified · Last updated October 2025