The AzAPI provider, designed to expedite the integration of new Azure services with HashiCorp Terraform, has now released 2.0. This updated version marks a significant step in our goal to provide launch day support for Azure services using Terraform.
What is the AzAPI Provider?
The AzAPI provider functions as a lightweight layer atop the Azure ARM REST APIs. It is a first class provider experience along with the AzureRM provider. Azure resources that might not yet be or may never be supported in AzureRM can be accessed by this provider, including private/public preview services and features.
Key Features of the AzAPI Provider Include:
- Resource-specific versioning, allowing users to switch to a new API version without altering provider versions.
- Special functions like `azapi_update_resource` and `azapi_resource_action`.
- Immediate Day 0 support for new services.
Ready to see the new updates? Let’s take a look!
No More JSON!
All resource properties, outputs, and state representation are now handled with HashiCorp Configuration Language (HCL) instead of JSON. This change allows the use of all native Terraform HCL functionalities. For more info on scenarios on usage, check out our initial announcement.
Clarity with Outputs
Outputs are now customizable through the `response_export_values` property, which can function as either a list or a map.
For instance, to export response values for an Azure container registry:
- If I set the value to a list, i.e. response_export_values = `["properties.loginServer", "properties.policies.quarantinePolicy.status"]` , I would get the following output:
{
properties = {
loginServer = "registry1.azurecr.io"
policies = {
quarantinePolicy = {
status = "disabled"
}
}
}
}
- If I instead set the value to a map using JMESPath querying, i.e. response_export_values = `{"login_server": "properties.loginServer", "quarantine_status": "properties.policies.quarantinePolicy.status"}`, I would get the following output:
{
"login_server" = "registry1.azurecr.io"
"quarantine_status" = "disabled"
}
This feature uses a key-value configuration, making it easier to specify exact output values. For example, you can set `{"login_server": "properties.loginServer", "quarantine_status": "properties.policies.quarantinePolicy.status"}`.
retry Block
User-defined retriable errors via the retry block help the provider digest errors when expected. For example, if a resource may run into a create timeout issue, the following block of code may help:
resource "azapi_resource" "example" {
# usual properties
retry {
interval_seconds = 5
randomization_factor = 0.5 # adds randomization to retry pattern
multiplier = 2 # if try fails, multiplies time between next try by this much
error_message_regex = ["ResourceNotFound"]
}
timeouts {
create = "10m"
}
Preflight Support
Preflight validation, enabled by a feature flag, will identify errors without deploying resources, providing a quicker feedback loop. For example, in a config with several resources, an invalid network addressPrefix definition will be caught quickly:
provider "azapi" {
enable_preflight = true
}
resource "azapi_resource" "vnet" {
type = "Microsoft.Network/virtualNetworks@2024-01-01"
parent_id = azapi_resource.resourceGroup.id
name = "example-vnet"
location = "westus"
body = {
properties = {
addressSpace = {
addressPrefixes = [
"10.0.0.0/160", # preflight will throw an error here
]
}
}
}
}
Resource Replacement Triggers
Customize specific methods of replacing your resource.
- replace_triggers_external_values: Replaces if specified external values change.
- replace_triggers_refs: Triggers a resource replacement based on changes in specified paths.
Resource Discovery
Discover resources under a parent ID such as a subscription, virtual network, or resource group using the new `azapi_resource_list` data source. You can also filter using query parameters as shown below:
data "azapi_client_config" "current" {}
data "azapi_resource_list" "listPolicyDefinitionsBySubscription" {
type = "Microsoft.Authorization/policyDefinitions@2021-06-01"
parent_id = "/subscriptions/${data.azapi_client_config.current.subscription_id}"
query_parameters = {
"$filter" = ["policyType eq 'BuiltIn'"]
}
response_export_values = ["*"]
}
output "o1" {
value = data.azapi_resource_list.listPolicyDefinitionsBySubscription.output
}
AzAPI Provider Functions
AzAPI now supports several Terraform provider functions:
- build_resource_id: Constructs an Azure resource ID.
- parse_resource_id: Breaks down an Azure resource ID into its components.
- subscription_resource_id: Constructs an Azure subscription scope resource ID.
- tenant_resource_id: Builds an Azure tenant scope resource ID.
- management_group_resource_id: Creates an Azure management group scope resource ID.
- resource_group_resource_id: Forms an Azure resource group scope resource ID.
- extension_resource_id: Generates an Azure extension resource ID with additional names.
To check out the references and examples, visit the Terraform registry.
AzAPI VSCode Extension Improvements
The release coincides with updates to the VSCode extension:
- Code Samples: Quickly insert code samples from our auto-gen pipeline:
- Paste as AzAPI: Convert JSON or ARM templates directly into HCL:
Conclusion
AzAPI 2.0 brings numerous enhancements, promising a better Terraform experience on Azure. With these features, we believe that you can use AzAPI as a standalone provider to meet any of your infrastructure needs. Stay tuned for a blogpost coming on suggestions for when to use each provider. Be sure to explore the new features; we're confident you’ll enjoy them!
If you haven’t yet, check out the provider: https://registry.terraform.io/providers/Azure/azapi/latest/docs