You all know that Terraform is one of the leading infrastructure-as-code (IaC) tools, allows you to manage and implement cloud resources across various platforms, including Azure. While Terraform’s native Azure Provider (azurerm) is great for most all use cases, the AzAPI Provider introduces a more granular and direct way to manage Azure resources, especially when dealing with the latest Azure features or Azure resources not yet supported by HashiCorp for the azurerm provider.
In these scenarios, I would include PowerShell or AzCLI scripts in Terraform using the “null_resource” with the “local-exec” provisioner. I recall when I needed to automate the deployment of Azure Virtual Desktop in the Azure Cloud, some modules weren’t available in Terraform at the time. To solve this, I wrote a PowerShell script and integrated it with other Azure resources through Terraform. An example of this is shown below.
resource "null_resource" "deploy_avd_hostpool" {
provisioner "local-exec" {
command = "pwsh ./create-avd-hostpool.ps1 -ResourceGroup 'myResourceGroup' -HostPoolName 'myHostPool' -Location 'East US'"
}
}
In this setup, create-avd-hostpool.ps1 is a PowerShell script that contains the logic to deploy the Azure Virtual Desktop Host Pool using New-AzWvdHostPool or other related PowerShell cmdlets. This allows Terraform to execute the PowerShell script during its provisioning process, seamlessly integrating infrastructure deployment with script-based configuration.
“But there was limitation/problem in this method that the resource implemented via PowerShell Scripts was not being added in Terraform state file.”
We have got a solution to this problem which is AzAPI Provider
What is the AzAPI Provider?
The AzAPI Provider is an extension of Terraform for Azure that gives you more direct access to Azure’s Resource Manager API (ARM). This means that if a particular Azure resource or feature isn’t available in the regular azurerm provider, you can use the AzAPI Provider to interact directly with Azure’s REST APIs.
Key Features of AzAPI Provider:
- Early Access: If Azure releases a new feature or resource, it might take some time for the
azurermprovider to support it. However, with the AzAPI provider, you can access these features immediately. - Native API Support: The AzAPI provider gives you near-1:1 mapping to the ARM API, making it perfect for users who want fine control over Azure resources.
- Supports All Azure Resources: Since it directly interacts with Azure’s REST API, you can manage any resource available in ARM.
Why Use AzAPI Provider Over azurerm?
While azurerm is still the go-to provider for most Azure resources, there are scenarios where AzAPI becomes indispensable:
- New Resource Types: Azure often releases new resource types, features, or versions that may not be immediately supported by
azurerm. With AzAPI, you can manage those resources without waiting for updates. - Deep Customization: AzAPI provides more control for advanced users who need to tweak resource properties that may not be exposed in
azurerm. - Avoiding Delays: When you need to use a cutting-edge Azure feature, AzAPI provides a quicker pathway to implement it, while
azurermcatches up. - Full Terraform state file fidelity: Properties and values are saved to state file
How Does the AzAPI Provider Work?
The AzAPI provider works by directly calling Azure’s REST APIs to create, modify, or delete resources. It uses Azure’s native ARM templates under the hood, giving you a familiar experience if you’ve worked with ARM templates before.
Main Components:
- Resource Management: Like
azurerm, AzAPI uses familiar Terraform constructs such asresource,data,provider, etc., but offers deeper control over resource definitions. - Schema and Properties: When defining resources with AzAPI, you will need to provide more detailed properties, often directly corresponding to the JSON schema of the Azure resource.
Getting Started with AzAPI Provider
Let’s dive into a few examples of how to use the AzAPI provider in a Terraform configuration.
1. Setting Up the AzAPI Provider
First, make sure you have Terraform installed, and create a new Terraform project. Then, define the AzAPI provider in your main.tf file:
provider "azapi" {
subscription_id = "<your-subscription-id>"
}
provider "azurerm" {
features {}
}
- The
azapiprovider block configures the AzAPI provider. - The
azurermprovider block is optional but can be used alongside the AzAPI provider for managing resources that don’t require fine-grained control.
2. Example: Creating an Azure Storage Account with AzAPI
Here’s a basic example of using the AzAPI provider to create a storage account, which is one of the most common resources:
resource "azapi_resource" "storage_account" {
type = "Microsoft.Storage/storageAccounts@2021-09-01"
name = "examplestorageaccount"
location = "East US"
parent_id = azurerm_resource_group.example.id
body = jsonencode({
sku = {
name = "Standard_LRS"
}
kind = "StorageV2"
properties = {}
})
}
resource "azurerm_resource_group" "example" {
name = "example-resources"
location = "East US"
}
Breakdown:
azapi_resource: This is the main resource type provided by the AzAPI provider, which maps directly to an Azure resource.type: Specifies the ARM resource type, including the API version (Microsoft.Storage/storageAccounts@2021-09-01).body: Instead of using specific Terraform attributes, you define the properties of the resource in a JSON object.
3. Example: Using AzAPI for Preview Features
Suppose Azure recently released a preview feature for Virtual Machines that is not supported by azurerm. Here’s how you might define it using AzAPI:
resource "azapi_resource" "virtual_machine_preview" {
type = "Microsoft.Compute/virtualMachines@2021-03-01"
name = "my-preview-vm"
location = "East US"
parent_id = azurerm_resource_group.example.id
body = jsonencode({
properties = {
hardwareProfile = {
vmSize = "Standard_DS1_v2"
}
storageProfile = {
imageReference = {
publisher = "Canonical"
offer = "UbuntuServer"
sku = "18.04-LTS"
version = "latest"
}
}
osProfile = {
computerName = "myvm"
adminUsername = "azureuser"
linuxConfiguration = {
disablePasswordAuthentication = true
}
}
networkProfile = {
networkInterfaces = [{
id = azurerm_network_interface.example.id
}]
}
}
})
}
resource "azurerm_network_interface" "example" {
name = "example-nic"
location = azurerm_resource_group.example.location
resource_group_name = azurerm_resource_group.example.name
ip_configuration {
name = "internal"
subnet_id = azurerm_subnet.example.id
private_ip_address_allocation = "Dynamic"
}
}
In this example, we’re using a newer version of the API for Virtual Machines (VMs), and defining custom configurations for networking, OS, and storage.
4. Combining AzAPI with azurerm
You can use both providers in tandem when you need to use azurerm for certain resources and AzAPI for others. For instance, create a resource group with azurerm, and use AzAPI to create the resources inside it.
The AzAPI Provider is a powerful addition to Terraform’s Azure ecosystem, providing early access to new Azure features and more granular control over Azure resources. While it requires a more hands-on approach, it’s invaluable for those who need to manage cutting-edge features or resources that are not yet fully supported by Terraform’s azurerm provider.
By combining the power of AzAPI and azurerm, you can build robust, scalable, and flexible cloud infrastructure that keeps up with Azure’s evolving landscape.
AzAPI2AzureRM migration tool
The AzureRM provider offers the most seamless experience for managing Azure resources with Terraform. Therefore, the recommended approach for using the AzAPI and AzureRM providers is as follows:
- Use the AzAPI provider while the service or feature is in preview.
- Once the service is officially released, switch to the AzureRM provider.
The AzAPI2AzureRM tool is designed to simplify the migration from the AzAPI provider to the AzureRM provider.
AzAPI2AzureRM is an open-source tool that automates the conversion of AzAPI resources to AzureRM resources.
AzAPI2AzureRM has two modes: plan and migrate:
- Plan: Shows the AzAPI resources that can be migrated.
- Migrate: Converts AzAPI resources to AzureRM resources in both the HCL files and the state.
AzAPI2AzureRM ensures that after migration, your Terraform configuration and state match your actual resources. You can confirm this by running terraform plan after the migration to verify that nothing has changed.
For more latest information visit this Microsoft and HashiCorp documentation:
https://learn.microsoft.com/en-us/azure/developer/terraform/overview-azapi-provider
https://registry.terraform.io/providers/Azure/azapi/latest/docs