AVM TFLint Rules

This reference covers the custom AVM TFLint ruleset rules. It does not repeat rules provided by the standard Terraform TFLint plugin. AVM rules are enabled by default. An override is an exception to an AVM requirement and should be narrow, temporary where possible, and explained in the override file.

Rule applicability and overrides

Rules run in the scope that contains the applicable Terraform configuration:

  • All module scopes - the root module, each submodule, and each example independently.
  • Module scopes - the root module and each submodule independently; examples are excluded.
  • Root module - the published module root only.

To disable a rule, use the exact HCL shown in the Disable column. The configuration files and precedence rules are documented in TFLint configuration overrides.

RuleEnforcesScopeDisable
azapi_data_response_export_valuesAzAPI data sources declare response_export_values.All module scopesrule "azapi_data_response_export_values" { enabled = false }
azapi_replace_triggers_refsManaged AzAPI resources validate declared replacement-trigger paths.All module scopesrule "azapi_replace_triggers_refs" { enabled = false }
azapi_resource_tagSupported AzAPI resource types apply the standard tags input; unsupported types omit tags.All module scopesrule "azapi_resource_tag" { enabled = false }
azapi_response_export_valuesManaged AzAPI resources declare response_export_values.All module scopesrule "azapi_response_export_values" { enabled = false }
customer_managed_keyThe customer-managed key interface follows the AVM contract.All module scopesrule "customer_managed_key" { enabled = false }
deprecated_lock_interfaceDeprecated lock-interface shapes are not introduced.All module scopesrule "deprecated_lock_interface" { enabled = false }
deprecated_private_endpoints_interfaceDeprecated private-endpoint interface shapes are not introduced.All module scopesrule "deprecated_private_endpoints_interface" { enabled = false }
deprecated_role_assignments_interfaceDeprecated role-assignment interface shapes are not introduced.All module scopesrule "deprecated_role_assignments_interface" { enabled = false }
diagnostic_settingsThe diagnostic-settings interface follows the AVM contract.All module scopesrule "diagnostic_settings" { enabled = false }
ignore_body_changesApplicable AzAPI resources expose and apply ignore_body_changes.All module scopesrule "ignore_body_changes" { enabled = false }
locationThe location interface follows the AVM contract.All module scopesrule "location" { enabled = false }
lockThe lock interface follows the AVM contract.All module scopesrule "lock" { enabled = false }
managed_identitiesThe managed-identities interface follows the AVM contract.All module scopesrule "managed_identities" { enabled = false }
no_entire_resource_output_tffr2Outputs do not expose an entire provider resource.Module scopesrule "no_entire_resource_output_tffr2" { enabled = false }
private_endpointsThe private-endpoints interface follows the AVM contract.All module scopesrule "private_endpoints" { enabled = false }
private_endpoints_manage_dns_zone_groupPrivate-endpoint DNS-zone-group management follows the AVM contract.All module scopesrule "private_endpoints_manage_dns_zone_group" { enabled = false }
provider_azapi_version_constraintThe AzAPI provider constraint meets AVM requirements.Module scopesrule "provider_azapi_version_constraint" { enabled = false }
provider_azurerm_disallowedAzureRM is not used as a module foundation.Module scopesrule "provider_azurerm_disallowed" { enabled = false }
provider_azurerm_version_constraintAn approved AzureRM exception has the required constraint.Module scopesrule "provider_azurerm_version_constraint" { enabled = false }
provider_modtm_version_constraintThe ModTM provider constraint meets AVM requirements.Module scopesrule "provider_modtm_version_constraint" { enabled = false }
required_module_source_tffr1AVM module references use the required source format.Module scopesrule "required_module_source_tffr1" { enabled = false }
required_module_source_tfnfr10ignore_changes uses AVM-compliant references.All module scopesrule "required_module_source_tfnfr10" { enabled = false }
required_output_rmfr7Resource modules expose their required outputs.Root modulerule "required_output_rmfr7" { enabled = false }
resource_typesApplicable AzAPI resources use the resource_types interface.All module scopesrule "resource_types" { enabled = false }
retryApplicable AzAPI resources expose and apply retry.All module scopesrule "retry" { enabled = false }
role_assignmentsThe role-assignments interface follows the AVM contract.All module scopesrule "role_assignments" { enabled = false }
tagsThe standard tags interface follows the AVM contract.All module scopesrule "tags" { enabled = false }
terraform_heredoc_usageJSON and YAML are encoded with jsonencode or yamlencode, not literal heredocs.All module scopesrule "terraform_heredoc_usage" { enabled = false }
terraform_module_provider_declarationModules reject provider blocks and declare aliases with configuration_aliases.Module scopesrule "terraform_module_provider_declaration" { enabled = false }
terraform_sensitive_variable_no_defaultSensitive variables have no non-empty default.All module scopesrule "terraform_sensitive_variable_no_default" { enabled = false }
terraform_tf_fileEach module has exactly one terraform block in terraform.tf.Module scopesrule "terraform_tf_file" { enabled = false }
timeoutsApplicable AzAPI resources expose and apply timeouts.All module scopesrule "timeouts" { enabled = false }

Rule guidance

azapi data response export values

Applies TFFR4 to AzAPI data sources: declare response_export_values, including [] when no response fields are needed.

azapi replace triggers refs

Applies TFFR5. Omit replace_triggers_refs when no body paths require replacement. When present, it must be a non-empty static list of valid JMESPath expressions that identify body paths requiring replacement. Entries cannot be blank or duplicated, and cannot include name or location, because AzAPI already replaces the resource when either changes. When the body is statically evaluable, the rule verifies that each declared path resolves against it.

Authors remain responsible for identifying the properties that actually require replacement. Current Bicep-generated schemas do not reliably preserve create-only versus updateable mutability, so this rule validates declared paths but cannot prove that the list is semantically complete.

azapi resource tag

Applies TFFR9: set tags = var.tags exactly on types supported by the embedded AVM-generated capability snapshot, and omit tags for unsupported types. The rule skips dynamic or otherwise unevaluable type expressions.

The ruleset embeds its AVM-generated capability snapshot and works standalone. It does not consume, import, or query AzAPI, and does not accept an external snapshot path.

A weekly ruleset workflow compares the embedded snapshot with upstream data and opens a ruleset pull request when that data changes. Updated capability data ships with the next ruleset release. All users receive snapshot updates by upgrading the ruleset release.

azapi response export values

Applies TFFR4: every applicable managed AzAPI resource declares response_export_values, including [] when no fields are exported.

customer managed key

Validates the customer-managed key interface.

deprecated lock interface

Prevents new use of deprecated shapes in the resource-lock interface.

deprecated private endpoints interface

Prevents new use of deprecated shapes in the private-endpoints interface.

deprecated role assignments interface

Prevents new use of deprecated shapes in the role-assignments interface.

diagnostic settings

Validates the diagnostic-settings interface.

ignore body changes

Validates the AzAPI ignore_body_changes interface, including its per-resource and per-submodule applicability.

location

Validates the standard location interface.

lock

Validates the resource-lock interface.

managed identities

Validates the managed-identities interface.

no entire resource output tffr2

Applies TFFR2: output explicit values instead of an entire provider resource.

private endpoints

Validates the private-endpoints interface.

private endpoints manage dns zone group

Validates the DNS-zone-group behavior of the private-endpoints interface.

provider azapi version constraint

Validates the AzAPI constraint required by TFFR3.

provider azurerm disallowed

Applies the AzureRM-foundation prohibition in TFFR3.

provider azurerm version constraint

Validates the AzureRM constraint when the narrow TFFR3 exception is used.

provider modtm version constraint

Validates the ModTM provider constraint when that provider is used.

required module source tffr1

Applies TFFR1 to AVM module sources.

required module source tfnfr10

Applies TFNFR10 to ignore_changes references.

required output rmfr7

Applies the required-output contract in RMFR7.

resource types

Validates the AzAPI resource_types interface, including its deterministic resource-type keys and cascading shape.

retry

Validates the AzAPI retry interface.

role assignments

Validates the role-assignments interface.

tags

Validates the tags interface.

terraform heredoc usage

Applies TFNFR40: represent JSON or YAML structured values with jsonencode or yamlencode.

terraform module provider declaration

Applies TFNFR27: a published module contains no provider blocks; aliases are declared only through configuration_aliases and configured by its consumer.

terraform sensitive variable no default

Applies TFNFR23: a sensitive variable may default only to an empty collection.

terraform tf file

Applies TFNFR39: a module has exactly one terraform block and it is in terraform.tf.

timeouts

Validates the AzAPI timeouts interface.

MAPOTF and standard Terraform TFLint coverage

MAPOTF, not a custom AVM TFLint rule, owns formatting and deterministic ordering for resource and data blocks, variables, outputs, required providers, and file placement. It also removes redundant explicit nullable = true; that cleanup does not replace the semantic requirements for nullable = false in TFNFR20 and TFNFR21.

The standard Terraform TFLint plugin validates required_version and provider requirement declarations. TFNFR25 and TFNFR26 explain the complementary AVM file-layout and ordering requirements.

TFLint configuration overrides

Avm.Authoring loads the following repository-root override files:

FileDefault scope
avm.tflint.override.hclAll root-module checks
avm.tflint_module.override.hclAll submodule checks
avm.tflint_example.override.hclAll example checks
modules/<name>/avm.tflint.override.hclOne direct submodule
examples/<name>/avm.tflint.override.hclOne direct example

Each file contains normal TFLint rule configuration. For example:

rule "terraform_sensitive_variable_no_default" {
  enabled = false
}

Avm.Authoring merges overrides in this order: the immutable AVM base configuration, the matching repository-root all-scope override, then the target-directory override. A submodule or example override is loaded only for its target directory and takes precedence over the matching all-submodule or all-example file. Use it when an exception is specific to one direct child module or example; do not weaken the corresponding repository-wide default.

AVM permits only one directory layer for Terraform submodule and example roots: modules/* and examples/*. Nested Terraform module or example roots are prohibited, so target overrides apply only to those direct scopes. Avm.Authoring convention validation enforces this structure.