Why azapi?

The azapi provider is a thin Terraform provider maintained by Microsoft that calls the Azure Resource Manager REST API directly — giving it the same day-0 coverage as ARM Templates and Bicep.

The azurerm provider (by HashiCorp) wraps the Azure API behind its own HCL-friendly field names and abstractions. That abstraction is convenient but introduces a lag: a new Azure feature has to be implemented in the provider before you can use it in Terraform. azapi skips that layer entirely.

azurerm vs azapi

  azurerm azapi
Maintained by HashiCorp Microsoft
Day-0 coverage No — provider lag possible Yes — same API as ARM/Bicep
Field names Custom HCL-friendly names Mirror ARM/Bicep API names
Abstraction level High — opinionated resource blocks Low — body is raw JSON/YAML
Maturity Very mature Generally Available (GA)
Best for Stable, well-supported resources New/preview services, Azure-native teams

How It Works

azapi has three core resource types:

  • azapi_resource — create, update, and delete any Azure resource via the ARM REST API.
  • azapi_update_resource — patch properties of an existing resource (even one managed by azurerm).
  • azapi_resource_action — invoke arbitrary ARM actions (e.g. listKeys, restart).

Because the body is passed as structured data (HCL object → JSON), it mirrors Bicep’s properties block almost exactly, making Bicep docs directly applicable.

Quick Example

resource "azapi_resource" "storage" {
  type      = "Microsoft.Storage/storageAccounts@2023-01-01"
  name      = var.storage_account_name
  location  = var.location
  parent_id = var.resource_group_id

  body = {
    sku  = { name = "Standard_LRS" }
    kind = "StorageV2"
    properties = {
      minimumTlsVersion        = "TLS1_2"
      allowBlobPublicAccess    = false
      supportsHttpsTrafficOnly = true
    }
  }
}

Notice how the field names (minimumTlsVersion, allowBlobPublicAccess, supportsHttpsTrafficOnly) match the ARM/Bicep API exactly — the same names you’d use in a .bicep file.

Using azapi Alongside azurerm

The recommended pattern:

  • Use azurerm for stable, well-supported resources where its abstractions save time.
  • Use azapi for new/preview features not yet in azurerm, or when you need exact API control.
  • Use azapi_update_resource to set properties on an azurerm-managed resource that azurerm doesn’t expose yet.

Patching an azurerm Resource

# Core resource via azurerm
resource "azurerm_storage_account" "main" {
  name                     = var.storage_account_name
  resource_group_name      = var.resource_group_name
  location                 = var.location
  account_tier             = "Standard"
  account_replication_type = "LRS"
}

# Patch a property azurerm doesn't expose yet
resource "azapi_update_resource" "dns_endpoint_type" {
  type        = "Microsoft.Storage/storageAccounts@2023-01-01"
  resource_id = azurerm_storage_account.main.id

  body = {
    properties = {
      dnsEndpointType = "AzureDnsZone"
    }
  }
}

Bicep Alignment

Bicep azapi body
sku: { name: 'Standard_LRS' } sku = { name = "Standard_LRS" }
properties: { minimumTlsVersion: 'TLS1_2' } properties = { minimumTlsVersion = "TLS1_2" }
kind: 'StorageV2' kind = "StorageV2"

The main difference is syntax (Bicep’s : vs HCL’s =) — the structure and names are identical.

Cons

  • Verbosity for common resources — azurerm provides much shorter, more readable blocks for well-supported resources.
  • No provider-level validations — azurerm catches many mistakes at plan time; azapi passes the body straight to ARM, so errors surface at apply time.
  • Less community content — fewer examples, blog posts, and Stack Overflow answers compared to azurerm.

azapi Provider Docs azapi GitHub Azure/azapi — Microsoft Learn


🧪 Lab — Bicep to azapi

Translate this Bicep block into the azapi body below — same field names, HCL syntax (= instead of :, double-quoted strings):

sku: { name: 'Standard_GRS' }
kind: 'StorageV2'
properties: {
  minimumTlsVersion: 'TLS1_2'
  allowBlobPublicAccess: false
}
📝 Quiz — azapi Provider

Next Up

Module 6 puts ARM, Bicep, and both Terraform providers side by side.