Een virtuele-machineschaalset in Azure maken met behulp van Terraform

Met virtuele-machineschaalsets van Azure kunt u identieke VM's configureren. Het aantal VM-exemplaren kan worden aangepast op basis van de vraag of een planning. Zie Een virtuele-machineschaalset automatisch schalen in de Azure Portal.

In dit artikel leert u het volgende:

  • Een Terraform-implementatie instellen
  • Variabelen en uitvoer voor Terraform-implementatie gebruiken
  • Netwerkinfrastructuur maken en implementeren
  • Een virtuele-machineschaalset maken en implementeren, en deze koppelen aan het netwerk
  • Een jumpbox maken en implementeren om verbinding te maken met de VM's via SSH

1. Uw omgeving configureren

  • Azure-abonnement: Als u nog geen abonnement op Azure hebt, maak dan een gratis account aan voordat u begint.

2. De Terraform-code implementeren

  1. Maak een map waarin u de Terraform-voorbeeldcode wilt testen en deze de huidige map wilt maken.

  2. Maak een bestand met de main.tf naam en voeg de volgende code in:

    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
    }
    
    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 {
       publisher = "Canonical"
       offer     = "UbuntuServer"
       sku       = "16.04-LTS"
       version   = "latest"
     }
    
     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
       custom_data          = file("web.conf")
     }
    
     os_profile_linux_config {
       disable_password_authentication = false
     }
    
     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 = false
     }
    
     tags = var.tags
    }
    
  3. Maak een bestand met de variables.tf naam dat de projectvariabelen bevat en voeg de volgende code in:

    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. Maak een bestand met de output.tf naam om op te geven welke waarden Terraform we zien en voeg de volgende code in:

    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
    }
    
  5. Maak een bestand met de web.conf naam en voeg de volgende code in:

    #cloud-config
    packages:
     - nginx
    

3. Terraform initialiseren

Voer terraform init uit om de Terraform-implementatie te initialiseren.

terraform init

Belangrijkste punten:

  • Met deze opdracht worden de Azure-modules gedownload die nodig zijn om een Azure-resourcegroep te maken.

4. Een Terraform-uitvoeringsplan maken

Voer terraform plan uit om een uitvoeringsplan te maken.

terraform plan -out main.tfplan

Belangrijkste punten:

  • Met terraform plan de opdracht wordt een uitvoeringsplan gemaakt, maar niet uitgevoerd. In plaats daarvan wordt bepaald welke acties nodig zijn om de configuratie te maken die is opgegeven in uw configuratiebestanden. Met dit patroon kunt u controleren of het uitvoeringsplan overeenkomt met uw verwachtingen voordat u wijzigingen aan echte resources aantreft.
  • Met de -out optionele parameter kunt u een uitvoerbestand voor het plan opgeven. Door de -out parameter te gebruiken, zorgt u ervoor dat het plan dat u hebt gecontroleerd, precies is wat wordt toegepast.
  • Zie de sectie beveiligingswaarschuwing voor meer informatie over persistente uitvoeringsplannen en beveiliging.

5. Een Terraform-uitvoeringsplan toepassen

Voer terraform apply uit om het uitvoeringsplan toe te passen op uw cloudinfrastructuur.

terraform apply main.tfplan

Belangrijkste punten:

  • In terraform apply de bovenstaande opdracht wordt ervan uitgenomen dat u eerder hebt terraform plan -out main.tfplan uitvoeren.
  • Als u een andere bestandsnaam voor de parameter hebt opgegeven, gebruikt -out u dezelfde bestandsnaam in de aanroep van terraform apply .
  • Als u de parameter niet hebt -out gebruikt, roept u gewoon terraform apply aan zonder parameters.

6. De resultaten controleren

  1. In de uitvoer van de terraform apply opdracht ziet u waarden voor het volgende:

    • FQDN van virtuele machine
    • Jumpbox-FQDN
    • IP-adres van jumpbox
  2. Blader naar de URL van de virtuele machine om een standaardpagina te bevestigen met de tekst Welkom bij nginx!.

  3. Gebruik SSH om verbinding te maken met de jumpbox-VM met behulp van de gebruikersnaam die is gedefinieerd in het variabelenbestand en het wachtwoord dat u hebt opgegeven tijdens het gebruik terraform apply van . Bijvoorbeeld: ssh azureuser@<ip_address>.

7. Resources ops schonen

Wanneer u de resources die via Terraform zijn gemaakt niet meer nodig hebt, moet u de volgende stappen volgen:

  1. Voer terraform plan uit en geef de vlag op.

    terraform plan -destroy -out main.destroy.tfplan
    

    Belangrijkste punten:

    • Met terraform plan de opdracht wordt een uitvoeringsplan gemaakt, maar niet uitgevoerd. In plaats daarvan wordt bepaald welke acties nodig zijn om de configuratie te maken die is opgegeven in uw configuratiebestanden. Met dit patroon kunt u controleren of het uitvoeringsplan overeenkomt met uw verwachtingen voordat u wijzigingen aan echte resources aantreft.
    • Met de -out optionele parameter kunt u een uitvoerbestand voor het plan opgeven. Door de -out parameter te gebruiken, zorgt u ervoor dat het plan dat u hebt gecontroleerd, precies is wat wordt toegepast.
    • Zie de sectie beveiligingswaarschuwing voor meer informatie over persistente uitvoeringsplannen en beveiliging.
  2. Voer terraform apply uit om het uitvoeringsplan toe te passen.

    terraform apply main.destroy.tfplan
    

Problemen met Terraform in Azure oplossen

Veelvoorkomende problemen bij het gebruik van Terraform in Azure oplossen

Volgende stappen