Criar VM Windows com Terraform
Azure Virtual Machine
Avançado
30 min
Gratuito
📋 Visão Geral
Neste workshop você aprenderá a provisionar uma máquina virtual Windows Server completa usando Terraform — a ferramenta de Infrastructure as Code (IaC) mais popular do mercado.
Você irá criar toda a infraestrutura declarativamente:
- Resource Group
- Virtual Network (VNet) com Subnet
- Network Security Group (NSG) com regras para RDP e HTTP
- Public IP Address
- Network Interface (NIC)
- Storage Account para Boot Diagnostics
- Windows VM com extensão IIS
💡 Dica: Terraform permite versionar, revisar e reproduzir infraestrutura. É uma skill essencial para certificações como AZ-104 e AZ-400.
✅ Pré-requisitos
Antes de começar, certifique-se de ter:
- Uma subscrição Azure ativa
- Terraform instalado (download) — versão 1.0+
- Azure CLI instalado e autenticado
- Um editor de código (VS Code recomendado com extensão Terraform)
⚠️ Importante: Este workshop pode gerar custos na sua subscrição Azure. Lembre-se de executar
terraform destroy ao final.
🚀 Configuração do Ambiente
Prepare o ambiente e crie a estrutura do projeto Terraform:
1. Autenticar no Azure
az login
2. Criar diretório do projeto
mkdir terraform-vm-lab cd terraform-vm-lab
3. Criar arquivo providers.tf
Este arquivo define os providers necessários (azurerm e random):
terraform {
required_version = ">=1.0"
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "~>3.0"
}
random = {
source = "hashicorp/random"
version = "~>3.0"
}
}
}
provider "azurerm" {
features {}
}
⚙️ Implementação
Crie os arquivos Terraform para toda a infraestrutura:
Passo 1: Criar variables.tf
variable "resource_group_location" {
type = string
default = "eastus"
description = "Location of the resource group."
}
variable "resource_group_name_prefix" {
type = string
default = "rg"
description = "Prefix for the resource group name."
}
variable "admin_username" {
type = string
default = "azureuser"
description = "The admin username for the VM."
}
variable "admin_password" {
type = string
sensitive = true
description = "The admin password for the VM."
}
Passo 2: Criar main.tf — Infraestrutura Completa
Este é o arquivo principal com todos os recursos:
# Resource Group
resource "random_pet" "rg_name" {
prefix = var.resource_group_name_prefix
}
resource "azurerm_resource_group" "rg" {
location = var.resource_group_location
name = random_pet.rg_name.id
}
# Virtual Network
resource "azurerm_virtual_network" "my_vnet" {
name = "myVnet"
address_space = ["10.0.0.0/16"]
location = azurerm_resource_group.rg.location
resource_group_name = azurerm_resource_group.rg.name
}
# Subnet
resource "azurerm_subnet" "my_subnet" {
name = "mySubnet"
resource_group_name = azurerm_resource_group.rg.name
virtual_network_name = azurerm_virtual_network.my_vnet.name
address_prefixes = ["10.0.1.0/24"]
}
# Public IP
resource "azurerm_public_ip" "my_public_ip" {
name = "myPublicIP"
location = azurerm_resource_group.rg.location
resource_group_name = azurerm_resource_group.rg.name
allocation_method = "Dynamic"
}
# Network Security Group
resource "azurerm_network_security_group" "my_nsg" {
name = "myNSG"
location = azurerm_resource_group.rg.location
resource_group_name = azurerm_resource_group.rg.name
security_rule {
name = "RDP"
priority = 1000
direction = "Inbound"
access = "Allow"
protocol = "*"
source_port_range = "*"
destination_port_range = "3389"
source_address_prefix = "*"
destination_address_prefix = "*"
}
security_rule {
name = "web"
priority = 1001
direction = "Inbound"
access = "Allow"
protocol = "Tcp"
source_port_range = "*"
destination_port_range = "80"
source_address_prefix = "*"
destination_address_prefix = "*"
}
}
# Network Interface
resource "azurerm_network_interface" "my_nic" {
name = "myNIC"
location = azurerm_resource_group.rg.location
resource_group_name = azurerm_resource_group.rg.name
ip_configuration {
name = "my_nic_configuration"
subnet_id = azurerm_subnet.my_subnet.id
private_ip_address_allocation = "Dynamic"
public_ip_address_id = azurerm_public_ip.my_public_ip.id
}
}
# Connect NSG to NIC
resource "azurerm_network_interface_security_group_association" "example" {
network_interface_id = azurerm_network_interface.my_nic.id
network_security_group_id = azurerm_network_security_group.my_nsg.id
}
# Storage Account for Boot Diagnostics
resource "random_id" "random_id" {
keepers = {
resource_group = azurerm_resource_group.rg.name
}
byte_length = 8
}
resource "azurerm_storage_account" "my_storage" {
name = "diag${random_id.random_id.hex}"
location = azurerm_resource_group.rg.location
resource_group_name = azurerm_resource_group.rg.name
account_tier = "Standard"
account_replication_type = "LRS"
}
# Windows Virtual Machine
resource "azurerm_windows_virtual_machine" "main" {
name = "myVM"
admin_username = var.admin_username
admin_password = var.admin_password
location = azurerm_resource_group.rg.location
resource_group_name = azurerm_resource_group.rg.name
network_interface_ids = [azurerm_network_interface.my_nic.id]
size = "Standard_DS1_v2"
os_disk {
name = "myOsDisk"
caching = "ReadWrite"
storage_account_type = "Premium_LRS"
}
source_image_reference {
publisher = "MicrosoftWindowsServer"
offer = "WindowsServer"
sku = "2022-datacenter-azure-edition"
version = "latest"
}
boot_diagnostics {
storage_account_uri = azurerm_storage_account.my_storage.primary_blob_endpoint
}
}
# Install IIS via VM Extension
resource "azurerm_virtual_machine_extension" "web_server_install" {
name = "wsi"
virtual_machine_id = azurerm_windows_virtual_machine.main.id
publisher = "Microsoft.Compute"
type = "CustomScriptExtension"
type_handler_version = "1.8"
auto_upgrade_minor_version = true
settings = <<SETTINGS
{
"commandToExecute": "powershell -ExecutionPolicy Unrestricted Install-WindowsFeature -name Web-Server -IncludeManagementTools;"
}
SETTINGS
}
📝 Nota: O arquivo main.tf cria 10 recursos Azure interconectados: Resource Group, VNet, Subnet, Public IP, NSG (com regras RDP + HTTP), NIC, associação NSG-NIC, Storage Account, VM e extensão IIS.
Passo 3: Criar outputs.tf
output "resource_group_name" {
value = azurerm_resource_group.rg.name
}
output "public_ip_address" {
value = azurerm_windows_virtual_machine.main.public_ip_address
}
Passo 4: Inicializar e Executar Terraform
# Inicializar o Terraform (baixar providers) terraform init -upgrade # Criar o plano de execução terraform plan -out main.tfplan # Aplicar o plano (criar os recursos) terraform apply main.tfplan
📝 Nota: Você será solicitado a fornecer a
admin_password durante o plan/apply. O deployment completo leva de 5 a 10 minutos.
✅ Validação
Verifique se toda a infraestrutura foi provisionada corretamente:
1. Verificar outputs do Terraform
# Ver o nome do resource group criado terraform output resource_group_name # Ver o IP público da VM terraform output public_ip_address
2. Verificar recursos no Azure
# Listar recursos no resource group az resource list \ --resource-group $(terraform output -raw resource_group_name) \ --output table
3. Testar o IIS no navegador
Acesse o IP público retornado pelo output:
http://<PUBLIC_IP_ADDRESS>
🎉 Parabéns! Se a página do IIS aparecer, você provisionou toda uma infraestrutura Azure como código usando Terraform — VNet, Subnet, NSG, NIC, Storage, VM e IIS!
🧹 Limpeza
Use o Terraform para destruir todos os recursos de forma limpa:
# Criar plano de destruição terraform plan -destroy -out main.destroy.tfplan # Executar a destruição terraform apply main.destroy.tfplan
⚠️ Atenção: O
terraform destroy removerá todos os 10 recursos criados (Resource Group, VNet, Subnet, IP, NSG, NIC, Storage, VM, extensão). A operação é irreversível.