【備忘録】AzureのScale Setを準備する 前編

■はじめに

前回、packerでVMイメージの作成まで行いました。

本日はこのImageを使用してVMを建てるところまで持ってゆきます。

■作業の概要

まずselenoidVM側の構築に、Ansibleのプロビジョニングではなくて構築済みのImage(selenoidImage)を使って建てます。
またその際今まで使用していたazurerm_linux_virtual_machineではなく、azurerm_linux_virtual_machine_scale_setを使用します。

理由としては、selenoidの特性です。
selenoidはwebdriverによるセッション起動すると内部でコンテナが起動されブラウザーが立ち上がりますが、並列実行が可能なのでセッションが複数起動されるほどリソースを消費します。

現代のE2Eテストでは、環境を並列起動してテストリードタイムを短縮するのがセオリーとなっているので、環境のスケールアウト・インは前提となります。

■tfファイルの書き換え方

参考としたページは以下です。

⒈ terraformによるスケールセット構築方法

docs.microsoft.com

⒉ packerイメージからスケールセットを構築する方法

docs.microsoft.com

⒊ azurerm_linux_virtual_machine_scale_set

ちなみに上記はazurerm_virtual_machine_scale_setを使用したガイドになっているのですが、terraformの公式を見ると最新ではazurerm_linux_virtual_machine_scale_setに挿し替わっているそうで、合わせて以下のページも参考にしています。

www.terraform.io

■手順

以前のエントリ通りの手順だとうまく構築まで進まないので、最初の手順から記載します。

①リソースグループの準備

まずpackerを実行してselenoidImageを構築するために、前提となるリソースグループが必要です。
なのでリソースグループだけのtfファイルを準備・実行します。

# Azure 接続とリソース グループを作成する
resource "azurerm_resource_group" "rg" {
  name     = "rg"
  location = "eastus"
}


正常に実行されると以下のようになります。

Apply complete! Resources: 1 added, 0 changed, 0 destroyed.


②packerの実行

次にリソースグループに対して以前準備したpacker.jsonを実行します。

{
  "builders":[{
    "type": "azure-arm",

    "client_id": "xxxxx",
    "client_secret": "xxxxx",
    "tenant_id": "xxxxx",
    "subscription_id": "xxxxxx",

    "managed_image_resource_group_name": "rg",
    "managed_image_name": "selenoidImage",

    "os_type": "Linux",
    "image_publisher": "Canonical",
    "image_offer": "UbuntuServer",
    "image_sku": "18.04-LTS",

    "azure_tags": {
        "dept": "Engineering",
        "task": "Image deployment"
    },

    "location": "eastus",
    "vm_size": "Standard_F2"
  }],
  "provisioners":[
    {
      "type": "ansible",
      "playbook_file": "playbook_node.yml"
    }
  ]
}


実行すると以下の通り出力され、事前準備したリソースグループにImageが出来上がります。

    azure-arm: PLAY RECAP *********************************************************************
    azure-arm: default                    : ok=17   changed=14   unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

(中略)

==> azure-arm:  -> Image Name                : 'selenoidImage'

(中略)

Build 'azure-arm' finished.


なおplaybook.ymlは以前のエントリ通りです。

③tfファイルの変更

Imageができたところで、今度はこのImageでVMScalseSetを構築します。
ここでは⒉ を参考に、以前準備していたselenoid構築用のtfファイルを書き換えます。

まず、全く記述のないロードバランサー周りを書き起こします。

resource "azurerm_lb" "selenoid_lb" {
  name                = "selenoid_lb"
  location            = var.location
  resource_group_name = azurerm_resource_group.rg.name

  frontend_ip_configuration {
    name                 = "selenoid_lb_ip_configration"
    public_ip_address_id = azurerm_public_ip.selenoid_publicip_01.id
  }
  tags = var.tags
}

resource "azurerm_lb_backend_address_pool" "bpepool" {
  resource_group_name = azurerm_resource_group.rg.name
  loadbalancer_id     = azurerm_lb.selenoid_lb.id
  name                = "selenoid_bea_pool"
}

resource "azurerm_lb_probe" "selenoid_lbp" {
  resource_group_name = azurerm_resource_group.rg.name
  loadbalancer_id     = azurerm_lb.selenoid_lb.id
  name                = "selenoid_ssh_running_probe"
  port                = var.selenoid_port_01
}

resource "azurerm_lb_rule" "selenoid_lbnatrule01" {
  resource_group_name            = azurerm_resource_group.rg.name
  loadbalancer_id                = azurerm_lb.selenoid_lb.id
  name                           = "http01"
  protocol                       = "Tcp"
  frontend_port                  = var.selenoid_port_01
  backend_port                   = var.selenoid_port_01
  backend_address_pool_id        = azurerm_lb_backend_address_pool.bpepool.id
  frontend_ip_configuration_name = "selenoid_lb_ip_configration"
  probe_id                       = azurerm_lb_probe.selenoid_lbp.id
}

resource "azurerm_lb_rule" "selenoid_lbnatrule02" {
  resource_group_name            = azurerm_resource_group.rg.name
  loadbalancer_id                = azurerm_lb.selenoid_lb.id
  name                           = "http02"
  protocol                       = "Tcp"
  frontend_port                  = var.selenoid_port_02
  backend_port                   = var.selenoid_port_02
  backend_address_pool_id        = azurerm_lb_backend_address_pool.bpepool.id
  frontend_ip_configuration_name = "selenoid_lb_ip_configration"
  probe_id                       = azurerm_lb_probe.selenoid_lbp.id
}

resource "azurerm_lb_rule" "selenoid_lbnatrule03" {
  resource_group_name            = azurerm_resource_group.rg.name
  loadbalancer_id                = azurerm_lb.selenoid_lb.id
  name                           = "http03"
  protocol                       = "Tcp"
  frontend_port                  = var.selenoid_port_03
  backend_port                   = var.selenoid_port_03
  backend_address_pool_id        = azurerm_lb_backend_address_pool.bpepool.id
  frontend_ip_configuration_name = "selenoid_lb_ip_configration"
  probe_id                       = azurerm_lb_probe.selenoid_lbp.id
}

data "azurerm_resource_group" "image" {
  name = "selenoid_rg"
}

data "azurerm_image" "image" {
  name                = "selenoidImage"
  resource_group_name = data.azurerm_resource_group.image.name
}


次に以前はazurerm_linux_virtual_machineとして準備していた部分を、azurerm_linux_virtual_machine_scale_setとして書き換えます。

resource "azurerm_linux_virtual_machine_scale_set" "selenoid_vm01" {
  name                = "selenoid01"
  location            = var.location
  resource_group_name = azurerm_resource_group.rg.name
  admin_username      = "qa"
  instances           = 1
  sku                 = "Standard_F2"
  source_image_id     = data.azurerm_image.image.id

  admin_ssh_key {
    username   = "qa"
    public_key = file("~/.ssh/id_rsa.pub")
  }

  os_disk {
    caching              = "ReadWrite"
    storage_account_type = "Standard_LRS"
  }

  network_interface {
    name    = "example"
    primary = true

    ip_configuration {
      name                                   = "selenoid_subnet"
      primary                                = true
      subnet_id                              = azurerm_subnet.selenoid_subnet.id
      load_balancer_backend_address_pool_ids = [azurerm_lb_backend_address_pool.bpepool.id]
    }
  }
}


ポイントは
source_image_id = data.azurerm_image.image.id
という部分です。
これでScaleSetをImageから構築できます。

次回、実際にterraform applyして行きます。

ではでは。