One area that always need focus is around security and managing credentials. Using Terraform, and the method in this blog post, you can help build Azure Key Vault and create a secure secret to use when creating VMs, automatically.
To keep things secure, my method uses a combination of randomised password values, and Azure Key Vault. This post explains how to automate the creation of both of these, and use the Secret when setting up a Virtual Machine.
This code is also available in my GitHub repo: Terraform-Azure/Azure-KeyVault-with-Secret
The code does 4 main things to set this up:
- Creates a random string with a prefix using the hashicorp/random provider for the Key Vault name.
- Creates an Azure Key Vault with the randomised name – so that multiple people can deploy the environment and all get a different, unique, Key Vault Name. Permissions for Secret are set here too.
- Creates a random string using the hashicorp/random_password provider for the Virtual Machine password.
- Creates a Secret within the Key Vault called “vmpassword” using the generated password. This means that every deployment also has a different, unique password – just like the Key Vault name.
Creating a random string, and then creating an Azure Key Vault:
This creates a random string with a prefix, so the output is keyvault##########. It then uses this value to create a Key Vault. Secret Permissions are also set within the Key Vault creation – so if you require any other permissions set here these will need to be added.
#Create KeyVault ID
resource "random_id" "kvname" {
byte_length = 5
prefix = "keyvault"
}
#Keyvault Creation
data "azurerm_client_config" "current" {}
resource "azurerm_key_vault" "kv1" {
depends_on = [ azurerm_resource_group.rg2 ]
name = random_id.kvname.hex
location = var.loc1
resource_group_name = var.azure-rg-2
enabled_for_disk_encryption = true
tenant_id = data.azurerm_client_config.current.tenant_id
soft_delete_retention_days = 7
purge_protection_enabled = false
sku_name = "standard"
access_policy {
tenant_id = data.azurerm_client_config.current.tenant_id
object_id = data.azurerm_client_config.current.object_id
key_permissions = [
"get",
]
secret_permissions = [
"get", "backup", "delete", "list", "purge", "recover", "restore", "set",
]
storage_permissions = [
"get",
]
}
}
Note that if you need to use this Key Vault throughout your code, you can reference the random string result using: random_string.kvname.result
Creating a random password, and then creating a Secret within our Azure Key Vault:
#Create KeyVault VM password
resource "random_password" "vmpassword" {
length = 20
special = true
}
#Create Key Vault Secret
resource "azurerm_key_vault_secret" "vmpassword" {
name = "vmpassword"
value = random_password.vmpassword.result
key_vault_id = azurerm_key_vault.kv1.id
depends_on = [ azurerm_key_vault.kv1 ]
}
Using the Secret when creating a Virtual Machine:
#Create VM
resource "azurerm_windows_virtual_machine" "dc01-vm" {
name = "dc01-vm"
depends_on = [ azurerm_key_vault.kv1 ]
resource_group_name = azurerm_resource_group.rg2.name
location = var.loc1
size = var.vmsize-domaincontroller
admin_username = var.adminusername
admin_password = azurerm_key_vault_secret.vmpassword.value
network_interface_ids = [
azurerm_network_interface.dc01-nic.id,
]
os_disk {
caching = "ReadWrite"
storage_account_type = "StandardSSD_LRS"
}
source_image_reference {
publisher = "MicrosoftWindowsServer"
offer = "WindowsServer"
sku = "2019-Datacenter"
version = "latest"
}
}
We can then access the Secret via the created Key Vault:

We can use the “Show Secret Value” option, or just copy it to the Clipboard:

I hope this has been useful! 😀 Please also check out best practises around storing/working with sensitive data in Terraform state files, as the generated value will be inside the state file.