Skip to content

CLZ-190 - Windows VM Basics

Windows VM Basics architecture
Service or workflow illustration. The lesson defines the exact resource settings. Open at full size.

Goal

Deploy the first Windows Server 2022 Azure Edition VM and understand the NIC, subnet, NSG, public IP, disk, image, size, and generated-credential relationships.

CLZ-190 learning sequence
Arrows show the learning sequence, not service traffic. Azure deployment. Open at full size.

Prerequisites

  • Complete CLZ-180.
  • Available regional vCPU quota for the chosen vm_size.
  • A current administrator IPv4 /32 for this deliberately direct-access lesson.

Architecture

CLZ-190 — A Windows VM's public IP, scoped NIC NSG, private NIC, OS disk, and generated password dependencies; no IIS is deployed.
Lesson-specific teaching diagram. Read the arrow legend and the accompanying architecture explanation. Azure deployment. On narrow screens, scroll the diagram horizontally. Open at full size.

A Windows VM attaches to a NIC in the protected web subnet. A Standard public IP gives the introductory VM inbound and outbound connectivity. Terraform generates the administrator password and stores it in state as a sensitive value.

Resources And Cost

Relative cost: Moderate. The VM size and running hours dominate; managed disk and Standard public IPv4 also incur charges.

Component Purpose and principal cost driver
Windows virtual machine Compute charged while allocated; default Azure Edition image uses latest intentionally.
OS disk Managed storage billed by provisioned tier.
NIC and Standard public IP Network attachment and intentional introductory public access.
VNet, subnets, and NSG Web subnet allows only the documented ports and scoped RDP source.

Inputs

Input Required substitution or decision
subscription_id Required for plan, apply, and destroy; use the exact subscription GUID.
environment Keep dev for an ephemeral lab unless testing an environment boundary.
location Select a supported region with adequate quota.
name_prefix Use a short lowercase prefix for derived names.
admin_username Choose a nonreserved Windows administrator name.
admin_cidr Required: your current public IPv4 /32; broad RDP sources fail validation.
vm_size Choose a small available size that fits regional quota.

Keep real subscription IDs, CIDRs, and secrets in untracked terraform.tfvars or environment variables.

The CIDR validation verifies IPv4 /32 syntax, not public routability. Confirm that the value is your actual current public administrator address.

Deploy

Review the plan and lesson-specific gates before deliberate execution. Local-only and read-only lessons create no Azure resources.
Review the plan and lesson-specific gates before deliberate execution. Local-only and read-only lessons create no Azure resources. Open at full size.

Run from the repository root in PowerShell 7:

Set-Location CLZ-190-windows-vm-basics
if (-not (Test-Path terraform.tfvars)) {
  Copy-Item terraform.tfvars.example terraform.tfvars
}
$subscriptionId = az account show --query id --output tsv
terraform init -lockfile=readonly
terraform fmt -check
terraform validate
terraform plan -var "subscription_id=$subscriptionId" -out tfplan
terraform show tfplan
terraform apply tfplan

Validate

$resourceGroup = terraform output -raw resource_group_name
$publicIp = terraform output -raw windows_vm_public_ip
az vm list --resource-group $resourceGroup --show-details --query '[].{name:name,powerState:powerState,privateIp:privateIps,publicIp:publicIps,size:hardwareProfile.vmSize}' --output table
Test-NetConnection $publicIp -Port 3389

Expected result:

  • Azure reports one VM in VM running state with private and public addresses.
  • TCP 3389 succeeds only from the configured administrator source.
  • The sensitive password is not printed by ordinary terraform output.

Troubleshooting

Gather evidence, repair the cause, and rerun verification.
Gather evidence, repair the cause, and rerun verification. Open at full size.
Symptom Resolution
The size is unavailable or quota is exceeded Select another small vm_size or an approved region after checking CLZ-110.
RDP times out Confirm the current public IP still matches admin_cidr, the VM is running, and local egress permits 3389.
The password is needed for the lab Use terraform output -raw windows_admin_password only in a private terminal; never paste it into logs.

Cleanup

Use the lesson state and cleanup instructions. Preserve remote-state dependencies until consumers are removed.
Use the lesson state and cleanup instructions. Preserve remote-state dependencies until consumers are removed. Open at full size.
$resourceGroup = terraform output -raw resource_group_name
terraform destroy -var "subscription_id=$subscriptionId"
terraform state list
az group exists --name $resourceGroup

The VM, disk, public IP, network, password state, and resource group are gone; Azure CLI returns false.

Production Delta

  • Intentional teaching exception: remove the VM public IP and use Bastion/private connectivity.
  • Use managed identities, hardened images, patch orchestration, backup, endpoint protection, disk encryption requirements, and secret rotation.

Exercises

  1. Change vm_size and identify whether Azure proposes an in-place resize or replacement.
  2. List every resource address that exists only because a VM needs network and credential dependencies.

← CLZ-180 - Network Security Groups | Curriculum | CLZ-200 - Windows VM IIS Bootstrap →