Azure Verified Modules
Glossary GitHub GitHub Issues Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Back to homepage

TFNFR12 - Dynamic for Optional Nested Objects

ID: TFNFR12 - Category: Code Style - Dynamic for Optional Nested Objects

An example from the community:

resource "azurerm_kubernetes_cluster" "main" {
  ...
  dynamic "identity" {
    for_each = var.client_id == "" || var.client_secret == "" ? [1] : []

    content {
      type                      = var.identity_type
      user_assigned_identity_id = var.user_assigned_identity_id
    }
  }
  ...
}

Please refer to the coding style in the example. Nested blocks under conditions, MUST be declared as:

Read full article gdoc_arrow_right_alt

TFNFR13 - Default Values with coalesce/try

ID: TFNFR13 - Category: Code Style - Default Values with coalesce/try

The following example shows how "${var.subnet_name}-nsg" SHOULD be used when var.new_network_security_group_name is null or ""

Good examples:

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

Bad examples:

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

TFNFR14 - Not allowed variables

ID: TFNFR14 - Category: Inputs - Not allowed variables

Since Terraform 0.13, count, for_each and depends_on are introduced for modules, module development is significantly simplified. Module’s owners MUST NOT add variables like enabled or module_depends_on to control the entire module’s operation. Boolean feature toggles are acceptable however.

Read full article gdoc_arrow_right_alt

TFNFR15 - Variable Definition Order

ID: TFNFR15 - Category: Code Style - Variable Definition Order

Input variables SHOULD follow this order:

  1. All required fields, in alphabetical order
  2. All optional fields, in alphabetical order

A variable without default value is a required field, otherwise it’s an optional one.

Read full article gdoc_arrow_right_alt

TFNFR16 - Variable Naming Rules

ID: TFNFR16 - Category: Code Style - Variable Naming Rules

The naming of a variable SHOULD follow HashiCorp’s naming rule .

variable used as feature switches SHOULD apply a positive statement, use xxx_enabled instead of xxx_disabled. Avoid double negatives like !xxx_disabled.

Read full article gdoc_arrow_right_alt

TFNFR17 - Variables with Descriptions

ID: TFNFR17 - Category: Code Style - Variables with Descriptions

The target audience of description is the module users.

For a newly created variable (Eg. variable for switching dynamic block on-off), it’s description SHOULD precisely describe the input parameter’s purpose and the expected data type. description SHOULD NOT contain any information for module developers, this kind of information can only exist in code comments.

Read full article gdoc_arrow_right_alt

TFNFR18 - Variables with Types

ID: TFNFR18 - Category: Code Style - Variables with Types

type MUST be defined for every variable. type SHOULD be as precise as possible, any MAY only be defined with adequate reasons.

  • Use bool instead of string or number for true/false
  • Use string for text
  • Use concrete object instead of map(any)

TFNFR19 - Sensitive Data Variables

ID: TFNFR19 - Category: Code Style - Sensitive Data Variables

If variable’s type is object and contains one or more fields that would be assigned to a sensitive argument, then this whole variable SHOULD be declared as sensitive = true, otherwise you SHOULD extract sensitive field into separated variable block with sensitive = true.

Read full article gdoc_arrow_right_alt

TFNFR2 - Module Documentation Generation

ID: TFNFR2 - Category: Documentation - Module Documentation Generation

Terraform modules documentation MUST be automatically generated via Terraform Docs .

A file called .terraform-docs.yml MUST be present in the root of the module and have the following content:

---
### To generate the output file to partially incorporate in the README.md,
### Execute this command in the Terraform module's code folder:
# terraform-docs -c .terraform-docs.yml .

formatter: "markdown document" # this is required

version: "0.16.0"

header-from: "_header.md"
footer-from: "_footer.md"

recursive:
  enabled: false
  path: modules

sections:
  hide: []
  show: []

content: |-
  {{ .Header }}

  <!-- markdownlint-disable MD033 -->
  {{ .Requirements }}

  {{ .Providers }}

  {{ .Resources }}

  <!-- markdownlint-disable MD013 -->
  {{ .Inputs }}

  {{ .Outputs }}

  {{ .Modules }}

  {{ .Footer }}  

output:
  file: README.md
  mode: replace
  template: |-
    <!-- BEGIN_TF_DOCS -->
    {{ .Content }}
    <!-- END_TF_DOCS -->    
output-values:
  enabled: false
  from: ""

sort:
  enabled: true
  by: required

settings:
  anchor: true
  color: true
  default: true
  description: false
  escape: true
  hide-empty: false
  html: true
  indent: 2
  lockfile: true
  read-comments: true
  required: true
  sensitive: true
  type: true

TFNFR20 - Non-Nullable Defaults for collection values

ID: TFNFR20 - Category: Code Style - Non-Nullable Defaults for collection values

Nullable SHOULD be set to false for collection values (e.g. sets, maps, lists) when using them in loops. However for scalar values like string and number, a null value MAY have a semantic meaning and as such these values are allowed.

Read full article gdoc_arrow_right_alt