Azure Key Vault is a cloud service that provides a secure store for secrets, such as keys, passwords, and certificates. The service is used in conjunction with Terraform to define, preview, and deploy cloud infrastructure in a repeatable manner. Terraform enables the definition, preview, and deployment of cloud infrastructure. Using Terraform, you create configuration files using HCL syntax. The HCL syntax allows you to specify the cloud provider - such as Azure - and the elements that make up your cloud infrastructure. After you create your configuration files, you create an execution plan that allows you to preview your infrastructure changes before they're deployed. Once you verify the changes, you apply the execution plan to deploy the infrastructure.
The article focuses on the process of deploying a Terraform file to create a key vault and a key. The workflow is relevant to teams managing secrets, certificates, and keys securely as a critical part of any cloud infrastructure. Azure Key Vault is Microsoft’s go-to solution for secure key management, and Terraform provides a clean, repeatable way to manage secure resources. With just a few lines of code, you can automate what would normally take several steps in the Azure Portal.
The process begins with prerequisites and directory creation for testing and running sample Terraform code. The goal is to keep secrets out of code and configuration files, to centralize storage of sensitive data, and to maintain strong security practices through fine-grained control over who can access what. The deployment pattern covers provider setup, resource group creation, key vault provisioning, access policy configuration, and options for RBAC authorization.
Prerequisites and Environment Setup
Before diving into the code, make sure you’ve got the following set up:
- Terraform installed (version 1.10.0 or later)
- An active Azure subscription
- The Azure CLI installed and logged in
- A service principal or user account with sufficient permissions to deploy resources
- Familiarity with basic Terraform concepts (providers, resources, variables)
Creating a directory to test and run the sample Terraform code is listed as a prerequisite step in the learning path. The prerequisites ensure the execution plan can be created and applied without permission failures. Having the Azure CLI installed and logged in provides authentication context for data sources such as azurerm_client_config. A service principal or user account with sufficient permissions is required because key vault creation and access policy assignment demand contributor-level rights in Azure.
Terraform version constraints appear in the reference configurations. One configuration requires required_version = ">= 1.10.0". Another configuration requires required_version = ">= 1.5.0". Both constraints reflect version pinning to avoid breaking changes in provider behavior.
Azure Key Vault Fundamentals for Terraform
What is Azure Key Vault?
Azure Key Vault is a handy tool for securely storing sensitive information like secrets, encryption keys, and certificates. Centralising the storage of your sensitive data makes it easier to manage. Plus, it gives you fine-grained control over who can access what, helping you maintain strong security practices.
It’s never ideal to embed secrets into your code or configuration files, so storing them in Azure Key Vault and then calling the information as and when needed is the preferred solution.
Azure Key Vault offers a lot of features that can improve your security posture, soft delete, purge protection, and integration with Azure role based access control (RBAC) and managed identities.
It can also manage key rotation policies and work with hardware security modules (HSMs) for extra protection.
There are two SKUs available with Azure Key Vault, Standard and Premium. The standard SKU supports most use cases, while premium adds support for HSM-backed keys and advanced scenarios. You can view full pricing details on the Azure Pricing page.
The SKU choice directly influences cost and capability. Standard SKU is referenced in deployment examples with sku_name = "standard". The configuration comment notes "standard" or "premium" (supports HSM-protected keys). Soft delete and purge protection are enabled as best practices for protecting against accidental deletion.
Terraform Provider Configuration
Provider Version Constraints and Sources
Terraform configuration begins by declaring the Terraform version and required providers.
terraform {
required_version = ">= 1.10.0"
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = ">= 3.71, < 5.0.0"
}
random = {
source = "hashicorp/random"
version = ">= 3.5.1, < 4.0.0"
}
azapi = {
source = "Azure/azapi"
version = ">= 2.2.0, < 3.0.0"
}
}
}
Provider configuration is also shown in an alternative style:
terraform {
required_version = ">= 1.5.0"
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "~> 3.80"
}
}
}
Provider blocks include feature toggles.
provider "azurerm" {
features {}
subscription_id = "XXXX-XXXX-XXXX-XXXX"
}
An alternative provider block with key vault specific features:
provider "azurerm" {
features {
key_vault {
purge_soft_delete_on_destroy = false # Don't purge on destroy in production
recover_soft_deleted_key_vaults = true
}
}
}
The azurerm provider is used to deploy Azure resources. The random provider is used to randomly select a region. The azapi provider is used to support the modules being used. You must configure the providers with your Azure subscription details. The subscription_id in the azurerm provider should be updated with your actual ID.
The features block controls destroy behavior for soft-deleted key vaults. Setting purge_soft_delete_on_destroy = false prevents purging on destroy in production. Setting recover_soft_deleted_key_vaults = true enables recovery.
Data Sources for Current Context
data "azurerm_client_config" "current" {}
The data source retrieves the current client configuration for access policies. The tenantid and objectid used in access policies are obtained from this data source.
tenant_id = data.azurerm_client_config.current.tenant_id
object_id = data.azurerm_client_config.current.object_id
Resource Group and Naming
The Terraform configuration will:
- Randomly pick a region from a list
- Create a new Azure resource group
- Deploy an Azure Key Vault instance into that resource group
- Assign an access policy to the current user or service principal running the code
Resource group example:
resource "azurerm_resource_group" "kv" {
name = "rg-keyvault-production"
location = "East US"
}
Another example uses a reference to a resource group named rg:
location = azurerm_resource_group.rg.location
resource_group_name = azurerm_resource_group.rg.name
The resource group provides the container for the key vault. Location consistency between resource group and key vault is maintained by referencing the resource group location.
Key Vault Resource Definition
The core of the deployment is the azurerm_key_vault resource.
Example configuration:
resource "azurerm_key_vault" "example" {
name = module.naming.key_vault.name_unique
location = azurerm_resource_group.rg.location
resource_group_name = azurerm_resource_group.rg.name
tenant_id = data.azurerm_client_config.current.tenant_id
sku_name = "standard"
soft_delete_retention_days = 7
purge_protection_enabled = true
}
Alternative production-oriented configuration:
resource "azurerm_key_vault" "main" {
name = "kv-prod-2026"
location = azurerm_resource_group.kv.location
resource_group_name = azurerm_resource_group.kv.name
tenant_id = data.azurerm_client_config.current.tenant_id
sku_name = "standard" # "standard" or "premium" (supports HSM-protected keys)
soft_delete_retention_days = 90
}
Soft delete protects against accidental deletion. Purge protection prevents permanent deletion during retention.
The soft_delete_retention_days value differs across examples, 7 days in one example and 90 days in another. The choice impacts the recovery window after accidental deletion.
The name is generated via a naming module in one example: module.naming.key_vault.name_unique. In another example the name is static: kv-prod-2026.
Access Policies Configuration
Access policies are defined per-vault and offer granular permissions on keys, secrets, and certificates. Each vault supports up to 1024 access policies.
The traditional approach uses access policies to control who can do what with secrets, keys, and certificates.
Example access policy block:
access_policy {
tenant_id = data.azurerm_client_config.current.tenant_id
object_id = data.azurerm_client_config.current.object_id
secret_permissions = [
"Get",
"List",
"Set",
"Delete"
]
key_permissions = [
"Get",
"List",
"Create",
"Delete",
"Update",
"Import",
"Backup",
"Restore",
"GetRotationPolicy",
"Recover"
]
}
This grants the authenticated user/service principal access to manage secrets and keys. The permissions listed for secrets are Get, List, Set, Delete. The permissions listed for keys are Get, List, Create, Delete, Update, Import, Backup, Restore, GetRotationPolicy, Recover.
You can also verify that the access policy has been applied by reviewing your permissions in the Key Vault settings.
Setting it up through Terraform ensures consistent security configuration across all your environments and keeps your access policies version-controlled.
RBAC Authorization Model
RBAC authorization is the newer model. It uses Azure role assignments at the vault, resource group, or subscription level. Built-in roles like Key Vault Secrets User and Key Vault Administrator simplify management and work consistently with the rest of Azure RBAC.
For new deployments, RBAC is the recommended approach. It centralizes access control and integrates with Privileged Identity Management (PIM) for just-in-time access.
The reference material notes that access policies are defined per-vault and offer granular permissions. RBAC provides an alternative authorization model that centralizes access control.
Key Vault is a foundational piece of any secure Azure architecture. Getting it right in Terraform means your secrets management, encryption key storage, and certificate lifecycle are all reproducible and auditable from the start.
Variables and Separation of Concerns
Variables file
We keep the variables in a separate file from our main Terraform deployment.
Separating variables from main configuration supports environment promotion and secret-free code. The reference configuration mentions keeping variables in a separate file.
Deployment Workflow
Terraform enables the definition, preview, and deployment of cloud infrastructure. Using Terraform, you create configuration files using HCL syntax. After you create your configuration files, you create an execution plan that allows you to preview your infrastructure changes before they're deployed. Once you verify the changes, you apply the execution plan to deploy the infrastructure.
In this article, you learn how to create a directory to test and run the sample Terraform code.
The workflow produces a repeatable deployment where the key vault, resource group, and access policy are codified. The execution plan preview reduces risk before applying changes to production.
Feature Comparison Table
| Feature | Description |
|---|---|
| Soft Delete | Protects against accidental deletion |
| Purge Protection | Prevents permanent deletion during retention |
| SKU Standard | Supports most use cases |
| SKU Premium | Adds support for HSM-backed keys and advanced scenarios |
| Access Policies | Defined per-vault, up to 1024 per vault |
| RBAC | Role assignments at vault, resource group, or subscription level |
Provider and Resource Summary Table
| Component | Example Attribute |
|---|---|
| Terraform Version | >= 1.10.0 |
| Provider azurerm Source | hashicorp/azurerm |
| Provider random Source | hashicorp/random |
| Provider azapi Source | Azure/azapi |
| Key Vault SKU | standard |
| Soft Delete Retention | 7 days or 90 days |
| Purge Protection | enabled |
The tables summarize structured data extracted from the reference configurations.
Security Considerations
Soft delete and purge protection are best practices for protecting against accidental deletion. Integration with Azure RBAC and managed identities provides fine-grained control. Key rotation policies and HSM support provide extra protection.
Never embed secrets into code or configuration files. Centralizing storage in Azure Key Vault and calling information as needed is the preferred solution.
Deploying Azure Key Vault with Terraform is a clean, repeatable way to manage secure resources. With just a few lines of code, you can automate what would normally take several steps in the Azure Portal.
Conclusion
Terraform Azure Key Vault deployment combines HCL configuration, provider version pinning, resource group provisioning, and access control definition into a reproducible pipeline. The configuration examples show two access models: access policies with granular secret and key permissions, and RBAC with built-in roles for centralized management. Soft delete retention days, purge protection settings, and SKU selection directly influence security posture and cost.
The reference configurations demonstrate provider setup for azurerm, random, and azapi, data source usage for current client context, and key vault resources with soft delete and purge protection enabled. Access policy blocks grant Get, List, Set, Delete for secrets and Get, List, Create, Delete, Update, Import, Backup, Restore, GetRotationPolicy, Recover for keys to the authenticated principal.
For new deployments, RBAC is recommended over access policies. It centralizes access control and integrates with Privileged Identity Management for just-in-time access. Setting up through Terraform ensures consistent security configuration across environments and keeps access policies version-controlled.
Key Vault remains a foundational piece of secure Azure architecture. Reproducible and auditable secrets management, encryption key storage, and certificate lifecycle are achieved from the start when Terraform codifies the key vault, network restrictions, diagnostic logging, and access governance.