key vaultsecurityazurecafnaming conventions

Azure Key Vault Naming Conventions: CAF Rules and Soft-Delete Gotchas

CAF-compliant naming for Azure Key Vault — including the 24-character limit, globally unique names, soft-delete name reservation, and Terraform/Bicep examples.

AzureNamer Team ·

Azure Key Vault has two naming quirks that catch teams out: the 24-character maximum, and soft-delete name reservation. A Key Vault you delete stays reserved under that name for 90 days — even across subscriptions. Get the naming right upfront, because recovering from a collision on a deleted vault is surprisingly painful.

The constraints

RuleDetail
CAF prefixkv
Min length3 characters
Max length24 characters
Allowed charactersAlphanumerics and hyphens
Must start withA letter
Must end withA letter or digit
Scope of uniquenessGlobal (within Azure public cloud)
Soft-delete reservation90 days after deletion

CAF naming pattern

kv-{workload}-{environment}-{region}-{instance}

Examples:

WorkloadEnvironmentRegionKey Vault name
paymentsprodeuskv-payments-prod-eus
hrportaldevweukv-hrportal-dev-weu
sharedprodeuskv-shared-prod-eus-001
infrastgukskv-infra-stg-uks-001

Note that kv-payments-prod-eus is already 20 characters — you have 4 characters left for an instance number before hitting the 24-character ceiling. For longer workload names, abbreviate:

kv-pmts-prod-eus-001      ← "pmts" for payments (22 chars)
kv-hrp-prod-eus-001       ← "hrp" for hrportal (19 chars)

The soft-delete gotcha

Since Azure Key Vault 2020, soft-delete is mandatory and cannot be disabled. When you delete a Key Vault, its name is reserved for 90 days in a “soft-deleted” state — even if you move to a different subscription or even a different Azure AD tenant in the same cloud.

This creates a problem in CI/CD pipelines and Terraform workflows that create and destroy environments frequently. If a Key Vault named kv-payments-dev-eus-001 is destroyed in a teardown, you can’t create a new one with the same name for 90 days.

Solutions

Option 1 — Purge on delete (Terraform):

resource "azurerm_key_vault" "main" {
  name                      = "kv-payments-dev-eus-001"
  resource_group_name       = azurerm_resource_group.main.name
  location                  = azurerm_resource_group.main.location
  tenant_id                 = data.azurerm_client_config.current.tenant_id
  sku_name                  = "standard"
  soft_delete_retention_days = 7        # minimum allowed
  purge_protection_enabled  = false     # allow hard delete
}

With purge_protection_enabled = false and a short retention, you can manually purge the vault after deletion and immediately reuse the name. Never disable purge protection in production.

Option 2 — Include a timestamp or build ID in the name:

variable "instance" { default = "001" }   # bump this for each teardown cycle

resource "azurerm_key_vault" "main" {
  name = "kv-payments-dev-eus-${var.instance}"
}

Option 3 — Don’t destroy dev Key Vaults; rotate secrets instead. If the vault is cheap to keep running (it is — ~$0/month at low usage), leave it and rotate the secrets rather than deleting the vault.

Purging a soft-deleted Key Vault

If you’re blocked by a soft-deleted vault name, purge it from the CLI:

# List soft-deleted vaults
az keyvault list-deleted --resource-type vault

# Purge a specific vault (irreversible)
az keyvault purge --name kv-payments-dev-eus-001 --location eastus

Or from PowerShell:

Get-AzKeyVault -InRemovedState
Remove-AzKeyVault -VaultName "kv-payments-dev-eus-001" -Location "eastus" -InRemovedState -Force

Managed HSM naming

Azure Dedicated HSM and Managed HSM have their own resource type:

ResourceCAF prefixMax lengthHyphens
Key Vault (standard/premium)kv24Yes
Managed HSMkvmhsm24Yes
kvmhsm-payments-prod-eus-001

Naming in Terraform

variable "workload"    { default = "payments" }
variable "environment" { default = "prod" }
variable "region"      { default = "eus" }

resource "azurerm_resource_group" "main" {
  name     = "rg-${var.workload}-${var.environment}-${var.region}-001"
  location = "eastus"
}

data "azurerm_client_config" "current" {}

resource "azurerm_key_vault" "main" {
  name                       = "kv-${var.workload}-${var.environment}-${var.region}-001"
  resource_group_name        = azurerm_resource_group.main.name
  location                   = azurerm_resource_group.main.location
  tenant_id                  = data.azurerm_client_config.current.tenant_id
  sku_name                   = "standard"
  soft_delete_retention_days = 90
  purge_protection_enabled   = true   # required for production

  tags = {
    environment = var.environment
    workload    = var.workload
  }
}

Naming in Bicep

param workload string = 'payments'
param environment string = 'prod'
param region string = 'eus'

var kvName = take('kv-${workload}-${environment}-${region}-001', 24)

resource keyVault 'Microsoft.KeyVault/vaults@2023-07-01' = {
  name: kvName
  location: resourceGroup().location
  properties: {
    sku: {
      family: 'A'
      name: 'standard'
    }
    tenantId: subscription().tenantId
    enableSoftDelete: true
    softDeleteRetentionInDays: 90
    enablePurgeProtection: true
  }
}

The take() function truncates to 24 characters if the name would exceed the limit — safer than letting the deployment fail at runtime.

Enforcing Key Vault naming with Azure Policy

Require the kv- prefix and deny any Key Vault with purge protection disabled in production:

{
  "if": {
    "allOf": [
      { "field": "type", "equals": "Microsoft.KeyVault/vaults" },
      { "field": "name", "notMatch": "kv-*" }
    ]
  },
  "then": { "effect": "Deny" }
}

Summary

  • Pattern: kv-{workload}-{environment}-{region}-{instance} — 24-character max, hyphens allowed
  • Names are globally unique across all of Azure; plan accordingly
  • Soft-delete reserves your vault name for 90 days after deletion — critical for ephemeral environments
  • Disable purge protection only in dev/test; always enable it in production
  • Use take() in Bicep or substr() in Terraform to guard against truncation at the 24-char limit

Use AzureNamer to generate Key Vault names and the corresponding Azure Policy in seconds.

Try AzureNamer

Generate CAF-compliant names for all 203 Azure resource types — free, no login required.

Open the Generator →