Using Terraform#
PSRule for Azure supports analyzing Azure resources defined in Terraform configurations by expanding Terraform plan JSON files.
This enables pre-flight validation of Terraform-managed Azure resources against Azure Well-Architected Framework (WAF) rules.
Experimental - Learn more
Terraform plan expansion is a work in progress, and not ready for production use. We are actively working on improving this experience, and would love to hear your feedback.
As always if you find bugs/ errors or if something just doesn't work as your expect it to, please let us know. You can log a bug on GitHub or provide feedback here.
Overview#
Terraform plan expansion parses the output of terraform show -json and converts Azure resources from the AzAPI provider into ARM-format representations.
These are then evaluated by the same PSRule rules used for ARM templates and Bicep files.
Supported providers#
Currently, the following Terraform providers are supported:
| Provider | Support |
|---|---|
AzAPI (azure/azapi) |
azapi_resource and azapi_update_resource are converted to ARM format. |
AzureRM (hashicorp/azurerm) |
Not yet supported. Planned for a future release. |
The AzAPI provider is a thin wrapper over the Azure ARM REST API, meaning its body property is already in ARM-compatible format.
This makes it the highest-fidelity provider for PSRule analysis.
Getting started#
Step 1: Generate a Terraform plan#
In your CI pipeline, generate a plan and export it as JSON:
Step 2: Enable Terraform plan expansion#
Add the following to your ps-rule.yaml configuration:
Step 3: Run PSRule#
Analyze the plan JSON file with PSRule:
Or using the CLI:
How it works#
When AZURE_TERRAFORM_PLAN_EXPANSION is enabled and a JSON file matching the Terraform plan schema is detected, PSRule:
- Parses the
planned_valuessection of the plan JSON. - Walks the module tree (including nested
child_modules). - For each
azapi_resourceorazapi_update_resourcewithmode: "managed", converts it to ARM format. - Imports the converted resources into PSRule for rule evaluation.
Resource conversion#
The converter performs the following mappings from AzAPI to ARM format:
| AzAPI property | ARM property | Notes |
|---|---|---|
type (e.g., Microsoft.Storage/storageAccounts@2023-01-01) |
type + apiVersion |
Split at @ |
name |
name |
Direct |
location |
location |
Direct; omitted if null |
parent_id + type + name |
id |
Constructed resource ID |
body.* |
Merged to resource root | properties, sku, etc. |
tags |
tags |
Top-level takes precedence over body.tags |
identity.type |
identity.type |
Direct |
identity.identity_ids |
identity.userAssignedIdentities |
Array converted to object |
Excluded resource types#
The following are excluded from conversion:
- Data sources (
mode: "data") — Read-only lookups, not deployable resources. azapi_resource_action— Invokes POST actions, not a resource definition.azapi_data_plane_resource— Data plane operations don't map to ARM resources.- Non-Azure providers — Resources from
hashicorp/random,hashicorp/null, etc. are skipped.
Limitations#
The following limitations apply to Terraform plan expansion:
- Only
azapi_resourceandazapi_update_resourcetypes are supported. Theazurermprovider is not yet supported. - Raw
.tffiles cannot be analyzed directly. You must first generate a plan JSON file. - Unknown-at-plan-time values — Properties that Terraform cannot resolve until after
apply(e.g., resource IDs, FQDNs) will be absent from analysis.- As a result, using the
hashicorp/randomto generate resource names dynamically is currently not supported.
- As a result, using the
- Ephemeral values — Terraform 1.10+ ephemeral values are redacted from plan JSON and will not be available.
- Sensitive values — Values marked as sensitive in Terraform are redacted in the plan JSON.
- No runtime property projection — Unlike Bicep expansion, runtime-only properties (e.g.,
principalId) are not projected. azapi_update_resourceonly contains the properties being updated, not the full resource definition.
Configuration#
| Option | Type | Default | Description |
|---|---|---|---|
AZURE_TERRAFORM_PLAN_EXPANSION |
bool |
false |
Enable expansion from Terraform plan JSON files. |