How to deploy Azure Key Vault with Terraform: A Step-by-Step Guide

Learn how to deploy Azure Key Vault using Terraform with clear steps, code walkthrough, and best practices for secure setup.

How to deploy Azure Key Vault with Terraform: A Step-by-Step Guide
How to deploy Azure Key Vault with Terraform: A Step-by-Step Guide

Managing secrets, certificates, and keys securely is a critical part of any cloud infrastructure. Azure Key Vault is Microsoft’s go-to solution for secure key management, and in this blog, we’ll walk through how to deploy it using Terraform.

We'll break down the Terraform configuration so that even if you’re new to deploying Azure services as code, you’ll be able to follow along with confidence.

Pre-requisites

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)

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.

What we'll deploy

This 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

The Terraform configuration explained

1. Setting up Terraform and providers

We start 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 "azapi" {
  # Configuration options
}

provider "azurerm" {
  features {}
  subscription_id = "XXXX-XXXX-XXXX-XXXX"
}

We're using:

  • azurerm to deploy Azure resources
  • random to randomly select a region
  • azapi to support the modules we are using

You must configure the providers with your Azure subscription details. The subscription_id in the azurerm provider should be updated with your actual ID.

2. Naming and region selection
We use a community module to generate Azure Cloud Adoption Framework (CAF) compliant resource names:

module "naming" {
  source  = "Azure/naming/azurerm"
  version = "0.3.0"
}

We also define a list of Azure regions and randomly pick one for deployment:

locals {
  azure_regions = [
    "ukwest",
    "westeurope",
    "francecentral",
    "swedencentral"
  ]
}

resource "random_integer" "region_index" {
  max = length(local.azure_regions) - 1
  min = 0
}

This gives us a bit of variability in testing deployments across regions.

3. Creating the resource group

resource "azurerm_resource_group" "rg" {
  location = local.azure_regions[random_integer.region_index.result]
  name     = module.naming.resource_group.name_unique

  tags = {
    Environment = var.tag_environment
    Project     = var.tag_project
    Creator     = var.tag_creator
  }
}

We create the Azure resource group and also assign some basic tags using variables to help keep things organised.

4. Deploying the Azure Key Vault

Here’s the core of the deployment:

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

We enable soft delete and purge protection, both best practices for protecting against accidental deletion.

Next, we configure access policies:

 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.

Variables file

We keep the variables in a separate file from our main Terraform deployment.  And in this file we set our tag information.

variable "tag_environment" {
  type    = string
  default = "Testing"
}

variable "tag_project" {
  type    = string
  default = "KeyVault"
}

variable "tag_creator" {
  type    = string
  default = "TechieLass"
}

These can be overridden at deployment time or left as-is for testing.

How to deploy

Once your Terraform configuration files are ready, open a terminal and navigate to the directory containing them.

Make sure you're authenticated to Azure. The simplest way is by using the Azure CLI. You can do this by running:

az login

This opens a browser window where you can log in with your Azure credentials. If you're using a service principal instead, you can authenticate with:

az login --service-principal -u <app-id> -p <password-or-cert> --tenant <tenant-id>

After authenticating, run:

terraform init

This will download the necessary provider plugins and initialise the working directory.

Next, run the command:

terraform plan

This will give you a preview of what resource will be created. This helps you confirm the configuration looks correct.

When you're ready, deploy the infrastructure with the command:

terraform apply

You’ll be prompted to confirm the action—type yes to proceed.

Terraform deployment workflow
Terraform deployment workflow

After deployment, log in to the Azure Portal to confirm the resource group and Key Vault were created successfully. You can also verify that the access policy has been applied by reviewing your permissions in the Key Vault settings.

Wrapping Up

Deploying Azure Key Vault with Terraform is a clean, repeatable way to manage your secure resources. With just a few lines of code, you can automate what would normally take several steps in the Azure Portal.