Skip to content
Development
Skill

/azure-verified-modules

Azure Verified Modules (AVM) requirements and best practices for developing certified Azure Terraform modules. Use when creating or reviewing Azure modules that need AVM certification.

From plugin
hashicorp-agent-skills
86420 skills
Install
$ npx -y skills add hashicorp/agent-skills --skill azure-verified-modules --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/azure-verified-modules

Context preview

The summary Claude sees to decide when to auto-load this skill.

Azure Verified Modules (AVM) requirements and best practices for developing certified Azure Terraform modules. Use when creating or reviewing Azure modules that need AVM certification.

SKILL.md

azure-verified-modules.SKILL.md
name: azure-verified-modules
description: Azure Verified Modules (AVM) requirements and best practices for developing certified Azure Terraform modules. Use when creating or reviewing Azure modules that need AVM certification.
metadata:
  lifecycle-status: active

Azure Verified Modules (AVM) Requirements

This guide covers the mandatory requirements for Azure Verified Modules certification. These requirements ensure consistency, quality, and maintainability across Azure Terraform modules.

**References:**

  • [Azure Verified Modules](https://azure.github.io/Azure-Verified-Modules/)
  • [AVM Module Specifications](https://azure.github.io/Azure-Verified-Modules/specs/module-specs/)

Table of Contents

  • [Module Cross-Referencing](#module-cross-referencing)
  • [Azure Provider Requirements](#azure-provider-requirements)
  • [Code Style Standards](#code-style-standards)
  • [Variable Requirements](#variable-requirements)
  • [Output Requirements](#output-requirements)
  • [Local Values Standards](#local-values-standards)
  • [Terraform Configuration Requirements](#terraform-configuration-requirements)
  • [Testing Requirements](#testing-requirements)
  • [Documentation Requirements](#documentation-requirements)
  • [Breaking Changes & Feature Management](#breaking-changes--feature-management)
  • [Contribution Standards](#contribution-standards)
  • [Compliance Checklist](#compliance-checklist)

---

Module Cross-Referencing

**Severity:** MUST | **Requirement:** TFFR1

When building Resource or Pattern modules, module owners **MAY** cross-reference other modules. However:

  • Modules **MUST** be referenced using HashiCorp Terraform registry reference to a pinned version
  • Example: `source = "Azure/xxx/azurerm"` with `version = "1.2.3"`
  • Modules **MUST NOT** use git references (e.g., `git::https://xxx.yyy/xxx.git` or `github.com/xxx/yyy`)
  • Modules **MUST NOT** contain references to non-AVM modules

---

Azure Provider Requirements

**Severity:** MUST | **Requirement:** TFFR3

Authors **MUST** only use the following Azure providers:

| Provider | Min Version | Max Version | |----------|-------------|-------------| | azapi | >= 2.0 | < 3.0 | | azurerm | >= 4.0 | < 5.0 |

**Requirements:**

  • Authors **MAY** select either Azurerm, Azapi, or both providers
  • **MUST** use `required_providers` block to enforce provider versions
  • **SHOULD** use pessimistic version constraint operator (`~>`)

**Example:**

terraform {
  required_providers {
    azurerm = {
      source  = "hashicorp/azurerm"
      version = "~> 4.0"
    }
    azapi = {
      source  = "Azure/azapi"
      version = "~> 2.0"
    }
  }
}

---

Code Style Standards

Lower snake_casing

**Severity:** MUST | **Requirement:** TFNFR4

**MUST** use lower snake_casing for:

  • Locals
  • Variables
  • Outputs
  • Resources (symbolic names)
  • Modules (symbolic names)

Example: `snake_casing_example`

Resource & Data Source Ordering

**Severity:** SHOULD | **Requirement:** TFNFR6

  • Resources that are depended on **SHOULD** come first
  • Resources with dependencies **SHOULD** be defined close to each other

Count & for_each Usage

**Severity:** MUST | **Requirement:** TFNFR7

  • Use `count` for conditional resource creation
  • **MUST** use `map(xxx)` or `set(xxx)` as resource's `for_each` collection
  • The map's key or set's element **MUST** be static literals

**Example:**

resource "azurerm_subnet" "pair" {
  for_each             = var.subnet_map  # map(string)
  name                 = "${each.value}-pair"
  resource_group_name  = azurerm_resource_group.example.name
  virtual_network_name = azurerm_virtual_network.example.name
  address_prefixes     = ["10.0.1.0/24"]
}

Resource & Data Block Internal Ordering

**Severity:** SHOULD | **Requirement:** TFNFR8

**Order within resource/data blocks:**

1. **Meta-arguments (top)**:

  • `provider`
  • `count`
  • `for_each`

2. **Arguments/blocks (middle, alphabetical)**:

  • Required arguments
  • Optional arguments
  • Required nested blocks
  • Optional nested blocks

3. **Meta-arguments (bottom)**:

  • `depends_on`
  • `lifecycle` (with sub-order: `create_before_destroy`, `ignore_changes`, `prevent_destroy`)

Separate sections with blank lines.

Module Block Ordering

**Severity:** SHOULD | **Requirement:** TFNFR9

**Order within module blocks:**

1. **Top meta-arguments**:

  • `source`
  • `version`
  • `count`
  • `for_each`

2. **Arguments (alphabetical)**:

  • Required arguments
  • Optional arguments

3. **Bottom meta-arguments**:

  • `depends_on`
  • `providers`

Lifecycle ignore_changes Syntax

**Severity:** MUST | **Requirement:** TFNFR10

The `ignore_changes` attribute **MUST NOT** be enclosed in double quotes.

**Good:**

lifecycle {
  ignore_changes = [tags]
}

**Bad:**

lifecycle {
  ignore_changes = ["tags"]
}

Null Comparison for Conditional Creation

**Severity:** SHOULD | **Requirement:** TFNFR11

For parameters requiring conditional resource creation, wrap with `object` type to avoid "known after apply" issues during plan stage.

**Recommended:**

variable "security_group" {
  type = object({
    id = string
  })
  default = null
}

Dynamic Blocks for Optional Nested Objects

**Severity:** MUST | **Requirement:** TFNFR12

Nested blocks under conditions **MUST** use this pattern:

dynamic "identity" {
  for_each = <condition> ? [<some_item>] : []

  content {
    # block content
  }
}

Default Values with coalesce/try

**Severity:** SHOULD | **Requirement:** TFNFR13

**Good:**

coalesce(var.new_network_security_group_name, "${var.subnet_name}-nsg")

**Bad:**

var.new_network_security_group_name == null ? "${var.subnet_name}-nsg" : var.new_network_security_group_name

Provider Declarations in Modules

**Severity:** MUST | **Requirement:** TFNFR27

  • `provider` **MUST NOT** be declared in modules (except for `configuration_a
Read more
Ships withhashicorp-agent-skills

HashiCorp Agent Skills for Terraform and Packer. See SKILLS.md for the complete catalog and lifecycle status of each Skill. Legal note: Your use of a third-party MCP client or LLM is subject solely to that provider's terms.

Get the whole plugin
Stats
864
Stars
126
Forks
Active
Maintenance
HCL
Language
MPL-2.0
License
10d ago
Last commit
10mo ago
Created

Repo: hashicorp/agent-skills

Other skills on hashicorp-agent-skills.