Managing secrets like passwords or encryption keys is a critical part of deploying and managing a secure infrastructure. Doing it manually is risky and time-consuming and also can be error-prone.
In this blog post, I’ll walk you through how you can automatically generate a secure password, set an expiry date, and then store it safely in Azure Key Vault all via Terraform.
Let’s dive in.
Pre-requisites
Before we start, make sure you have the following:
- Terraform v1.10.0 or later
- Access to an Azure subscription
- An existing Azure Key Vault
- Basic familiarity with Terraform and Azure resources
What we're building
In this blog post we’re going to do the following:
- Generate a secure 20-character password
- Store the password in Azure Key Vault as a secret
- Sets an expiry date on the password when stored within Azure Key Vault
Terraform random module
The Terraform random provider is a handy tool for generating unpredictable values during your infrastructure deployments.
It’s often used to create random strings, passwords, or unique names — which is perfect for when you need something secure or something that is non-repeating.
In this example, we’re going to use the random_password resource to generate a strong 20-character password with a mix of upper-case letters, numbers, and special characters. It’s a simple but effective way to automate credential creation without hardcoding anything sensitive.
Terraform code to generate a secret
Let’s break it down step-by-step. We start by setting the minimum version for the providers to ensure compatibility and stability:
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"
}
time = {
source = "hashicorp/time"
version = "~> 0.9"
}
}
}
We then configure the AzureRM and Azure AzAPI providers:
provider "azapi" {
# Configuration options
}
provider "azurerm" {
features {}
subscription_id = "XXXX-XXXX-XXXX-XXXX"
}
Next we need to start to pull in some useful data about our existing Azure Key Vault which is going to store our generated secret. This helps Terraform understand which Azure Key Vault to use and who the current Azure user is.
data "azurerm_key_vault" "key_vault" {
name = var.key_vault_name
resource_group_name = var.key_vault_rg
}
Next we create the resource, or strong password using the Random module. This will create a random 20-character password that includes special characters, numbers and uppercase letters.
# Generate a random password
resource "random_password" "password" {
length = 20
special = true
upper = true
numeric = true
sensitive = true
}
So the secret doesn’t live forever, we give them a 30-day expiry. This code generates a date 30 days from now in RFC3339 format, perfect for use in Azure Key Vault.
resource "time_offset" "expiry" {
offset_days = 30
}
And lastly we want to store the secret we’ve generated in the Azure Key Vault. This code ensures the secret is stored security, will automatically expire and can be managed centrally in Azure Key Vault.
# Store the generated password in the Key Vault
resource "azurerm_key_vault_secret" "passwordstorage" {
name = "generated-password"
value = random_password.password.result
key_vault_id = data.azurerm_key_vault.key_vault.id
expiration_date = time_offset.expiry.rfc3339
}
I also have a variables.tf file to store some variables with this Terraform code:
##
# Variables
##
variable "key_vault_rg" {
description = "The resource group name of the key vault"
type = string
default = "rg-rk77"
}
variable "key_vault_name" {
description = "The name of the key vault"
type = string
default = "kv-rk77"
}
Best practices
When you are working with secrets within your code it’s important to strike the right balance between automation and security.
Within your Terraform code you want to make sure you mark any sensitive values like generated passwords as sensitive within outputs or variables. This prevents Terraform from accidentally printing them within the CLI output or logs during pipeline runs.
Also, remember that Terraform state files store everything, including secret values. Using a secure remote backend, like an Azure Storage Account with encryption and access controls, is a must to avoid exposing credentials.
Avoid using terraform output to pass secrets to other systems. Instead, ensure applications securely retrieve secrets directly from Azure Key Vault, that’s ultimately what it’s designed for.
Lastly, ensure you define an expiry date for your secrets and keys. In this example, I used a 30-day offset, but it’s important to build in a regular rotation process too. That could mean rerunning Terraform on a schedule or triggering updates via your CI/CD tool.
These small steps can help keep your automation secure, scalable and production-ready.
Wrapping Up
Automating your secret creation and management with Terraform helps to reduce manual effort and improve security.
By generating secure passwords, applying sensible expiry policies and using something like Azure Key Vault to store those passwords in you are building a strong foundation for managing your sensitive data in the cloud.
This is just one example of how infrastructure as code can help build in those secure and repeatable patterns from here you can introduce rotation policies or even integrate with Azure services, happy automation!
Top comments (0)