可用性セットを組んだ仮想マシンをバックエンドプールに使うロードバランサーを構築する Terraform サンプル

Azure にて、仮想マシンスケールセットではなく、可用性セットを組んだ仮想マシン 2 台を、ロードバランサーのバックエンドプールにしてみた。

まぁ、最終的には仮想マシンスケールセットを使ったけどね。せっかく試したんでメモを残しておく。

resource "azurerm_resource_group" "example" {
  name     = "rg-example"
  location = "japaneast"
}

# 仮想ネットワーク
resource "azurerm_virtual_network" "example" {
  name                = "vnet-example"
  address_space       = ["10.0.0.0/16"]
  location            = azurerm_resource_group.example.location
  resource_group_name = azurerm_resource_group.example.name
}

# 仮想ネットワークのサブネット
resource "azurerm_subnet" "example" {
  name                 = "snet-example"
  resource_group_name  = azurerm_resource_group.example.name
  virtual_network_name = azurerm_virtual_network.example.name
  address_prefixes     = ["10.0.2.0/24"]
}

# ロードバランサー用パブリックIPアドレス
resource "azurerm_public_ip" "example" {
  name                = "pip-example"
  location            = azurerm_resource_group.example.location
  resource_group_name = azurerm_resource_group.example.name
  allocation_method   = "Static"
  sku                 = "Standard"
}

# ネットワークセキュリティグループ
resource "azurerm_network_security_group" "example" {
  name                = "nsg-example"
  location            = azurerm_resource_group.example.location
  resource_group_name = azurerm_resource_group.example.name
}

# TCP 443 を許可するネットワークセキュリティルール
resource "azurerm_network_security_rule" "example" {
  name                        = "nsrule-example"
  resource_group_name         = azurerm_resource_group.example.name
  network_security_group_name = azurerm_network_security_group.example.name
  priority                    = 1001
  direction                   = "Inbound"
  access                      = "Allow"
  protocol                    = "Tcp"
  source_port_range           = "*"
  destination_port_range      = 443
  source_address_prefix       = "*"
  destination_address_prefix  = "*"
}

# 仮想ネットワークインターフェイスカード
resource "azurerm_network_interface" "example" {
  count               = 2
  name                = "nic-example-${format("%03d", count.index + 1)}"
  location            = azurerm_resource_group.example.location
  resource_group_name = azurerm_resource_group.example.name

  ip_configuration {
    name                          = "nicconf-example"
    subnet_id                     = azurerm_subnet.example.id
    private_ip_address_allocation = "Dynamic"
  }
}

# ネットワークインタフェースをセキュリティグループに接続
resource "azurerm_network_interface_security_group_association" "example" {
  count                     = length(azurerm_network_interface.example)
  network_interface_id      = azurerm_network_interface.example[count.index].id
  network_security_group_id = azurerm_network_security_group.example.id
}


# 仮想マシンの可用性セット
resource "azurerm_availability_set" "example" {
  name                         = "avail-example"
  location                     = azurerm_resource_group.example.location
  resource_group_name          = azurerm_resource_group.example.name
  platform_fault_domain_count  = 2
  platform_update_domain_count = 2
  managed                      = true
}

# 仮想マシン(Windows)
resource "azurerm_windows_virtual_machine" "example" {
  count                 = 2
  name                  = "vmexample${format("%03d", count.index + 1)}"
  resource_group_name   = azurerm_resource_group.example.name
  location              = azurerm_resource_group.example.location
  size                  = "Standard_F2s_v2"
  admin_username        = "Administrator"
  admin_password        = "P@assw0rd12345"
  availability_set_id   = azurerm_availability_set.example.id
  network_interface_ids = [
    azurerm_network_interface.example[count.index].id
  ]

  os_disk {
    name                 = "osdisk-example-${format("%03d", count.index + 1)}"
    caching              = "ReadWrite"
    storage_account_type = "Standard_LRS"
  }

  source_image_reference {
    publisher = "MicrosoftWindowsServer"
    offer     = "WindowsServer"
    sku       = "2019-Datacenter"
    version   = "latest"
  }
}

# ロードバランサー
resource "azurerm_lb" "example" {
 name                = "lb-example"
 location            = azurerm_resource_group.example.location
 resource_group_name = azurerm_resource_group.example.name
 sku                 = "Standard"

 # フロントエンドIP構成
 frontend_ip_configuration {
   name                 = "fipconf-example"
   public_ip_address_id = azurerm_public_ip.example.id
 }
}

# バックエンドプール
resource "azurerm_lb_backend_address_pool" "example" {
 name                = "bep-example"
 loadbalancer_id     = azurerm_lb.example.id
}

# バックエンドプールの仮想マシン
# 厳密にはネットワークインターフェース
resource "azurerm_network_interface_backend_address_pool_association" "example" {
  count                   = length(azurerm_network_interface.example)
  network_interface_id    = azurerm_network_interface.example[count.index].id
  ip_configuration_name   = "nicconf-example"
  backend_address_pool_id = azurerm_lb_backend_address_pool.example.id
}

# 正常性プローブ
resource "azurerm_lb_probe" "example" {
 name                = "probe-example"
 resource_group_name = azurerm_resource_group.example.name
 loadbalancer_id     = azurerm_lb.example.id
 port                = 443
}

# 負荷分散規則
resource "azurerm_lb_rule" "example" {
   name                           = "lbrule-example"
   resource_group_name            = azurerm_resource_group.example.name
   loadbalancer_id                = azurerm_lb.example.id
   protocol                       = "Tcp"
   frontend_port                  = 443
   backend_port                   = 443
   backend_address_pool_id        = azurerm_lb_backend_address_pool.example.id
   frontend_ip_configuration_name = "fipconf-example"
   probe_id                       = azurerm_lb_probe.example.id
}