DevOps Blog - Nicolas Paris

Azure Compute Engine Workstation Cost reduced with Terraform

AzureTerraformFinOps

This is very similar to the GCP version post but for Azure. I'm using azure for windows compute engine because of the Windows 10 licence. GCP has only the Windows Datacenter licence, which is more expensive. I wont discuss about the interest of such a configuration, if you're interrest check this post it's for Google Cloud Platform and for a linux VM but it's the same idea.

You're paying GPU and RAM only when the computer is running, but persistent storage, or osDisk like they call it in Azure cost some money all the time, that can come expensive in the case of a SSD.

The idea is to make a snapshot, cheapest storage and only the real space needed, and create a virtual computer with terraform in one command line. Make a .tf file, execute in the cloud shell with the already installed terraform.

In my case, I have 2 disks, OS and data. let's make a workstation.tf. It's more verbose than the GCP, but it's works.

Improvment can be done with variable of course.

variable "prefix" {
default = "tfvmex"
}

resource "azurerm_virtual_network" "main" {
name = "${var.prefix}-network"
address_space = ["10.0.0.0/16"]
location = "northeurope"
resource_group_name = "nsirap"
}

resource "azurerm_subnet" "internal" {
name = "internal"
resource_group_name = "nsirap"
virtual_network_name = "${azurerm_virtual_network.main.name}"
address_prefix = "10.0.2.0/24"
}

resource "azurerm_public_ip" "example" {
name = "test-pip"
location = "northeurope"
resource_group_name = "nsirap"
allocation_method = "Dynamic"
idle_timeout_in_minutes = 30
}

resource "azurerm_network_interface" "main" {
name = "${var.prefix}-nic"
location = "northeurope"
resource_group_name = "nsirap"

ip_configuration {
name = "testconfiguration1"
subnet_id = "${azurerm_subnet.internal.id}"
private_ip_address_allocation = "Dynamic"
public_ip_address_id = "${azurerm_public_ip.example.id}"
}
}

resource "azurerm_managed_disk" "copy" {
name = "win-home2"
location = "northeurope"
resource_group_name = "nsirap"
storage_account_type = "Premium_LRS"
create_option = "Copy"
source_resource_id = "/subscriptions/14ff37b9-ce04-4a1/resourceGroups/nsirap/providers/Microsoft.Compute/snapshots/win-home"
disk_size_gb = "128"
}

data "azurerm_managed_disk" "photo" {
name = "photo"
resource_group_name = "nsirap"
}

resource "azurerm_virtual_machine" "windows-workstation" {
name = "windows-workstation"
location = "North Europe"
resource_group_name = "nsirap"
vm_size = "Standard_D4s_v3"
network_interface_ids = ["${azurerm_network_interface.main.id}"]

storage_os_disk {
name = "win-home2"
os_type = "windows"
managed_disk_id = "${azurerm_managed_disk.copy.id}"
create_option = "Attach"
}
storage_data_disk {
name = "${data.azurerm_managed_disk.photo.name}"
managed_disk_id = "${data.azurerm_managed_disk.photo.id}"
create_option = "Attach"
lun = 0
disk_size_gb = "${data.azurerm_managed_disk.photo.disk_size_gb}"
}

}

To execute, run terraform init the first time, then terraform apply. To delete every thing use terraform destroy.

Once I done some OS changes, I save a snapshot like this

az snapshot create -g nsirap -n win-home --sku Standard_LRS --source win-home2 --location northeurope

With this, you instanciate an expensive SSD premium that you pay only when the computer is up, and store in a cheap efficient storage once is down. The instantiation can take a minute or two. It's up to you to estimate if this extra minute worth the effort, and the cost saving.

update 04-2022: this was a FinOps oriented post might be before I knew what FinOps was. I wrote an Introduction to FinOps that might give you furthur advices to reduce cost bill.