The AzureRM provider in Terraform is familiar to everyone working with Azure infrastructure as code. However, the AzureRM provider doesn't always support the latest releases and changes to services, proving hard for any engineer to include an as-code solution for everything.
As such, Microsoft released the AzAPI provider to give users day-zero support on features/changes. This was a welcome addition, but how many of you know this exists, how it differentiates from the AzureRM provider, and how to use it in conjunction with the AzureRM provider.
A little more about AzAPI
AzAPI was built to support missing features or configurations that have yet or will never be supported in the AzureRM provider. It utilises the JSON config to specify configurations in a resource block.
There are three resource types:
azapi_resource - used for complete resource management
azapi_resource_action - used for specific actions on a resource. For example, start/stop a virtual machine
azapi_update_resource - used to manage configurations where AzureRM also manages partially.
Using AzAPI
Provider
You will need to add the azapi provider. It will look like the below (check if there are any newer versions of the provider):
terraform {
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "3.27.0"
}
azapi = {
source = "Azure/azapi"
version = "1.0.0"
}
}
}
provider "azurerm" {}
provider "azapi" {}
Find the Type
Within any of the above resource types, you will need to set the value of type in the resource block.
To find the type, you can either use an existing resource where you can open the JSON view and take the type:
Alternatively, you can locate the resource type by using Azure CLI:
Login to Azure CLI
Run the following command to list providers (take note of the provider you require):
az provider list --query "[].{Provider:namespace, Status:registrationState}" --out table
Run the following command to list resources within the provider (replace Microsoft.KeyVault with the provider you found above):
az provider show --namespace Microsoft.KeyVault --query "resourceTypes[*].resourceType" --out table
Once you have found the provider and resource, you must locate an API version. To do this, run the following command, replacing the provider and resource with what you require:
az provider show --namespace Microsoft.KeyVault --query "resourceTypes[?resourceType=='vaults'].apiVersions | [0]" --out table
Try an API version (recommend the latest non-preview) or if you know the specific version, use that instead.
Now you can bring it together to set your type in the resource block:
resource "azapi_update_resource" "azure_key_vault" {
type = "Microsoft.KeyVault/vaults@2016-10-01"
Resource ID
You will need to specify a resource ID using either an existing resource in code or a data source. The ID would look something like this:
resource_id = azurerm_key_vault.mykeyvault.id
Add JSON
Use the body within the resource block and set the body to jsonencode. Then add the properties block where you can add your json config. Remember, it must be formatted correctly, or it will cause errors on deployment.
body = jsonencode({
"properties" = {
"enabledForDeployment": false,
"softDeleteRetentionInDays": 90
}
})
Conclusion
The result should look something like this:
terraform {
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "3.27.0"
}
azapi = {
source = "Azure/azapi"
version = "1.0.0"
}
}
}
provider "azurerm" {}
provider "azapi" {}
resource "azapi_update_resource" "azure_key_vault" {
type = "Microsoft.KeyVault/vaults@2016-10-01"
resource_id = azurerm_key_vault.mykeyvault.id
body = jsonencode({
"properties" = {
"enabledForDeployment": false,
"softDeleteRetentionInDays": 90
}
})
Remember to select the right resource from the AzAPI provider to complete actions correctly.