Key Vault looks trivial: put secret in, read secret out. The design decisions that separate a clean deployment from a mess are about topology, access model, and rotation. Get those three right and Key Vault quietly does its job for years. Get them wrong and you have a single shared vault with two hundred secrets, access policies nobody can audit, and certificates that expire in production on a Saturday.
Topology: Vault per Workload per Environment
One vault per application per environment. The vault becomes a security boundary that matches your RBAC boundary: the payments team touches the payments vaults and nothing else, production access differs from dev, and a compromise blast radius stays small. Shared vaults always drift toward everyone having access to everything.
resource "azurerm_key_vault" "payments_prod" {
name = "kv-payments-prod-weu"
location = "westeurope"
resource_group_name = azurerm_resource_group.sec.name
tenant_id = data.azurerm_client_config.current.tenant_id
sku_name = "standard"
rbac_authorization_enabled = true
purge_protection_enabled = true
soft_delete_retention_days = 90
public_network_access_enabled = false
}
resource "azurerm_role_assignment" "app_read" {
scope = azurerm_key_vault.payments_prod.id
role_definition_name = "Key Vault Secrets User"
principal_id = azurerm_user_assigned_identity.payments.principal_id
}
Non negotiables in that block: RBAC authorization instead of legacy access policies, purge protection on (required for CMK scenarios and prevents an attacker permanently destroying secrets), and public access off with a private endpoint in front. Humans get access through PIM eligible roles, never standing assignments, and applications authenticate with managed identities, never client secrets, because using a secret to fetch secrets defeats the point.
Certificate Rotation That Actually Rotates
Key Vault certificates carry a lifetime policy, and for public certs an integrated CA (DigiCert or GlobalSign) lets Key Vault renew automatically. The consumers that matter, App Gateway, App Service, and AKS via the Secrets Store CSI driver, all poll the vault and pick up the new version without redeployment. That combination is the difference between certificate expiry being an incident category and being a non event.
resource "azurerm_key_vault_certificate" "api" {
name = "api-contoso-com"
key_vault_id = azurerm_key_vault.payments_prod.id
certificate_policy {
issuer_parameters {
name = "DigiCert"
}
key_properties {
key_type = "RSA"
key_size = 2048
exportable = true
reuse_key = false
}
lifetime_action {
action {
action_type = "AutoRenew"
}
trigger {
days_before_expiry = 30
}
}
x509_certificate_properties {
subject = "CN=api.contoso.com"
validity_in_months = 12
key_usage = ["digitalSignature", "keyEncipherment"]
}
}
}
Key Rotation and Customer Managed Keys
For encryption keys backing storage accounts, disks, and databases, set a rotation policy on the key itself. Azure services using CMK reference the key without a version, so when Key Vault rotates it the service starts using the new version automatically.
resource "azurerm_key_vault_key" "storage_cmk" {
name = "cmk-storage"
key_vault_id = azurerm_key_vault.payments_prod.id
key_type = "RSA"
key_size = 3072
key_opts = ["unwrapKey", "wrapKey"]
rotation_policy {
automatic {
time_before_expiry = "P30D"
}
expire_after = "P90D"
notify_before_expiry = "P29D"
}
}
Secrets Are the Weak Link
Certificates and keys rotate natively. Plain secrets do not, because rotation means coordinating with the system that validates the credential. The pattern that works: an Event Grid subscription on the vault fires SecretNearExpiry, a Function generates a new credential at the source (database, API provider), writes it as a new secret version, and applications always read the latest version at startup or on a short cache. Better still, eliminate the secret entirely, and every managed identity you adopt is one less thing to rotate. Finally, enable diagnostic logging to Log Analytics and alert on denied access attempts and purge operations, because a vault that is being probed is telling you something.
Cheers
Osama
Leave a comment