Governance Anti Patterns Terraform Structure - Azure/az-prototype GitHub Wiki

Terraform Structure

Provider hygiene, version consistency, tag placement, and azapi conventions

Domain: terraform_structure


Checks (9)

Check Description
ANTI-TFS-001 azurerm provider detected — use hashicorp/azapi provider with azapi_resource for all resources.
ANTI-TFS-002 azurerm resource detected — use azapi_resource with the ARM resource type instead.
ANTI-TFS-003 Random provider detected — use deterministic alternatives like substr(md5(...)).
ANTI-TFS-004 Outdated azapi provider version detected — use ~> 2.x.
ANTI-TFS-005 uuid() detected — use uuidv5() with a deterministic seed for reproducible GUIDs.
ANTI-TFS-006 jsondecode() on azapi resource output — use .output.properties.* directly (azapi v2 syntax).
ANTI-TFS-007 Accessing .output.properties.* without response_export_values — add response_export_values = ["*"] to the resource.
ANTI-TFS-008 data.azurerm_client_config detected — use var.subscription_id and var.tenant_id instead.
ANTI-TFS-009 data.azurerm_subscription detected — use var.subscription_id instead.

ANTI-TFS-001

azurerm provider detected — use hashicorp/azapi provider with azapi_resource for all resources.

Rationale: The azurerm provider is not used in this project. All resources use azapi_resource with ARM resource types.
Agents: terraform-agent

Targets

Services Triggers On Correct Patterns
*All*
  • 'source = "hashicorp/azurerm"'
  • 'source = "hashicorp/azurerm"'
  • 'provider "azurerm"'
  • 'source = "hashicorp/azapi"'

ANTI-TFS-002

azurerm resource detected — use azapi_resource with the ARM resource type instead.

Rationale: azurerm_* resources require the azurerm provider which is not used; use azapi_resource with ARM resource types instead.
Agents: terraform-agent

Targets

Services Triggers On Correct Patterns
*All*
  • 'azurerm_role_assignment'
  • 'azurerm_monitor_metric_alert'
  • 'azurerm_storage_management_policy'
  • 'azurerm_key_vault_secret'
  • 'azurerm_monitor_diagnostic_setting'
  • 'Microsoft.Authorization/roleAssignments@'
  • 'Microsoft.Insights/diagnosticSettings@'

ANTI-TFS-003

Random provider detected — use deterministic alternatives like substr(md5(...)).

Rationale: The random provider generates different values on each apply, breaking plan reproducibility and causing unnecessary resource recreation.
Agents: terraform-agent

Targets

Services Triggers On Correct Patterns
*All*
  • 'source = "hashicorp/random"'
  • 'source = "hashicorp/random"'
  • 'provider "random"'
  • 'random_string'
  • 'random_id'
  • 'random_pet'
  • 'substr(md5("deterministic-seed"), 0, 8)'

ANTI-TFS-004

Outdated azapi provider version detected — use ~> 2.x.

Rationale: azapi 1.x uses different output access patterns (jsondecode) and lacks v2 features like direct property access.
Agents: terraform-agent

Targets

Services Triggers On Correct Patterns
*All*
  • '~> 1.15'
  • '~> 1.14'
  • '~> 1.13'
  • '~> 1.12'
  • '~> 1.11'
  • '~> 1.10'
  • '~> 2.8'
  • '~> 2.'

ANTI-TFS-005

uuid() detected — use uuidv5() with a deterministic seed for reproducible GUIDs.

Rationale: uuid() generates a new value every time Terraform evaluates it, causing unnecessary resource recreation on every apply.
Agents: terraform-agent

Targets

Services Triggers On Correct Patterns
*All*
  • 'uuid()'
  • 'uuidv5("6ba7b811-9dad-11d1-80b4-00c04fd430c8", "deterministic-seed")'

ANTI-TFS-006

jsondecode() on azapi resource output — use .output.properties.* directly (azapi v2 syntax).

Rationale: azapi v2 provides direct property access via .output.properties.* — jsondecode is a v1 workaround that is unnecessary and error-prone.
Agents: terraform-agent

Targets

Services Triggers On Correct Patterns
*All*
  • 'jsondecode(azapi_resource.'
  • 'jsondecode( azapi_resource.'
  • '.output.properties.'

ANTI-TFS-007

Accessing .output.properties.* without response_export_values — add response_export_values = ["*"] to the resource.

Rationale: azapi_resource requires response_export_values to be set for any .output.properties.* access — without it, the value is null.
Agents: terraform-agent

Targets

Services Triggers On Correct Patterns
*All*
  • '.output.properties.'
  • 'response_export_values = ["*"]'

ANTI-TFS-008

data.azurerm_client_config detected — use var.subscription_id and var.tenant_id instead.

Rationale: data.azurerm_client_config requires azurerm provider — use var.subscription_id and var.tenant_id instead.
Agents: terraform-agent

Targets

Services Triggers On Correct Patterns
*All*
  • 'data.azurerm_client_config'
  • 'data "azurerm_client_config"'
  • 'var.subscription_id'
  • 'var.tenant_id'

ANTI-TFS-009

data.azurerm_subscription detected — use var.subscription_id instead.

Rationale: data.azurerm_subscription requires azurerm provider — use var.subscription_id for subscription-level references.
Agents: terraform-agent

Targets

Services Triggers On Correct Patterns
*All*
  • 'data.azurerm_subscription'
  • 'data "azurerm_subscription"'
  • 'var.subscription_id'

⚠️ **GitHub.com Fallback** ⚠️