Cloud Block Store Use Cases for Microsoft Azure - Terraform Edition
Previously I explained how to use Terraform to Deploy an Azure VM. Now that Cloud Block Store iS GA in Azure, I can cover how to use Automation for Test/Dev, Disaster Recovery and Migration use cases to move workloads from on-premises to Microsoft Azure!
Overview
When it comes to automating deployments, its great to be able to use the same automation tool across clouds. This blog will focus on how to migrate windows based machines from on-premises to Microsoft Azure. We will utilize Terraform to automate provisioning. Utilizing previous powershell scripts to configure iSCSI will simplify and automate some of these use cases.
Pre-Requisites
- This is used to authenticate to Azure to deploy the VM via Terraform.
- This is used to automate the provisioning using a Terraform .TF file.
- This is the infrastructure to run the Azure virtual machines.
Terraform Manifest Configuration
Download the sample manifest from GitHub and update the variables for your environment. This includes the Azure Resource Group, Virtual Network, Subnet and Interface. You will also need to update the Azure VM’s hostname, admin username and password as well as any of fields you wish.
1provider "azurerm" {
2 features {}
3}
4
5data "azurerm_resource_group" "resourcegroup" {
6 name = "Azure-ResourceGroup"
7}
8
9data "azurerm_virtual_network" "virtualnetwork" {
10 name = "Azure-VirtualNetwork"
11 resource_group_name = data.azurerm_resource_group.resourcegroup.name
12}
13
14data "azurerm_subnet" "subnet" {
15 name = "Azure-Subnet"
16 resource_group_name = data.azurerm_resource_group.resourcegroup.name
17 virtual_network_name = data.azurerm_virtual_network.virtualnetwork.name
18}
19
20resource "azurerm_network_interface" "networkinterface" {
21 name = "Azure-NetworkInterface"
22 location = data.azurerm_resource_group.resourcegroup.location
23 resource_group_name = data.azurerm_resource_group.resourcegroup.name
24 ip_configuration {
25 name = "Azure-IP"
26 subnet_id = data.azurerm_subnet.subnet.id
27 private_ip_address_allocation = "Dynamic"
28 }
29}
30
31resource "azurerm_windows_virtual_machine" "avm" {
32 name = "DS-TERRAFORM"
33 resource_group_name = data.azurerm_resource_group.resourcegroup.name
34 location = data.azurerm_resource_group.resourcegroup.location
35 computer_name = "hostname"
36 admin_username = "terraform"
37 admin_password = "Password1!"
38 size = "Standard_B1s"
39 network_interface_ids = [
40 azurerm_network_interface.networkinterface.id,
41 ]
42 os_disk {
43 caching = "ReadWrite"
44 storage_account_type = "Standard_LRS"
45 }
46 source_image_reference {
47 publisher = "MicrosoftWindowsServer"
48 offer = "WindowsServer"
49 sku = "2019-Datacenter"
50 version = "latest"
51 }
52}
53
54resource "azurerm_virtual_machine_extension" "customize" {
55 name = "customize"
56 virtual_machine_id = azurerm_windows_virtual_machine.avm.id
57 publisher = "Microsoft.Compute"
58 type = "CustomScriptExtension"
59 type_handler_version = "1.9"
60 protected_settings = <<PROTECTED_SETTINGS
61
62 protected_settings = <<PROTECTED_SETTINGS
63 {
64 "commandToExecute": "powershell.exe -Command \"./chocolatey.ps1; exit 0;\""
65 }
66 PROTECTED_SETTINGS
67
68 settings = <<SETTINGS
69 {
70 "fileUris": [
71 "https://gist.githubusercontent.com/mcasperson/c815ac880df481418ff2e199ea1d0a46/raw/5d4fc583b28ecb27807d8ba90ec5f636387b00a3/chocolatey.ps1"
72 ]
73 }
74 SETTINGS
75}
Update the Terraform Manifest for Your Environment
This file is a standard deployment of an azure virtual machine. The best part about it is that you can utilize Azure customization to run a script once the machine is deployed.
To customize the Azure VM you’ll need to update the customize resource. You can either have it run a local file, or in my case it pulls down the script from a GIST. In an enterprise environment this can be a local server or repository.
1resource "azurerm_virtual_machine_extension" "customize" {
2 name = "customize"
3 virtual_machine_id = azurerm_windows_virtual_machine.avm.id
4 publisher = "Microsoft.Compute"
5 type = "CustomScriptExtension"
6 type_handler_version = "1.9"
7 protected_settings = <<PROTECTED_SETTINGS
8 protected_settings = <<PROTECTED_SETTINGS
9 {
10 "commandToExecute": "powershell.exe -Command \"./ConfigureAzureCBS-DR.ps1; exit 0;\""
11 }
12 PROTECTED_SETTINGS
13
14 settings = <<SETTINGS
15 {
16 "fileUris": [
17 "https://gist.githubusercontent.com/dstamen/e021dcc181c30a9fc5af2d33deafff3f/raw/56b568a9e1183bc5920a344eb51b8a90690fd620/ConfigureAzureCBS-DR.ps1"
18 ]
19 }
20 SETTINGS
Scripted Use Cases
THe following script is a standard PowerShell script that will do the following for a Windows based Azure Virtual Machine.
- Install PowerShell Pre-Requistives and the PureStoragePowershellSDK
- Set iSCSI Service to Startup Automatically
- Set a Custom iSCSI IQN (this allows the host to be pre-configured on CBS)
- Configure iSCSI to talk to the CBS Array and Connect initiators
- Login to the flasharray and will overwrite the CBS volume with the latest replicated snapshot. It will then online the disk within windows.
1#Install Pure Powershell Module
2Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Force
3Install-Module PureStoragePowershellSDK -Confirm:$false -Force
4
5#Enable ISCSI
6Set-Service -Name msiscsi -StartupType Automatic
7Start-Service -Name msiscsi
8
9#Confgure Static Initiator Name
10Set-InitiatorPort -NodeAddress (Get-InitiatorPort).NodeAddress -NewNodeAddress "iqn.1991-05.com.ds-terraform"
11
12#Configure ISCSI to CBS
13$iscsitarget = "172.29.0.6"
14if ((Get-IscsiTargetPortal).TargetPortalAddress -notcontains $iscsitarget){
15 New-IscsiTargetPortal -TargetPortalAddress $iscsitarget
16 Get-IscsiTarget | Connect-IscsiTarget -InitiatorPortalAddress (Get-NetIPAddress |Where-Object {$_.InterfaceAlias -like "Ethernet" -and $_.AddressFamily -like "IPv4"}).IPAddress -IsMultipathEnabled $true -IsPersistent $true -TargetPortalAddress $iscsitarget
17}
18
19#Create Volume from Latest Snap and Online Disk
20$arrayendpoint = "IP-of-CBS"
21$srcprotectiongroup = "arrayname:pgname"
22$destvolumename = "destvolumename"
23$srcvolumename = "sourcevolumename"
24$pureuser = "pureuser"
25$purepass = ConvertTo-SecureString "MYPASSWORD" -AsPlainText -Force
26$purecred = New-Object System.Management.Automation.PSCredential -ArgumentList ($pureuser, $purepass)
27
28# Connect to and set the active Pure Storage FlashArray
29$array = New-PfaArray -endpoint $arrayendpoint -credentials $purecred -ignoreCertificateError
30
31#Get Most Recent Completed Snapshot
32Write-Host "Obtaining the most recent snapshot for the protection group..." -ForegroundColor Red
33$MostRecentSnapshots = Get-PfaProtectionGroupSnapshots -Array $array -Name $srcprotectiongroup | Sort-Object created -Descending | Select-Object -Property name -First 2
34
35# Check that the last snapshot has been fully replicated
36$FirstSnapStatus = Get-PfaProtectionGroupSnapshotReplicationStatus -Array $array -Name $MostRecentSnapshots[0].name
37
38# If the latest snapshot's completed property is null, then it hasn't been fully replicated - the previous snapshot is good, though
39if ($null -ne $FirstSnapStatus.completed) {
40 $MostRecentSnapshot = $MostRecentSnapshots[0].name
41}
42else {
43 $MostRecentSnapshot = $MostRecentSnapshots[1].name
44}
45
46# Perform the DR volume overwrite
47Write-Host "Overwriting the volume with a copy of the most recent snapshot..." -ForegroundColor Red
48New-PfaVolume -Array $array -VolumeName $destvolumename -Source ($MostRecentSnapshot + '.' + $srcvolumename) -Overwrite | Out-Null
49
50# Online the volume
51Write-Host "Onlining the volume..." -ForegroundColor Red
52Get-Disk | Where-Object {$_.OperationalStatus -eq "Offline"} | Set-Disk -IsOffline $false
This use case can be utilized for Test/Dev and/or Disaster Recovery. It utilizes a default Azure Machine template, but this can be customized for your liking. Remember any configuration here is done via powershell so truly the options are endless.
Deploy your Azure VM
Unlike with other Terraform providers where you specify login credentials in the manifest, Azure is a bit different. There are 4 options and the easiest is to authenticate using Azure CLI
To login just run the below command. It will open a web browser and you’ll authenticate.
1az login
Once authenticated, you can run your Terraform deployment.
Run terraform init to install any needed providers, terraform plan to make sure all the connectivity is working and then terraform apply to deploy!
1terraform init
2terraform plan
3terraform apply
If everything is successful your Azure Virtual Machine instance should be deployed in ~5minutes!
Conclusion
Im loving how flexible it is to take advantage of Pure Storage in the Cloud! Using Cloud Block Store, it can be utilized for Migration, Test/Dev, Disaster Recovery as well as Public/Hybrid/Multi Cloud.
If you have any additional questions or comments, please leave them below!
comments powered by DisqusSee Also
- Deploying a Windows Azure VM with Hashicorp Terraform to Microsoft Azure
- Using the Pure Storage Cloud Block Store Terraform Provider for AWS
- Deploying a Linux EC2 Instance with Hashicorp Terraform and Vault to AWS and Connect to Pure Cloud Block Store
- Deploying a Windows EC2 Instance with Hashicorp Terraform and Vault to AWS
- Deploying a EC2 Instance with PowerShell to AWS