Skip to content

Build5Nines/terraform-azure-naming

Azure Naming

Unit Tests azurerm: supported azapi: supported

Stop wasting time manually crafting Azure resource names and eliminate naming inconsistencies across your infrastructure. This Terraform module automates your entire Azure naming convention, ensuring every resource—from resource groups to storage accounts to key vaults—follows your organizational standards automatically.

What you get:

  • Instant productivity: Define your convention once, apply it everywhere—across all 70+ Azure resource types and Azure Regions!
  • Zero errors: No more typos, forgotten abbreviations, or inconsistent patterns
  • Multi-region made simple: Deploy to multiple Azure Regions with automatic location-aware naming
  • Multi-Provider flexibility: Supports both the azurerm and azapi Azure providers for Terraform for maximum flexibility of adhering to your naming convention
  • Team alignment: Everyone on your team uses the same naming standard without thinking about it
  • Proven foundation: This module is built on and extends Microsoft's official Azure/naming/azurerm module

Transform hours of naming decisions into seconds with a consistent, location‑aware, environment‑aware Microsoft Azure resource naming convention.


Quick Start

module "azure_primary" {
    source        = "Build5Nines/naming/azure"
    organization  = "b59"
    environment   = "prod"
    location      = "East US"   # or "eastus"
}

resource "azurerm_resource_group" "main" {
    name     = module.azure_primary.resources.resource_group.name
    location = module.azure_primary.location
}

Resulting resource group name pattern (example):

rg-b59-eus-prod

(rg is applied internally by the upstream module as the slug for a resource group.)

This naming pattern enables the use of this module to more easily adhere to a defined Azure resource naming convention for multiple Azure resources. Here's an example of using this to set the prefix of the Azure resource names using the defined naming convention while also naming them according to the specific workload and using the correct Azure resource abbreviation:

resource "azurerm_storage_account" "files" {
  name                     = "${module.azure_primary.resources.storage_account.name}files"
  resource_group_name      = azurerm_resource_group.main.name
  location                 = azurerm_resource_group.main.location
  account_tier             = "Standard"
  account_replication_type = "GRS"
}

resource "azurerm_sql_server" "sql_data" {
  name                         = "${module.azure_primary.resources.sql_server.name}-data"
  resource_group_name          = azurerm_resource_group.main.name
  location                     = azurerm_resource_group.main.location
  version                      = "12.0"
  administrator_login          = "dataadministrator"
  administrator_login_password = "b59isawesome"
}

Resulting resources will be named (example):

Azure Storage Account = stb59eusprodfiles
Azure SQL Server      = sql-b59-eus-prod-data

Real-World Examples

If you're looking for some more practical example usages of this module, check out the following:


Additional Highlights

  • Eliminate naming inconsistencies across your Azure infrastructure with a single, reusable module.
  • Save time and reduce errors by automating complex naming conventions instead of manually crafting names.
  • Manage multi-region architectures more easily with built-in region pairing and location-aware naming.
  • Maintain compliance with organizational standards through consistent naming patterns across all environments.
  • Access 70+ Azure resource types with proper abbreviations and constraints—all from one unified interface.
  • Scale your infrastructure confidently knowing every resource follows your defined naming convention.

Accessing Resource Names

The resources output is an entire instantiated module object from Azure/naming/azurerm, not just a string. This means that the resources output has properties for each Azure Resource type. Each resource (e.g. .resources.app_service) is an object with additional properties for that Azure Resource type:

Property Description
name Generated name with your suffix applied.
name_unique Same as name but with additional random characters for uniqueness (when supported).
slug Short identifier segment for the resource type (e.g. rg, sa, kv).
min_length Minimum allowed length.
max_length Maximum allowed length.
scope Uniqueness scope (resourcegroup, global, etc.).
dashes Whether dashes are allowed.
regex Validation regex (Terraform compatible).

Example usages:

# Storage Account
resource "azurerm_storage_account" "sa" {
    name                     = module.azure_primary.resources.storage_account.name
    resource_group_name      = azurerm_resource_group.main.name
    location                 = module.azure_primary.location
    account_tier             = "Standard"
    account_replication_type = "LRS"
}

# Unique variation (if collision risk)
resource "azurerm_key_vault" "kv" {
    name                = module.azure_primary.resources.key_vault.name_unique
    resource_group_name = azurerm_resource_group.main.name
    location            = module.azure_primary.location
    tenant_id           = data.azurerm_client_config.current.tenant_id
    sku_name            = "standard"
}

Secondary / Paired Region

location_secondary exposes the paired (or canonicalized) region derived from data/region_pair.json. Use it to instantiate a second module instance for DR / HA scenarios:

module "azure_secondary" {
    source       = "Build5Nines/naming/azure"
    organization = module.azure_primary.organization
    environment  = module.azure_primary.environment
    location     = module.azure_primary.location_secondary
}

Customizing the Suffix Naming Pattern

The default suffix is equivalent to the pattern array:

name_suffix = ["{org}", "{loc}", "{env}"]

You can rearrange or add static parts:

module "azure_primary" {
    source        = "Build5Nines/naming/azure"
    organization  = "b59"
    environment   = "dev"
    location      = "westeurope"
    name_suffix   = ["{org}", "{env}", "{loc}"] # b59-dev-weu
}

Customizing the Prefix Naming Pattern

The default prefix is empty, so if you want to use the prefix patter instead of the suffix pattern you'll need to set the input variables for what you need.

Here's an example of using a Prefix Naming Pattern (via name_prefix):

module "azure_primary" {
    source      = "Build5Nines/naming/azure"
    organization = "b59"
    environment  = "prod"
    location     = "westus"
    name_prefix =  ["{org}", "{env}", "{loc}"] # b59-dev-wus
    name_suffix  = []
}

resource "azurerm_storage_account" "sa" {
    name                     = module.azure_primary.resources.storage_account.name
    resource_group_name      = azurerm_resource_group.main.name
    location                 = module.azure_primary.location
    account_tier             = "Standard"
    account_replication_type = "LRS"
}

resource "azurerm_sql_server" "sql_data" {
  name                         = "${module.azure_primary.resources.sql_server.name}-data"
  resource_group_name          = azurerm_resource_group.main.name
  location                     = azurerm_resource_group.main.location
  version                      = "12.0"
  administrator_login          = "dataadministrator"
  administrator_login_password = "b59isawesome"
}

In this example of using a Prefix Naming Pattern, the Azure resource names will be set to:

Azure Storage Account = b59devwussa
Azure SQL Server      = b59-dev-wus-sql-data

Customizing the Azure Region / Location Abbreviations

Override region abbreviations:

module "azure_primary" {
    source        = "Build5Nines/naming/azure"
    organization  = "b59"
    environment   = "prod"
    location      = "East US"
    location_abbreviations = {
        eastus = "east"    # overrides default "eus"
        westus = "west"
    }
}

Customizing the Secondary Location / Azure Region Pair

Override the secondary location by setting a custom secondary region on the primary module:

module "azure_primary" {
    source              = "Build5Nines/naming/azure"
    organization        = "b59"
    environment         = "prod"
    location            = "East US"
    location_secondary  = "North Central US  # or "northcentralus"
}

# Now module.azure_primary.location_secondary == "North Central US"

By default, the module will lookup the Microsoft Region Pair to return for the location_secondary output from the module. By setting the location_secondary explicitly, you can override this behavior by setting the secondary location needed for your own disaster recovery plans.


Inputs

Name Description Type Default Required
organization Organization / business unit segment. string "" yes*
environment Environment segment (dev, test, prod, etc.). string "" yes*
location Azure region (display or programmatic). string n/a yes
name_prefix Ordered list of pattern tokens / literals forming the prefix. Tokens: {org}, {loc}, {env}. list(string) `[] no
name_suffix Ordered list of pattern tokens / literals forming the suffix. Tokens: {org}, {loc}, {env}. list(string) ["{org}", "{loc}", "{env}"] no
location_abbreviations Map of region -> abbreviation overrides (display or programmatic keys). map(string) {} no
location_secondary Optional override for the secondary region. When set (non-empty), the location_secondary output will equal this value instead of the computed Microsoft regional pair. string "" no
unique_include_numbers Include numbers in the unique suffix generation. bool true no
unique_length Max length of the uniqueness suffix to be added number 4 no
unique_seed Custom value for the random characters to be used string "" no

organization / environment default to empty strings; supplying them is strongly recommended for meaningful names.


Outputs

Name Description
base_suffix Final joined suffix string (e.g. b59-eus-prod).
resources The full upstream Azure naming module instance (access resource names via resources.<resource>.name).
organization Echo of var.organization.
environment Echo of var.environment.
location Original provided location input.
location_abbreviation Resolved abbreviation (override > JSON > canonical short name).
location_secondary Secondary region. If var.location_secondary is set (non-empty), this output equals that value; otherwise it is the paired/canonicalized region from region_pair.json.

Example referencing an output:

locals {
    rg_name     = module.azure_primary.resources.resource_group.name
    storage_slug = module.azure_primary.resources.storage_account.slug  # "st"
}

Internals

  • Canonicalization: location_canonical = lower(replace(var.location, " ", "")).
  • Abbreviations: Merge of JSON defaults + raw overrides + canonicalized override keys.
  • Region pairing: region_pair.json maps both display and programmatic names to a paired region.
  • Suffix expansion: Each element of var.name_suffix has tokens replaced; result list joined into a single string by the upstream module when composing names.
  • Upstream module call:
    module "azure_naming" {
        source = "Azure/naming/azurerm"
        suffix = local.name_suffix
    }

Advanced Usage

  • Use name_unique for resources that require globally unique naming (storage accounts, key vaults, etc.).
  • Derive secondary region infra with location_secondary.
  • Compose additional naming layers by appending static literals in name_suffix (e.g. add a workload slug {org}-{loc}-{env}-app).
  • Inspect constraints before naming collisions: module.azure_primary.resources.storage_account.max_length.

Region Data Files

File Purpose
data/region_abbr.json Default abbreviations keyed by canonical short region names.
data/region_pair.json Region pairing / canonicalization map (primary -> secondary).

Additions/changes are simple JSON edits; prefer PRs with minimal diff noise.


Inspiration / Upstream

This module wraps and extends the Microsoft Azure/naming/azurerm module, adding organizational & regional context consistency while reusing its comprehensive resource naming logic.


Example: Multi‑Region Deployment

module "azure_primary" {
    source       = "Build5Nines/naming/azure"
    organization = "b59"
    environment  = "prod"
    location     = "East US"
}

module "azure_secondary" {
    source       = "Build5Nines/naming/azure"
    organization = module.azure_primary.organization
    environment  = module.azure_primary.environment
    location     = module.azure_primary.location_secondary
}

resource "azurerm_resource_group" "primary" {
    name     = module.azure_primary.resources.resource_group.name
    location = module.azure_primary.location
}

resource "azurerm_resource_group" "secondary" {
    name     = module.azure_secondary.resources.resource_group.name
    location = module.azure_secondary.location
}

Troubleshooting

Symptom Cause Fix
Validation error for location Region not in allow list Use a supported region or update variables.tf.
Unexpected abbreviation Override not applied Ensure key matches display or programmatic name; canonical form will also work.
Missing paired region Pair absent in region_pair.json Add entry mapping both display & programmatic names.

FAQ

Q: Why an array (name_suffix) instead of a single template string?
Allows easier reordering and alignment with upstream module expectations (suffix accepts list).

Q: Why an array (name_prefix) instead of a single template string?
Using an array for name_prefix allows for greater flexibility in ordering and customization. It aligns with the upstream module's expectations, as the prefix can accept a list of tokens, making it easier to manage and modify the naming patterns as needed.

Q: Can I add a workload slug?
Yes, you can add a literal to either the name_prefix or name_suffix as required for your naming convention: ["{org}", "{loc}", "{env}", "api"].


Acknowledgments

This project is created and maintained by Chris Pietschmann, Microsoft MVP (Azure and Dev Tools), HashiCorp Ambassador, and MCT.