- Published on
用 Terraform 開一個 Azure VM
前言
在上一篇文章中,我們介紹了如何用 Terraform 開一個 NGINX,這篇文章我們要介紹如何用 Terraform 開一個 Azure VM。
Terraform 前置作業
安裝 Terraform。
在此網站中,我們可以找到 Terraform 的安裝檔,Windows 請下載 386 版本。
安裝 Azure CLI。
安裝 Azure CLI 是為了讓 Terraform 能夠連接到 Azure。
在此網站中,我們可以找到 Azure CLI 的安裝方式。 其實只要在 Windows 的命令提示字元中輸入以下指令,就可以安裝 Azure CLI。
winget install -e --id Microsoft.AzureCLI輸入以下指令,確認 Azure CLI 是否安裝成功。
az --version
撰寫 Terraform 檔案。
建立一個資料夾。
在這個資料夾中,我們會放置 Terraform 的檔案。
建立一些 .tf 檔案。
可以參考Azure 官網的範例。
在 main.tf 裡面,admin_password 是隨機亂數,你不會知道密碼是什麼,若要使用密碼登入主機,請先把admin_password改掉。
main.tf
resource "azurerm_resource_group" "rg" {
location = var.resource_group_location
name = "${random_pet.prefix.id}-rg"
}
# Create virtual network
resource "azurerm_virtual_network" "my_terraform_network" {
name = "${random_pet.prefix.id}-vnet"
address_space = ["10.0.0.0/16"]
location = azurerm_resource_group.rg.location
resource_group_name = azurerm_resource_group.rg.name
}
# Create subnet
resource "azurerm_subnet" "my_terraform_subnet" {
name = "${random_pet.prefix.id}-subnet"
resource_group_name = azurerm_resource_group.rg.name
virtual_network_name = azurerm_virtual_network.my_terraform_network.name
address_prefixes = ["10.0.1.0/24"]
}
# Create public IPs
resource "azurerm_public_ip" "my_terraform_public_ip" {
name = "${random_pet.prefix.id}-public-ip"
location = azurerm_resource_group.rg.location
resource_group_name = azurerm_resource_group.rg.name
allocation_method = "Dynamic"
}
# Create Network Security Group and rules
resource "azurerm_network_security_group" "my_terraform_nsg" {
name = "${random_pet.prefix.id}-nsg"
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 = "*"
}
}
# Create network interface
resource "azurerm_network_interface" "my_terraform_nic" {
name = "${random_pet.prefix.id}-nic"
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_terraform_subnet.id
private_ip_address_allocation = "Dynamic"
public_ip_address_id = azurerm_public_ip.my_terraform_public_ip.id
}
}
# Connect the security group to the network interface
resource "azurerm_network_interface_security_group_association" "example" {
network_interface_id = azurerm_network_interface.my_terraform_nic.id
network_security_group_id = azurerm_network_security_group.my_terraform_nsg.id
}
# Create storage account for boot diagnostics
resource "azurerm_storage_account" "my_storage_account" {
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"
}
# Create virtual machine
resource "azurerm_windows_virtual_machine" "main" {
name = "${var.prefix}-vm"
admin_username = "azureuser"
admin_password = random_password.password.result
location = azurerm_resource_group.rg.location
resource_group_name = azurerm_resource_group.rg.name
network_interface_ids = [azurerm_network_interface.my_terraform_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_account.primary_blob_endpoint
}
}
# Install IIS web server to the virtual machine
resource "azurerm_virtual_machine_extension" "web_server_install" {
name = "${random_pet.prefix.id}-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 -IncludeAllSubFeature -IncludeManagementTools"
}
SETTINGS
}
# Generate random text for a unique storage account name
resource "random_id" "random_id" {
keepers = {
# Generate a new ID only when a new resource group is defined
resource_group = azurerm_resource_group.rg.name
}
byte_length = 8
}
resource "random_password" "password" {
length = 20
min_lower = 1
min_upper = 1
min_numeric = 1
min_special = 1
special = true
}
resource "random_pet" "prefix" {
prefix = var.prefix
length = 1
}
provider.tf
terraform {
required_version = ">=1.0"
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "~>3.0"
}
random = {
source = "hashicorp/random"
version = "~>3.0"
}
}
}
provider "azurerm" {
features {}
}
variables.tf
variable "resource_group_location" {
default = "eastus"
description = "Location of the resource group."
}
variable "prefix" {
type = string
default = "win-vm-iis"
description = "Prefix of the resource name"
}
output.tf
output "resource_group_name" {
value = azurerm_resource_group.rg.name
}
output "public_ip_address" {
value = azurerm_windows_virtual_machine.main.public_ip_address
}
output "admin_password" {
sensitive = true
value = azurerm_windows_virtual_machine.main.admin_password
}
登入 Azure CLI。
在命令提示字元中,輸入以下指令。
az login
執行 Terraform 指令。
在命令提示字元中,切換到剛剛新增的資料夾中,並執行以下指令。
terraform init -upgrade terraform plan -out main.tfplan terraform apply main.tfplan


Terraform 會詢問你是否要執行,輸入 yes 後,Terraform 就會開始執行。
可以看到 Azure VM 已經成功啟用~

若要刪除剛剛建立的資源,可以執行以下指令。
terraform apply main.destroy.tfplan