04. Virtual Machines
Azure の VM は VM 本体・NIC・Public IP・OS Disk を別リソースとして組み合わせる構造。AWS の aws_instance 一発作成と比べると、最初は冗長に見えますが「責務分離」と捉えると整理しやすいです。
構成要素
Azure で 1 台の VM を起動するために必要なリソース:
- azurerm_public_ip(公開アクセスする場合)
- azurerm_network_interface(NIC)
- azurerm_linux_virtual_machine または azurerm_windows_virtual_machine
- (必要なら)azurerm_managed_disk + azurerm_virtual_machine_data_disk_attachment
Public IP と NIC
resource "azurerm_public_ip" "web" {
name = "pip-web-prd"
resource_group_name = azurerm_resource_group.main.name
location = azurerm_resource_group.main.location
allocation_method = "Static"
sku = "Standard"
}
resource "azurerm_network_interface" "web" {
name = "nic-web-prd-001"
resource_group_name = azurerm_resource_group.main.name
location = azurerm_resource_group.main.location
ip_configuration {
name = "internal"
subnet_id = azurerm_subnet.public.id
private_ip_address_allocation = "Dynamic"
public_ip_address_id = azurerm_public_ip.web.id
}
}
resource "azurerm_network_interface_security_group_association" "web" {
network_interface_id = azurerm_network_interface.web.id
network_security_group_id = azurerm_network_security_group.web.id
}
azurerm_linux_virtual_machine
resource "azurerm_linux_virtual_machine" "web" {
name = "vm-web-prd-001"
resource_group_name = azurerm_resource_group.main.name
location = azurerm_resource_group.main.location
size = "Standard_B2s"
admin_username = "azureuser"
network_interface_ids = [azurerm_network_interface.web.id]
admin_ssh_key {
username = "azureuser"
public_key = file("~/.ssh/id_rsa.pub")
}
os_disk {
caching = "ReadWrite"
storage_account_type = "Premium_LRS"
disk_size_gb = 30
}
source_image_reference {
publisher = "Canonical"
offer = "ubuntu-24_04-lts"
sku = "server"
version = "latest"
}
custom_data = base64encode(<<-EOT
#!/bin/bash
apt-get update
apt-get install -y nginx
systemctl enable --now nginx
EOT
)
identity {
type = "SystemAssigned"
}
tags = local.common_tags
}
SSH キー認証
Azure VM は パスワード認証はデフォルトで無効。SSH キーが必須です。
# 既存の公開鍵を使う
admin_ssh_key {
username = "azureuser"
public_key = file("~/.ssh/id_rsa.pub")
}
# Terraform で鍵ペアを生成(学習用、本番では既存鍵を)
resource "tls_private_key" "ssh" {
algorithm = "RSA"
rsa_bits = 4096
}
# 秘密鍵を Key Vault 等に保存(あるいは output で抜く)
SSH より SSM 風の運用を
Azure には Azure Bastion や Just-in-Time VM access があり、22 番ポート開放なしで管理できます。本番運用ではこちらが推奨。
Managed Identity
AWS の iam_instance_profile 相当。VM 自体が「自分の ID」で他 Azure サービスを叩けます。
resource "azurerm_linux_virtual_machine" "web" {
# ...
identity {
type = "SystemAssigned" # この VM 専用 ID。VM 削除で同時消滅
}
}
# その ID に Storage への権限を付与
resource "azurerm_role_assignment" "vm_to_storage" {
scope = azurerm_storage_account.data.id
role_definition_name = "Storage Blob Data Reader"
principal_id = azurerm_linux_virtual_machine.web.identity[0].principal_id
}
VM Scale Set
AWS の Auto Scaling Group 相当。複数 VM を 1 リソースで管理。
resource "azurerm_linux_virtual_machine_scale_set" "web" {
name = "vmss-web-prd"
resource_group_name = azurerm_resource_group.main.name
location = azurerm_resource_group.main.location
sku = "Standard_B2s"
instances = 3
admin_username = "azureuser"
admin_ssh_key {
username = "azureuser"
public_key = file("~/.ssh/id_rsa.pub")
}
source_image_reference {
publisher = "Canonical"
offer = "ubuntu-24_04-lts"
sku = "server"
version = "latest"
}
os_disk {
storage_account_type = "Standard_LRS"
caching = "ReadWrite"
}
network_interface {
name = "primary"
primary = true
ip_configuration {
name = "internal"
primary = true
subnet_id = azurerm_subnet.private.id
}
}
upgrade_mode = "Rolling" # 自動でローリング更新
}
VM じゃない選択肢を先に検討
Web/API は Container Apps や App Service、バッチは Container Instances や Functions。VM が必要なケースは「OS まで管理したい」「特殊ソフト」に限られます。