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 = ""

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 = ""

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 = "*" is a website that displays the caller’s external IP address so you can use it in your automatic deployments.


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,

48.127809 11.612734

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.