The AzAPI Terraform provider for Microsoft Azure has introduced a feature known as dynamic properties. This feature simplifies resource definitions by enabling the use of HCL (HashiCorp Configuration Language) blocks instead of JSON blocks that would previously require the use of JSON encoding (via jsonencode
) and decoding (via jsondecode
). This is a great improvement to the use of the AzAPI provider, and provides a more native Terraform coding solution with the provider. In this article, we’ll look at what the AzAPI dynamic properties feature is, and how to go about using it in your Terraform projects to manage Microsoft Azure resources.
What are AzAPI Dynamic Properties?
Dynamic properties in the AzAPI Terraform provider allow you to define Microsoft Azure resources using HCL blocks, eliminating the need for the use of JSON encoding with the provider. This enhances the authoring experience by making Terraform configurations more intuitive and aligned with standard Terraform practices. With dynamic properties, you can achieve clearer Terraform plan outputs, simplify resource definitions, and utilize native Terraform HCL functionality previously more cumbersome with JSON-encoded blocks.
What are the Benefits of Dynamic Properties over JSON?
With the AzAPI Terraform provider adding the dynamic properties feature, it bring with a few benefits when working with the provider:
- Improved Coding Experience – Dynamic properties enhance the readability and maintainability of Terraform configurations built with the AzAPI provider by utilizing a more standard HCL syntax when defining resource property configurations.
- Clearer Plan Outputs – With dynamic properties the Terraform plan outputs become more transparent and descriptive; increasing the readability and understanding of the planned configuration changes.
- Simplified Resource Definitions – By eliminating the need for JSON to be embedded and encoded within the Terraform HCL code, dynamic properties streamlines Azure resource definitions, making it easier to manage the Terraform project code.
- Utilization of HCL Functionality – Dynamic properties enable the use of native HCL functionality such as
for_each
looks and lifecycle management, enhancing the flexibility of resource management.
How to Upgrade Your AzAPI Terraform Code to Dynamic Properties
The transition of your existing AzAPI Terraform provider code to using dynamic properties does require some changes to your Terraform project. Adopting this feature does require you to remove the use of the jsonencode
and jsondecode
functions within AzAPI resource definitions from your code. Moving to this feature needs to be a purposeful change, but it’s not really a complicated one.
To upgrade your AzAPI provider code to use the dynamic properties feature, you will need to take the following steps within your Terraform project:
-
Upgrade to the latest version of the AzAPI provider. You can do this by running the following command to tell Terraform to upgrade the project to the latest version:
terraform init -upgrade
-
If you are using any data sources in your Terraform code that use the AzAPI provider, you’ll need to update the
provider
block in your project to set theenable_hcl_output_for_data_source
setting for the provider totrue
. You can do this like the following example:provider "azapi" { enable_hcl_output_for_data_source = true }
The
enable_hcl_output_for_data_source
is set tofalse
by the AzAPI provider so it doesn’t cause breaking changes for existing Terraform projects. Set tofalse
will store the body of the resources as a JSON string. Setting totrue
will configure the provider to instead store each property as its corresponding HCL type (object or string). -
Go through your Terraform project and remove the use of
jsonencode
function with any code referencing the AzAPI provider.This will require you to modify AzAPI code in your project using the
jsonencode
function to be more like the following code that uses Dynamic Properties:resource "azapi_resource" "automationAccount" { type = "Microsoft.Automation/automationAccounts@2023-11-01" parent_id = azapi_resource.resourceGroup.id name = "example-automation-account" location = "westeurope" body = { properties = { encryption = { keySource = "Microsoft.Automation" } publicNetworkAccess = true sku = { name = "Basic" } } } response_export_values = ["properties"] }
After the change, you’re Terraform project will be required to no longer contain the
jsonencode
style of defining the AzAPI providers resource properties:resource "azapi_resource" "automationAccount" { type = "Microsoft.Automation/automationAccounts@2023-11-01" parent_id = azapi_resource.resourceGroup.id name = "example-automation-account" location = "westeurope" body = jsonencode({ properties = { encryption = { keySource = "Microsoft.Automation" } publicNetworkAccess = true sku = { name = "Basic" } } }) }
-
You’ll also need to update any AzAPI provider code using the
jsondecode
function to read resource and data source properties to instead use dynamic properties as well. To do this, you’ll need to update those blocks to read the resource properties using the native HCL method instead. Here’s an example that shows the definition of a Terraform output value to demonstrate the difference for what change is needed:# New: using Dynamic Properties output "o1" { value = azapi_resource.automationAccount.output.properties.automationHybridServiceUrl } # Old: using jsondecode to read JSON properties output "o1" { value = jsondecode(azapi_resource.automationAccount.output).properties.automationHybridServiceUrl }
AzAPI Dynamic Properties Examples
To give you a clearer picture of how the AzAPI Dynamic Properties feature is used to declare the configuration for Microsoft Azure resources, here’s a few examples for different usage scenarios.
AzAPI Dynamic Properties Resource Creation Example
resource "azapi_resource" "virtualNetwork" {
type = "Microsoft.Network/virtualNetworks@2021-02-01"
parent_id = azapi_resource.resourceGroup.id
name = "example-vnet"
location = "westeurope"
body = {
properties = {
addressSpace = {
addressPrefixes = [
"10.0.0.0/16",
]
}
subnets = [
for subnet in local.subnets : {
name = subnet.name
properties = {
addressPrefix = subnet.addressPrefix
}
}
]
}
}
}
AzAPI Dynamic Properties Resource Update Example
resource "azapi_update_resource" "automationAccount" {
type = "Microsoft.Automation/automationAccounts@2023-11-01"
resource_id = azapi_resource.automationAccount.id
body = {
properties = {
publicNetworkAccess = true
}
}
}
AzAPI Dynamic Properties Lifecycle Management Example
resource "azapi_resource" "automationAccount" {
type = "Microsoft.Automation/automationAccounts@2023-11-01"
parent_id = azapi_resource.resourceGroup.id
name = "example-account"
location = azapi_resource.resourceGroup.location
body = {
properties = {
encryption = {
keySource = "Microsoft.Automation"
}
publicNetworkAccess = true
sku = {
name = "Free" // Config: "Free"; Remote: "Basic"
}
}
}
lifecycle {
ignore_changes = [
body.properties.sku.name
]
}
}
Conclusion
Dynamic properties in the AzAPI Terraform provider offers a significant enhancement to the Microsoft Azure resource provisioning workflow within Terraform projects. By embracing HCL blocks, DevOps Engineers and SREs can enjoy a more intuitive and efficient authoring experience while maintaining the reliability and consistency promised by the AzAPI provider. Upgrade to the latest version, explore dynamic properties, and unlock new possibilities in managing Microsoft Azure resources with the provider!
Original Article Source: Using AzAPI Terraform Provider Dynamic Properties Feature instead of jsonencode by Chris Pietschmann (If you’re reading this somewhere other than Build5Nines.com, it was republished without permission.)