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.