Terraform on Azure is the combination of HashiCorp's multi-cloud IaC tool Terraform with Azure resource management. While Bicep is an Azure-specific DSL, Terraform is multi-cloud (3,000+ Providers) with strong existing investments and an active OSS community. This article walks through Provider selection, State management, Module design, and CI/CD integration end to end.
| Item | Bicep | Terraform |
|---|---|---|
| Developer | Microsoft | HashiCorp |
| Supported clouds | Azure only | Multi-cloud (3,000+ Providers) |
| Language | Bicep DSL | HCL |
| State management | Not required (handled by ARM) | Required (Azure Storage / Terraform Cloud) |
| Latest Azure features | Immediate support | Can lag (workaround via AzAPI) |
| Pricing | Free | OSS free / Cloud is paid |
| Best fit | Azure-only, latest features first | Multi-cloud, existing assets |
The modern rule of thumb: Bicep for greenfield Azure-only projects, Terraform for multi-cloud or existing Terraform projects.
| Item | AzureRM Provider | AzAPI Provider (released 2022) |
|---|---|---|
| Positioning | Standard | Complementary |
| Behavior | Dedicated functions over the Azure REST API | Generic — calls the Azure REST API directly |
| Resource count | 3,000+ dedicated functions | A single azapi_resource covers everything |
| Latest feature support | Can lag by several months | Immediate |
| Use case | Standard pattern | Preview features and newly added resources |
Standard pattern: use AzureRM Provider as the base and reach for AzAPI Provider only for Preview features and newly added resources. The two can coexist inside the same Terraform project.
Terraform State is a JSON file recording the current state of your infrastructure and is the baseline for terraform plan / apply. The default is local; in production it must be stored in a remote Backend.
terraform {
backend "azurerm" {
resource_group_name = "rg-tfstate"
storage_account_name = "stgtfstate001"
container_name = "tfstate"
key = "prod.terraform.tfstate"
use_oidc = true
}
}Terraform Cloud (paid SaaS) is also available as a Backend and offers more advanced State management.
A Terraform Module is a reusable unit of Terraform code.
infra/
├── main.tf # エントリポイント・Provider 設定
├── variables.tf # 入力変数
├── outputs.tf # 出力値
├── modules/
│ ├── network/ # VNet / NSG / Subnet
│ ├── compute/ # VM / App Service / AKS
│ ├── storage/ # Storage Account / Container
│ └── identity/ # Managed Identity / Key Vault
└── environments/
├── dev.tfvars
├── stage.tfvars
└── prod.tfvarsmodule "network" {
source = "./modules/network"
vnet_name = var.vnet_name
address_space = ["10.0.0.0/16"]
location = var.location
resource_group_name = azurerm_resource_group.main.name
}
module "compute" {
source = "./modules/compute"
vm_name = var.vm_name
subnet_id = module.network.app_subnet_id
resource_group_name = azurerm_resource_group.main.name
depends_on = [module.network]
}Azure Verified Modules (AVM, GA in 2024) are a set of Microsoft-quality-assured Terraform Modules and serve as reference implementations aligned with industry best practices.
In the enterprise, customizing on top of AVM is the standard approach. Modularization dramatically improves the maintainability of large-scale IaC.
The two do not compete and can be used together. Typical patterns:
Drift Detection is the operation of detecting differences between Terraform State and the actual state of Azure resources. When resources are modified manually via the Azure Portal or CLI, State drifts and unexpected changes risk being applied during the next terraform apply.
terraform plan -refresh-only: refresh State to match current resourcesterraform apply -refresh-only: apply the diffterraform import: bring new resources into StateEmbedding periodic Drift Detection in your CI/CD pipeline (for example weekly) makes it possible to catch manual changes early. Combining this with Azure Policy Deny Effect to prohibit manual changes outright is the standard enterprise pattern.
terraform fmt -check + terraform validateterraform plan -out=tfplan — predict changesterraform apply tfplanname: Terraform Apply
on:
push:
branches: [main]
jobs:
terraform:
runs-on: ubuntu-latest
permissions:
id-token: write
contents: read
steps:
- uses: actions/checkout@v4
- uses: hashicorp/setup-terraform@v3
- uses: azure/login@v2
with:
client-id: ${{ secrets.AZURE_CLIENT_ID }}
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
- run: terraform init
- run: terraform plan -out=tfplan
- run: terraform apply tfplanUse OIDC / Workload Identity Federation for AzureRM Provider authentication (no secrets needed) and for Backend authentication as well. Auto-posting Plan output as a PR comment on Pull Requests is also a standard implementation.
What is Terraform on Azure?
Terraform on Azure is the combination of HashiCorp's multi-cloud IaC tool Terraform with Azure resource management. Azure resources are defined declaratively in HCL (HashiCorp Configuration Language) via the AzureRM Provider (officially maintained by Microsoft) and applied to Azure with the terraform plan / apply commands. While Bicep is an Azure-specific DSL with immediate support for new features, Terraform is multi-cloud (3,000+ Providers covering AWS / GCP / Azure / Kubernetes / SaaS) with strong existing investments and a vibrant OSS community. Modern selection criteria: Bicep for greenfield Azure-only projects, Terraform for multi-cloud or existing Terraform projects.
What is the difference between AzureRM Provider and AzAPI Provider?
AzureRM Provider: the standard Azure resource management Provider, officially maintained by Microsoft, built on the Azure REST API, with dedicated functions for each resource type (3,000+ resources such as azurerm_storage_account), published on the Terraform Registry. AzAPI Provider: a newer Provider released by Microsoft in 2022 that calls the Azure REST API directly via a generic resource (azapi_resource), enabling immediate use of new Azure features and Preview features that AzureRM has yet to support (AzureRM can lag by several months). Standard pattern: use AzureRM Provider as the base and rely on AzAPI Provider only for Preview features and newly added resources. The two can coexist inside the same Terraform project and be selected per resource type.
How should Terraform State be managed?
Terraform State is a JSON file recording the current state of your infrastructure and is the baseline for terraform plan / apply. The default location is local (terraform.tfstate), but production must use a remote Backend. Azure standard pattern: 1) use an Azure Storage Account Blob Container as the Backend, 2) implement State Lock (preventing concurrent updates) via Blob Lease, 3) encrypt State (Customer-Managed Key), 4) prevent accidental deletion with Versioning + Soft Delete, 5) control access to State with Microsoft Entra ID authentication. Backend config example: terraform { backend 'azurerm' { resource_group_name = '...' storage_account_name = '...' container_name = '...' key = 'prod.terraform.tfstate' } }. Terraform Cloud (paid SaaS) is also available as a Backend and offers more advanced State management.
How should Modules be designed?
A Terraform Module is a reusable unit of Terraform code. Standard directory structure: 1) main.tf (entry point and Provider config), 2) variables.tf (input variables), 3) outputs.tf (output values), 4) modules/ (functional modules: network, compute, storage), 5) environments/ (per-environment tfvars). Publish Modules to the Terraform Registry or internal Git for reuse across projects. Microsoft's official Azure Verified Modules (AVM, GA in 2024) are a set of Microsoft-quality-assured Terraform Modules and serve as reference implementations aligned with industry best practices. In the enterprise it is standard to customize on top of AVM. Modularization dramatically improves maintainability of large-scale IaC and provides the same kind of benefits as Bicep's Module feature.
Can Bicep and Terraform be used together?
Yes — the two do not compete and can be used together. Typical patterns: 1) Bicep for Azure-only resources, Terraform for multi-cloud requirements (e.g. AWS RDS), 2) Bicep for greenfield while keeping existing Terraform assets, 3) Bicep / AzAPI for Microsoft's latest (including Preview) features and Terraform AzureRM for stable features. The two can run sequentially inside the same Azure DevOps / GitHub Actions pipeline. CI/CD pipeline example: Stage 1 (build Hub VNet with Bicep) → Stage 2 (provision AWS resources + AKS with Terraform) → Stage 3 (configure Azure SaaS with Bicep). A realistic strategy is to mix them flexibly based on your team's skill set, existing assets, and requirements.
How does State Drift Detection work?
Drift Detection is the operation of detecting differences between Terraform State and the actual state of Azure resources. When resources are modified manually via the Azure Portal or CLI (changes outside Terraform), State drifts and unexpected changes risk being applied during the next terraform apply. Relevant commands: terraform plan -refresh-only (refresh State to match current resources), terraform apply -refresh-only (apply the diff), and terraform import (bring new resources into State). Embedding periodic Drift Detection into the CI/CD pipeline (for example weekly) makes it possible to catch manual changes early. Combining this with Azure Policy DenyEffect to prohibit manual changes outright is the standard enterprise pattern.
How does it integrate with GitHub Actions / Azure Pipelines?
Standard pattern: 1) Lint (terraform fmt -check + terraform validate), 2) Init (Backend connection), 3) Plan (terraform plan -out=tfplan, predicting changes), 4) Manual Approval (for Production), 5) Apply (terraform apply tfplan). On GitHub Actions, use the hashicorp/setup-terraform Action; on Azure Pipelines, combine the TerraformInstaller Task with the TerraformTaskV4 Task. Use OIDC / Workload Identity Federation for AzureRM Provider authentication (no secrets needed) and for Backend authentication as well. Auto-posting Plan output as a PR comment on Pull Requests is also a standard implementation. The CI/CD patterns covered in the Bicep tutorial article apply to Terraform with very few changes.
Which certifications are related?
AZ-400 (DevOps Engineer Expert) is the flagship certification for this area — Domain 3 covers Terraform alongside Bicep / ARM as IaC. AZ-104 (Administrator) covers IaC fundamentals, and AZ-305 (Solutions Architect Expert) covers IaC strategy selection from an architect's viewpoint (Bicep vs Terraform). Outside Microsoft: HashiCorp Certified: Terraform Associate (vendor-neutral, the standard Terraform certification, renewed annually) is recognized in the job market as proof of Terraform expertise. The combo of AZ-400 + Terraform Associate is a powerful asset for DevOps engineers and is especially valued at multi-cloud companies.
Related Articles and Technical Deep Dives
Azure Bicep チュートリアル|ARM 後継 IaC の基本構文・モジュール化・What-If・CI/CD 統合【2026 年版】
Azure 純正 IaC ツール Bicep の完全チュートリアル。ARM JSON との違い・基本構文 (param/var/resource/module/output)・モジュール化ベストプラクティス・What-If デプロイ・GitHub Actions / Azure Pipelines 統合・ARM からの移行手順・関連認定試験 (AZ-104 / AZ-204 / AZ-400 / AZ-305) を日本語で網羅。
GitHub Actions vs Azure Pipelines 完全比較|CI/CD 選定・Self-hosted Runner・OIDC 認証【2026 年版】
GitHub Actions と Azure Pipelines を完全比較。機能差・Marketplace エコシステム・Self-hosted Runner / Agent・OIDC (Workload Identity Federation) 認証・Matrix Build・Composite Action / Reusable Workflow・DevSecOps 統合・関連認定試験 (AZ-400 / AZ-204) を日本語で網羅。
Azure DevOps エンジニア キャリアロードマップ|AZ-104 → AZ-400 → SC-100 シニア DevOps への道【2026 年版】
Azure DevOps Engineer になるための認定取得ロードマップ完全版。AZ-900 → AZ-104 → AZ-400 の王道ルート、GitHub と Azure DevOps の両方を扱う AZ-400 の構成、Kubernetes 認定 (CKA / CKAD / CKS) との二刀流、IaC (Bicep / Terraform) 戦略、年収レンジまで日本語で網羅。
AZ-400 完全ガイド|Microsoft Azure DevOps Engineer Expert 出題範囲・学習リソース・合格戦略【2026 年版】
Microsoft Certified: DevOps Engineer Expert (AZ-400) の完全ガイド。5 ドメインの出題範囲、Azure DevOps と GitHub の両方を網羅、IaC (Bicep / ARM / Terraform)、CI/CD パイプライン設計、DevSecOps、SRE プラクティス、3-4 ヶ月の合格ロードマップ、AZ-305 / SC-100 との二刀流戦略を日本語で網羅。
The technical content in this article is based on the AzureRM Provider Documentation and the Microsoft Terraform on Azure Documentation. This article is not an official Microsoft Corporation product and has no affiliation or sponsorship relationship with Microsoft. Microsoft and Azure are trademarks of the Microsoft group of companies. Terraform is a trademark of HashiCorp. Information reflects official public materials as of May 24, 2026. Always check the official pages for the latest information.
Practice with certification-focused question sets
Visit the Azure exam prep pageNicheeLab Editorial Team
NicheeLab editorial team focused on data engineering and cloud certification learning. Content is structured around practical study needs and official exam domains.
AZ-900 Azure Fundamentals: Complete Exam Guide (2026)
Pass AZ-900 — cloud concepts, Azure architecture, management...
Azure Certification Roadmap: Which Cert to Take Next (2026)
Choose your Azure certification path — Fundamentals, Associa...
AI-901 Azure AI Fundamentals (Beta): Complete Guide (2026)
Pass AI-901 — Microsoft Foundry, generative AI, responsible ...
Microsoft Entra ID Fundamentals for Azure Certs (2026)
Entra ID basics every cert candidate needs — tenants, identi...
DP-900 Azure Data Fundamentals: Complete Guide (2026)
Pass DP-900 — relational, non-relational, analytics, Power B...