Vytvoření sady škálování virtuálních počítačů Azure z vlastní image balíčku pomocí Terraformu

Azure Virtual Machine Scale Sets vám umožní nakonfigurovat identické virtuální počítače. Počet instancí virtuálních počítačů se může upravovat na základě poptávky nebo plánu. Další informace najdete v tématu Automatické škálování sady škálování virtuálních počítačů v Azure Portal.

V tomto článku získáte informace o těchto tématech:

  • Nastavit nasazení Terraformu
  • Použít proměnné a výstupy u nasazení Terraformu
  • Vytvořit a nasadit síťovou infrastrukturu
  • Vytvoření vlastní image virtuálního počítače pomocí balírny
  • Vytvoření a nasazení sady škálování virtuálního počítače pomocí vlastní image
  • Vytvořit a nasadit jumpbox

1. konfigurace prostředí

  • Předplatné Azure: Pokud ještě nemáte předplatné Azure, vytvořte si bezplatný účet před tím, než začnete.

2. vytvoření image balíčku

  1. Nainstalujte balíček.

    Klíčové body:

    • Abyste se ujistili, že máte přístup ke spustitelnému souboru balíčku, spusťte následující příkaz: packer -v .
    • V závislosti na vašem prostředí možná budete muset nastavit cestu a znovu otevřít příkazový řádek.
  2. Spuštěním AZ Group Create vytvořte skupinu prostředků, která bude uchovávat image balíčku.

    az group create -n myPackerImages -l eastus
    
  3. Spusťte příkaz AZ AD SP Create-for-RBAC , aby bylo možné zapnout balíček pro ověřování v Azure pomocí instančního objektu.

    az ad sp create-for-rbac --role Contributor --query "{ client_id: appId, client_secret: password, tenant_id: tenant }"
    

    Klíčové body:

    • Poznamenejte si výstupní hodnoty ( appId , client_secret , tenant_id ).
  4. Spuštěním AZ Account show zobrazíte aktuální předplatné Azure.

    az account show --query "{ subscription_id: id }"
    
  5. Vytvořte soubor šablony balíčku s názvem ubuntu.json a vložte následující kód:

    {
        "builders": [{
          "type": "azure-arm",
      
          "client_id": "0bfc2293-4d69-49b5-83f7-bf0d60d20c45",
          "client_secret": "G3.6ytCh44Kcla~_JRPBDLkzsXLOa3edDL",
          "tenant_id": "c3fd441d-b8ad-487e-aa27-453079018fca",
          "subscription_id": "b162117f-53fa-4f42-8c77-6a65ca966c40",
      
          "managed_image_resource_group_name": "myPackerImages",
          "managed_image_name": "myPackerImage",
      
          "os_type": "Linux",
          "image_publisher": "Canonical",
          "image_offer": "UbuntuServer",
          "image_sku": "16.04-LTS",
      
          "azure_tags": {
              "dept": "Engineering",
              "task": "Image deployment"
          },
      
          "location": "East US",
          "vm_size": "Standard_DS2_v2"
        }],
        "provisioners": [{
          "execute_command": "chmod +x {{ .Path }}; {{ .Vars }} sudo -E sh '{{ .Path }}'",
          "inline": [
            "apt-get update",
            "apt-get upgrade -y",
            "apt-get -y install nginx",
      
            "/usr/sbin/waagent -force -deprovision+user && export HISTSIZE=0 && sync"
          ],
          "inline_shebang": "/bin/sh -x",
          "type": "shell"
        }]
      }
    

    Klíčové body:

    • Nastavte client_id pole, client_secret a tenant_id na příslušné hodnoty z objektu služby.
    • Nastavte subscription_id pole na ID předplatného Azure.
  6. Sestavte image balíčku.

    packer build ubuntu.json
    

3. implementace kódu Terraformu

  1. Vytvořte adresář, ve kterém chcete otestovat ukázkový kód Terraformu a nastavte ho jako aktuální adresář.

  2. Vytvořte soubor s názvem main.tf a vložte následující kód:

    terraform {
    
      required_version = ">=0.12"
    
      required_providers {
        azurerm = {
          source = "hashicorp/azurerm"
          version = "~>2.0"
        }
      }
    }
    
    provider "azurerm" {
      features {}
    }
    
    resource "azurerm_resource_group" "vmss" {
      name     = var.resource_group_name
      location = var.location
      tags = var.tags
    }
    
    resource "random_string" "fqdn" {
     length  = 6
     special = false
     upper   = false
     number  = false
    }
    
    resource "azurerm_virtual_network" "vmss" {
      name                = "vmss-vnet"
      address_space       = ["10.0.0.0/16"]
      location            = var.location
      resource_group_name = azurerm_resource_group.vmss.name
      tags = var.tags
    }
    
    resource "azurerm_subnet" "vmss" {
      name                 = "vmss-subnet"
      resource_group_name  = azurerm_resource_group.vmss.name
      virtual_network_name = azurerm_virtual_network.vmss.name
      address_prefixes       = ["10.0.2.0/24"]
    }
    
    resource "azurerm_public_ip" "vmss" {
      name                         = "vmss-public-ip"
      location                     = var.location
      resource_group_name          = azurerm_resource_group.vmss.name
      allocation_method            = "Static"
      domain_name_label            = random_string.fqdn.result
      tags = var.tags
    }
    
    resource "azurerm_lb" "vmss" {
      name                = "vmss-lb"
      location            = var.location
      resource_group_name = azurerm_resource_group.vmss.name
    
      frontend_ip_configuration {
        name                 = "PublicIPAddress"
        public_ip_address_id = azurerm_public_ip.vmss.id
      }
    
      tags = var.tags
    }
    
    resource "azurerm_lb_backend_address_pool" "bpepool" {
      loadbalancer_id     = azurerm_lb.vmss.id
      name                = "BackEndAddressPool"
    }
    
    resource "azurerm_lb_probe" "vmss" {
      resource_group_name = azurerm_resource_group.vmss.name
      loadbalancer_id     = azurerm_lb.vmss.id
      name                = "ssh-running-probe"
      port                = var.application_port
    }
    
    resource "azurerm_lb_rule" "lbnatrule" {
      resource_group_name            = azurerm_resource_group.vmss.name
      loadbalancer_id                = azurerm_lb.vmss.id
      name                           = "http"
      protocol                       = "Tcp"
      frontend_port                  = var.application_port
      backend_port                   = var.application_port
      backend_address_pool_id        = azurerm_lb_backend_address_pool.bpepool.id
      frontend_ip_configuration_name = "PublicIPAddress"
      probe_id                       = azurerm_lb_probe.vmss.id
    }
    
    data "azurerm_resource_group" "image" {
      name                = var.packer_resource_group_name
    }
    
    data "azurerm_image" "image" {
      name                = var.packer_image_name
      resource_group_name = data.azurerm_resource_group.image.name
    }
    
    resource "azurerm_virtual_machine_scale_set" "vmss" {
      name                = "vmscaleset"
      location            = var.location
      resource_group_name = azurerm_resource_group.vmss.name
      upgrade_policy_mode = "Manual"
    
      sku {
        name     = "Standard_DS1_v2"
        tier     = "Standard"
        capacity = 2
      }
    
      storage_profile_image_reference {
        id=data.azurerm_image.image.id
      }
    
      storage_profile_os_disk {
        name              = ""
        caching           = "ReadWrite"
        create_option     = "FromImage"
        managed_disk_type = "Standard_LRS"
      }
    
      storage_profile_data_disk {
        lun          = 0
        caching        = "ReadWrite"
        create_option  = "Empty"
        disk_size_gb   = 10
      }
    
      os_profile {
        computer_name_prefix = "vmlab"
        admin_username       = var.admin_user
        admin_password       = var.admin_password
      }
    
      os_profile_linux_config {
        disable_password_authentication = true
    
        ssh_keys {
          path     = "/home/azureuser/.ssh/authorized_keys"
          key_data = file("~/.ssh/id_rsa.pub")
        }
      }
    
      network_profile {
        name    = "terraformnetworkprofile"
        primary = true
    
        ip_configuration {
          name                                   = "IPConfiguration"
          subnet_id                              = azurerm_subnet.vmss.id
          load_balancer_backend_address_pool_ids = [azurerm_lb_backend_address_pool.bpepool.id]
          primary = true
        }
      }
      
      tags = var.tags
    }
    
    resource "azurerm_public_ip" "jumpbox" {
      name                         = "jumpbox-public-ip"
      location                     = var.location
      resource_group_name          = azurerm_resource_group.vmss.name
      allocation_method            = "Static"
      domain_name_label            = "${random_string.fqdn.result}-ssh"
      tags = var.tags
    }
    
    resource "azurerm_network_interface" "jumpbox" {
      name                = "jumpbox-nic"
      location            = var.location
      resource_group_name = azurerm_resource_group.vmss.name
    
      ip_configuration {
        name                          = "IPConfiguration"
        subnet_id                     = azurerm_subnet.vmss.id
        private_ip_address_allocation = "dynamic"
        public_ip_address_id          = azurerm_public_ip.jumpbox.id
      }
    
      tags = var.tags
    }
    
    resource "azurerm_virtual_machine" "jumpbox" {
      name                  = "jumpbox"
      location              = var.location
      resource_group_name   = azurerm_resource_group.vmss.name
      network_interface_ids = [azurerm_network_interface.jumpbox.id]
      vm_size               = "Standard_DS1_v2"
    
      storage_image_reference {
        publisher = "Canonical"
        offer     = "UbuntuServer"
        sku       = "16.04-LTS"
        version   = "latest"
      }
    
      storage_os_disk {
        name              = "jumpbox-osdisk"
        caching           = "ReadWrite"
        create_option     = "FromImage"
        managed_disk_type = "Standard_LRS"
      }
    
      os_profile {
        computer_name  = "jumpbox"
        admin_username = var.admin_user
        admin_password = var.admin_password
      }
    
      os_profile_linux_config {
        disable_password_authentication = true
    
        ssh_keys {
          path     = "/home/azureuser/.ssh/authorized_keys"
          key_data = file("~/.ssh/id_rsa.pub")
        }
      }
    
      tags = var.tags
    }
    
    
  3. Vytvořte soubor s názvem variables.tf , který obsahuje proměnné projektu, a vložte následující kód:

    variable "packer_resource_group_name" {
       description = "Name of the resource group in which the Packer image will be created"
       default     = "myPackerImages"
    }
    
    variable "packer_image_name" {
       description = "Name of the Packer image"
       default     = "myPackerImage"
    }
    
    variable "resource_group_name" {
       description = "Name of the resource group in which the Packer image  will be created"
       default     = "myPackerImages"
    }
    
    variable "resource_group_name" {
       description = "Name of the resource group in which the resources will be created"
       default     = "myResourceGroup"
    }
    
    variable "location" {
       default = "eastus"
       description = "Location where resources will be created"
    }
    
    variable "tags" {
       description = "Map of the tags to use for the resources that are deployed"
       type        = map(string)
       default = {
          environment = "codelab"
       }
    }
    
    variable "application_port" {
       description = "Port that you want to expose to the external load balancer"
       default     = 80
    }
    
    variable "admin_user" {
       description = "User name to use as the admin account on the VMs that will be part of the VM scale set"
       default     = "azureuser"
    }
    
    variable "admin_password" {
       description = "Default password for admin account"
    }
    
  4. Vytvořte soubor s názvem a output.tf Určete, jaké hodnoty terraformu se zobrazí, a vložte následující kód:

    output "vmss_public_ip_fqdn" {
        value = azurerm_public_ip.vmss.fqdn
    }
    
    output "jumpbox_public_ip_fqdn" {
        value = azurerm_public_ip.jumpbox.fqdn
    }
    
    output "jumpbox_public_ip" {
        value = azurerm_public_ip.jumpbox.ip_address
    }
    

4. inicializace Terraformu

Spusťte terraformu init pro inicializaci nasazení terraformu.

terraform init

Klíčové body:

  • Tento příkaz stáhne moduly Azure vyžadované k vytvoření skupiny prostředků Azure.

5. vytvoření plánu spuštění Terraformu

Spuštěním plánu terraformu vytvořte plán spuštění.

terraform plan -out main.tfplan

Klíčové body:

  • terraform planPříkaz vytvoří plán spuštění, ale neprovede ho. Místo toho určuje, jaké akce je potřeba k vytvoření konfigurace zadané v konfiguračních souborech. Tento model vám umožní ověřit, zda plán spuštění odpovídá vašim očekáváním, a teprve potom provádět změny ve skutečných prostředcích.
  • Volitelný -out parametr umožňuje zadat výstupní soubor pro daný plán. Použití -out parametru zajistí, že plán, který jste zkontrolovali, je přesně to, co se používá.
  • Další informace o zachování plánů provádění a zabezpečení najdete v části upozornění zabezpečení.

6. použití plánu spuštění Terraformu

Spuštění terraformu platí pro použití plánu spuštění pro cloudovou infrastrukturu.

terraform apply main.tfplan

Klíčové body:

  • terraform applyVýše uvedený příkaz předpokládá, že jste dřív spustili terraform plan -out main.tfplan .
  • Pokud jste pro parametr určili jiný název souboru -out , použijte stejný název souboru v volání metody terraform apply .
  • Pokud jste parametr nepoužili -out , jednoduše zavolejte terraform apply bez parametrů.

7. Ověřte výsledky.

  1. Z výstupu terraform apply příkazu se zobrazí následující hodnoty:

    • Plně kvalifikovaný název domény virtuálního počítače
    • JumpBox plně kvalifikovaný název domény
    • JumpBox IP adresa
  2. Přejděte na adresu URL virtuálního počítače a potvrďte výchozí stránku s textem Vítejte v Nginx!.

  3. Pomocí SSH se připojte k virtuálnímu počítači s JumpBox pomocí uživatelského jména definovaného v souboru proměnných a hesla, které jste zadali při spuštění terraform apply . Příklad: ssh azureuser@<ip_address>.

8. vyčištění prostředků

Odstranit sadu škálování virtuálního počítače

Pokud již nepotřebujete prostředky vytvořené prostřednictvím Terraformu, proveďte následující kroky:

  1. Spusťte plán terraformu a zadejte příznak.

    terraform plan -destroy -out main.destroy.tfplan
    

    Klíčové body:

    • terraform planPříkaz vytvoří plán spuštění, ale neprovede ho. Místo toho určuje, jaké akce je potřeba k vytvoření konfigurace zadané v konfiguračních souborech. Tento model vám umožní ověřit, zda plán spuštění odpovídá vašim očekáváním, a teprve potom provádět změny ve skutečných prostředcích.
    • Volitelný -out parametr umožňuje zadat výstupní soubor pro daný plán. Použití -out parametru zajistí, že plán, který jste zkontrolovali, je přesně to, co se používá.
    • Další informace o zachování plánů provádění a zabezpečení najdete v části upozornění zabezpečení.
  2. Spusťte terraformu použít pro použití plánu spuštění.

    terraform apply main.destroy.tfplan
    

Odstranit image balíčku a skupinu prostředků

Spuštěním AZ Group Delete odstraňte skupinu prostředků, která obsahuje image balíčku. Odstraní se i obrázek balíčku.

az group delete --name myPackerImages --yes

Řešení potíží s Terraformu v Azure

Řešení běžných problémů při použití Terraformu v Azure

Další kroky