Terraform – use Azure KeyVault secrets during deployments

In the second part of my Terraform blog series I explain how to access Azure KeyVault secrets during deployments and how to get your external IP address to refer to in a Network Security Group rule. Happy deploying.

Howdy folks,

in my last article I explained how to configure Terraform so you can use it to securely deploy Azure resources. Today I want to go one step further and provide you some information about how to deploy an Azure VM including all depending resources using Terraform.All code and information is provided in my Azure Security Github repository.


The use case I want to refer to today is pretty simple and still pretty common in lots of scenarios I am involved in. Imagine you want to automatically create Azure resources and you don’t want to have passwords hardcoded in any of your code files. Furthermore, corporate policies may deny to save passwords in template code. Sounds familiar? Read on!

Attention: Make sure to follow the configuration recommendations for a Terraform remote backend from my previous blog post because the KeyVault secret will be stored in the Terraform raw state in plain-text!

A data source is all you need

In the last article I explained how to use an Azure storage account as backend storage for Terraform and how to access the storage account key from an Azure KeyVault every time you need it – only then, and only if you are permitted! Wouldn’t it be nice to use the same Azure KeyVault to store passwords as KeyVault secrets and access them when we need them during deployment? Well, we can. All we need is a Terraform data source

data "azurerm_key_vault_secret" "mySecret" {
name = "labuser"
vault_uri = "https://yourKeyVault.vault.azure.net/"
}

and a reference in the operating system profile section of the deployment config.

os_profile {
computer_name = "myvm"
admin_username = "labuser"
admin_password = "${data.azurerm_key_vault_secret.mySecret.value}"
}

Looks easy? It is!

Get your public IP address and add it to a NSG rule

Now, what about creating a network security group rule that allows management access to that new VM only from the caller’s IP address? This is just as easy as accessing the KeyVault secret, too:

Just create a second data source in the deployment template


data "http" "myExtIP" {
url = "http://ident.me"
}

and refer to it in the respective section when defining the NSG:


security_rule {
name = "SSH"
priority = 1001
direction = "Inbound"
access = "Allow"
protocol = "Tcp"
source_port_range = "*"
destination_port_range = "22"
source_address_prefix = "${data.http.myExtIp.body}" # reference to http data source destination_address_prefix = "*"

Ident.me is a website that displays the caller’s external IP address so you can use it in your automatic deployments.

Conclusion

Within a Terraform template file you can easily refer to data sources and use them in your deployments. They can help to keep your deployment code clean and free from sensitive information. Access to the KeyVault is granted using role-based access control with rights to only the service principal you can create using the preparation script I provide on GitHub.

Happy deploying and bye for now,
Tom

Author: Tom Janetscheck

Cloud Security Enthusiast | Security Advocate

4 thoughts on “Terraform – use Azure KeyVault secrets during deployments”

  1. Be careful here, with the Terrafom data resource “azurerm_key_vault_secret” : “All arguments including the secret value will be stored in the raw state as plain-text.”

    Don”t forget to protect your remote state file location, for storage account use : IAM, Vnet service endpoint and firewall rule.

    Liked by 1 person

  2. Just a note, it looks like the current syntax of calling keyvault is a bit different than in your post here. Guessing that’s a tf .11 to .12 change. Here is what worked for me using tf .12.24:

    # Set up Azure keyvault
    data “azurerm_key_vault” “azkv” {
    name = “yourkeyvaultname”
    resource_group_name = “yourkeyvaultrg”
    }

    data “azurerm_key_vault_secret” “localadmin” {
    name = “localadmin”
    key_vault_id = data.azurerm_key_vault.azkv.id
    }

    # Azure VM Resource
    “azurerm_windows_virtual_machine” “tfvm” {
    […]
    admin_password = data.azurerm_key_vault_secret.localadmin.value
    }

    Liked by 1 person

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: