Terraform kullanarak Packer özel görüntüsünden Azure sanal makine ölçek kümesi oluşturma

Azure sanal makine ölçek kümeleri, aynı VM'leri yapılandırmaya olanak sağlar. VM örneklerinin sayısı isteğe veya zaman çizelgesine göre ayarlanabilir. Daha fazla bilgi için bkz. Sanal makine ölçek kümesinde otomatik olarak ölçeklendirme Azure portal.

Bu makalede şunları öğreneceksiniz:

  • Terraform dağıtımınızı ayarlama
  • Terraform dağıtımı için değişkenleri ve çıkışları kullanma
  • Ağ altyapısı oluşturma ve dağıtma
  • Packer kullanarak özel sanal makine görüntüsü oluşturma
  • Özel görüntüyü kullanarak sanal makine ölçek kümesi oluşturma ve dağıtma
  • Sıçrama kutusu oluşturma ve dağıtma

1. Ortamınızı yapılandırma

  • Azure aboneliği: Azure aboneliğiniz yoksa başlamadan önce ücretsiz bir hesap oluşturun.

2. Packer görüntüsü oluşturma

  1. Packer'i yükleyin.

    Önemli noktalar:

    • Packer yürütülebilir dosyasına erişiminiz olduğunu onaylamak için şu komutu çalıştırın: packer -v .
    • Ortamınıza bağlı olarak, yolu ayarlamanız ve komut satırınızı yeniden açmanız gerekir.
  2. Packer görüntüsünü tutmak için az group create'ı çalıştırarak bir kaynak grubu oluşturun.

    az group create -n myPackerImages -l eastus
    
  3. Packer'ın hizmet sorumlusu kullanarak Azure'da kimlik doğrulaması yapmasını sağlamak için az ad sp create-for-rbac çalıştırın.

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

    Önemli noktalar:

    • Çıkış değerlerini ( appId , client_secret , ) not tenant_id alırsınız.
  4. Geçerli Azure aboneliğini görüntülemek için az account show çalıştırın.

    az account show --query "{ subscription_id: id }"
    
  5. adlı bir Packer şablon dosyası ubuntu.json oluşturun ve aşağıdaki kodu girin:

    {
        "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"
        }]
      }
    

    Önemli noktalar:

    • , client_id ve client_secret alanlarını hizmet tenant_id sorumlundan ilgili değerlere ayarlayın.
    • Alanını subscription_id Azure abonelik kimliği olarak ayarlayın.
  6. Packer görüntüsünü oluşturma.

    packer build ubuntu.json
    

3. Terraform kodunu uygulama

  1. Örnek Terraform kodunu test etmek ve bunu geçerli dizin yapmak için bir dizin oluşturun.

  2. adlı bir dosya main.tf oluşturun ve aşağıdaki kodu girin:

    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. Proje değişkenlerini variables.tf içeren adlı bir dosya oluşturun ve aşağıdaki kodu girin:

    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. output.tfTerraform'daki değerleri belirtmek için adlı bir dosya oluşturun ve aşağıdaki kodu girin:

    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. Terraform'ü başlatma

Terraform dağıtımını başlatmak için terraform init'i çalıştırın.

terraform init

Önemli noktalar:

  • Bu komut, bir Azure kaynak grubu oluşturmak için gereken Azure modüllerini indirir.

5. Terraform yürütme planı oluşturma

Terraform planını çalıştırarak bir yürütme planı oluşturun.

terraform plan -out main.tfplan

Önemli noktalar:

  • Komut terraform plan bir yürütme planı oluşturur ancak yürütmez. Bunun yerine, yapılandırma dosyalarında belirtilen yapılandırmayı oluşturmak için hangi eylemlerin gerekli olduğunu belirler. Bu düzen, gerçek kaynaklarda değişiklik yapmadan önce yürütme planının beklentilerinize uygun olup olmadığını doğrulamanıza olanak sağlar.
  • İsteğe -out bağlı parametresi, plan için bir çıkış dosyası belirtmenize olanak sağlar. parametresini -out kullanmak, gözden geçiren planın tam olarak uygulandığını garantiler.
  • Yürütme planlarını ve güvenliği kalıcı hale uygulama hakkında daha fazla bilgi için güvenlik uyarısı bölümüne bakın.

6. Terraform yürütme planı uygulama

Yürütme planını bulut altyapınıza uygulamak için terraform apply'i çalıştırın.

terraform apply main.tfplan

Önemli noktalar:

  • Yukarıdaki terraform apply komut daha önce komutunun olduğunu varsayıyor. terraform plan -out main.tfplan
  • parametresi için farklı bir dosya adı -out belirttiyebilirsiniz, çağrısında aynı dosya adını terraform apply kullanın.
  • parametresini -out kullanmadıysanız herhangi bir parametre terraform apply olmadan çağrısı yapmanız gerekir.

7. Sonuçları doğrulama

  1. Komutun terraform apply çıkışında aşağıdaki değerlerin yer alan değerlerini görüyorsunuz:

    • Sanal makine FQDN'si
    • Jumpbox FQDN
    • Sıçrama kutusu IP adresi
  2. nginx'ehoş geldiniz! metninin yer alan varsayılan bir sayfa olduğunu onaylamak için sanal makine URL'sini bulun.

  3. Değişkenler dosyasında tanımlanan kullanıcı adını ve dosyasını çalıştırıp belirttiğiniz parolayı kullanarak sıçrama kutusu VM'sinde bağlanmak için SSH terraform apply kullanın. Örneğin: ssh azureuser@<ip_address>.

8. Kaynakları temizleme

Sanal makine ölçek kümesi silme

Terraform aracılığıyla oluşturulan kaynaklara artık ihtiyacınız kalmadan aşağıdaki adımları uygulayın:

  1. Terraform planını çalıştırın ve bayrağını belirtin.

    terraform plan -destroy -out main.destroy.tfplan
    

    Önemli noktalar:

    • Komut terraform plan bir yürütme planı oluşturur ancak yürütmez. Bunun yerine, yapılandırma dosyalarında belirtilen yapılandırmayı oluşturmak için hangi eylemlerin gerekli olduğunu belirler. Bu düzen, gerçek kaynaklarda değişiklik yapmadan önce yürütme planının beklentilerinize uygun olup olmadığını doğrulamanıza olanak sağlar.
    • İsteğe -out bağlı parametresi, plan için bir çıkış dosyası belirtmenize olanak sağlar. parametresini -out kullanmak, gözden geçiren planın tam olarak uygulandığını garantiler.
    • Yürütme planlarını ve güvenliği kalıcı hale uygulama hakkında daha fazla bilgi için güvenlik uyarısı bölümüne bakın.
  2. Yürütme planını uygulamak için terraform apply'i çalıştırın.

    terraform apply main.destroy.tfplan
    

Packer görüntüsünü ve kaynak grubunu silme

Packer görüntüsünü içeren kaynak grubunu silmek için az group delete çalıştırın. Packer görüntüsü de silinir.

az group delete --name myPackerImages --yes

Azure'da Terraform sorunlarını giderme

Azure'da Terraform kullanırken karşılaşılan yaygın sorunları giderme

Sonraki adımlar