Terraform kullanarak Packer özel görüntüsünden Azure sanal makine ölçek kümesi oluşturma
Terraform , bulut altyapısının tanımlanmasını, önizlemesini ve dağıtımını sağlar. Terraform kullanarak HCL söz dizimlerini kullanarak yapılandırma dosyaları oluşturursunuz. HCL söz dizimi, Azure gibi bulut sağlayıcısını ve bulut altyapınızı oluşturan öğeleri belirtmenize olanak tanır. Yapılandırma dosyalarınızı oluşturduktan sonra, altyapı değişikliklerinizin dağıtılmadan önce önizlemesini görüntülemenizi sağlayan bir yürütme planı oluşturursunuz. Değişiklikleri doğruladıktan sonra, altyapıyı dağıtmak için yürütme planını uygularsınız.
Azure sanal makine ölçek kümeleri , aynı VM'leri yapılandırmanıza olanak sağlar. VM örneklerinin sayısı isteğe veya zamanlamaya göre ayarlanabilir. Daha fazla bilgi için bkz . Azure portalında sanal makine ölçek kümesini otomatik olarak ölçeklendirme.
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 bir 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.
Terraform'ı yapılandırma: Henüz yapmadıysanız, aşağıdaki seçeneklerden birini kullanarak Terraform'ı yapılandırın:
2. Paketleyici görüntüsü oluşturma
Packer'ı yükleyin.
Önemli noktalar:
- Packer yürütülebilir dosyası erişiminiz olduğunu onaylamak için aşağıdaki komutu çalıştırın:
packer -v
. - Ortamınıza bağlı olarak, yolunuzu ayarlamanız ve komut satırını yeniden açmanız gerekebilir.
- Packer yürütülebilir dosyası erişiminiz olduğunu onaylamak için aşağıdaki komutu çalıştırın:
Paketleyici görüntüsünü tutacak bir kaynak grubu oluşturmak için az group create komutunu çalıştırın.
az group create -n myPackerImages -l eastus
Packer'ın hizmet sorumlusu kullanarak Azure'da kimlik doğrulaması yapmasını sağlamak için az ad sp create-for-rbac komutunu çalıştırın.
az ad sp create-for-rbac --role Contributor --scopes /subscriptions/<subscription_id> --query "{ client_id: appId, client_secret: password, tenant_id: tenant }"
Önemli noktalar:
- Çıkış değerlerini (
appId
,client_secret
,tenant_id
) not edin.
- Çıkış değerlerini (
Geçerli Azure aboneliğini görüntülemek için az account show komutunu çalıştırın.
az account show --query "{ subscription_id: id }"
adlı
ubuntu.pkr.hcl
bir Packer şablon değişkenleri dosyası oluşturun ve aşağıdaki kodu ekleyin. Vurgulanan satırları hizmet sorumlunuz ve Azure abonelik bilgilerinizle güncelleştirin.packer { required_plugins { azure = { source = "github.com/hashicorp/azure" version = "~> 2" } } } variable client_id { type = string default = null } variable client_secret { type = string default = null } variable subscription_id { type = string default = null } variable tenant_id { type = string default = null } variable location { default = "eastus" } variable "image_resource_group_name" { description = "Name of the resource group in which the Packer image will be created" default = "myPackerImages" } variable "oidc_request_url" { default = null } variable "oidc_request_token" { default = null } # arm builder source "azure-arm" "builder" { client_id = var.client_id client_secret = var.client_secret image_offer = "UbuntuServer" image_publisher = "canonical" image_sku = "16.04-LTS" location = var.location managed_image_name = "myPackerImage" managed_image_resource_group_name = var.image_resource_group_name os_type = "Linux" subscription_id = var.subscription_id tenant_id = var.tenant_id oidc_request_url = var.oidc_request_url oidc_request_token = var.oidc_request_token vm_size = "Standard_DS2_v2" azure_tags = { "dept" : "Engineering", "task" : "Image deployment", } } build { sources = ["source.azure-arm.builder"] provisioner "shell" { 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", ] } }
Önemli noktalar:
client_id
,client_secret
vetenant_id
alanlarını hizmet sorumlunuzdan ilgili değerlere ayarlayın.subscription_id
Alanı Azure abonelik kimliğiniz olarak ayarlayın.
Packer görüntüsünü oluşturun.
packer build ubuntu.json
3. Terraform kodunu uygulama
Örnek Terraform kodunu test etmek ve geçerli dizin yapmak için bir dizin oluşturun.
adlı
main.tf
bir dosya oluşturun ve aşağıdaki kodu ekleyin:terraform { required_version = ">=0.12" required_providers { azurerm = { source = "hashicorp/azurerm" version = "~>3.0" } azapi = { source = "Azure/azapi" version = "~> 1.0" } local = { source = "hashicorp/local" version = "2.4.0" } random = { source = "hashicorp/random" version = "3.5.1" } tls = { source = "hashicorp/tls" version = "4.0.4" } } } provider "azurerm" { features { resource_group { prevent_deletion_if_contains_resources = false } } } resource "random_pet" "id" {} resource "azurerm_resource_group" "vmss" { name = coalesce(var.resource_group_name, "201-vmss-packer-jumpbox-${random_pet.id.id}") location = var.location tags = var.tags } resource "random_string" "fqdn" { length = 6 special = false upper = false numeric = 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" { loadbalancer_id = azurerm_lb.vmss.id name = "ssh-running-probe" port = var.application_port } resource "azurerm_lb_rule" "lbnatrule" { loadbalancer_id = azurerm_lb.vmss.id name = "http" protocol = "Tcp" frontend_port = var.application_port backend_port = var.application_port backend_address_pool_ids = [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 "azapi_resource" "ssh_public_key" { type = "Microsoft.Compute/sshPublicKeys@2022-11-01" name = random_pet.id.id location = azurerm_resource_group.vmss.location parent_id = azurerm_resource_group.vmss.id } resource "azapi_resource_action" "ssh_public_key_gen" { type = "Microsoft.Compute/sshPublicKeys@2022-11-01" resource_id = azapi_resource.ssh_public_key.id action = "generateKeyPair" method = "POST" response_export_values = ["publicKey", "privateKey"] } resource "random_password" "password" { count = var.admin_password == null ? 1 : 0 length = 20 } locals { admin_password = try(random_password.password[0].result, var.admin_password) } 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 = local.admin_password } os_profile_linux_config { disable_password_authentication = true ssh_keys { path = "/home/azureuser/.ssh/authorized_keys" key_data = azapi_resource_action.ssh_public_key_gen.output.publicKey } } 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 = local.admin_password } os_profile_linux_config { disable_password_authentication = true ssh_keys { path = "/home/azureuser/.ssh/authorized_keys" key_data = azapi_resource_action.ssh_public_key_gen.output.publicKey } } tags = var.tags }
Proje değişkenlerini içerecek adlı
variables.tf
bir dosya oluşturun ve aşağıdaki kodu ekleyin: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 = null } 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" default = null }
Terraform'un hangi değerleri görüntüleyeceğini belirtmek için adlı
output.tf
bir dosya oluşturun ve aşağıdaki kodu ekleyin: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 komutunu çalıştırın. Bu komut, Azure kaynaklarınızı yönetmek için gereken Azure sağlayıcısını indirir.
terraform init -upgrade
Önemli noktalar:
-upgrade
parametresi, gerekli sağlayıcı eklentilerini yapılandırmanın sürüm kısıtlamalarına uygun en yeni sürüme yükseltir.
5. Terraform yürütme planı oluşturma
Terraform planını çalıştırarak yürütme planı oluşturun.
terraform plan -out main.tfplan
Önemli noktalar:
- komutu
terraform plan
bir yürütme planı oluşturur ancak yürütmez. Bunun yerine, yapılandırma dosyalarınızda 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 beklentilerinizle eşleşip eşleşmediğini doğrulamanızı sağlar. - İsteğe bağlı
-out
parametresi, plan için bir çıkış dosyası belirtmenize olanak tanır. parametresinin-out
kullanılması, gözden geçirdiğiniz planın tam olarak uygulanan plan olmasını sağlar.
6. Terraform yürütme planı uygulama
Yürütme planını bulut altyapınıza uygulamak için terraform apply komutunu çalıştırın.
terraform apply main.tfplan
Önemli noktalar:
- Örnek
terraform apply
komut, daha önce komutunu çalıştırdığınızıterraform plan -out main.tfplan
varsayar. - parametresi için
-out
farklı bir dosya adı belirttiyseniz, çağrısındaterraform apply
aynı dosya adını kullanın. - parametresini
-out
kullanmadıysanız, parametresiz olarak çağırınterraform apply
.
7. Sonuçları doğrulayın
Komutun çıkışında
terraform apply
aşağıdaki değerleri görürsünüz:- Sanal makine FQDN
- Jumpbox FQDN
- Sıçrama kutusu IP adresi
Nginx'e Hoş Geldiniz! metnini içeren varsayılan bir sayfayı onaylamak için sanal makine URL'sine göz atın.
değişken dosyasında tanımlanan kullanıcı adını ve çalıştırdığınızda
terraform apply
belirttiğiniz parolayı kullanarak sıçrama kutusu VM'sine bağlanmak için SSH kullanın. Örneğin:ssh azureuser@<ip_address>
.
8. Kaynakları temizleme
Sanal makine ölçek kümesini silme
Terraform aracılığıyla oluşturulan kaynaklara artık ihtiyacınız kalmadığında aşağıdaki adımları uygulayın:
terraform planını çalıştırın ve bayrağını
destroy
belirtin.terraform plan -destroy -out main.destroy.tfplan
Önemli noktalar:
- komutu
terraform plan
bir yürütme planı oluşturur ancak yürütmez. Bunun yerine, yapılandırma dosyalarınızda 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 beklentilerinizle eşleşip eşleşmediğini doğrulamanızı sağlar. - İsteğe bağlı
-out
parametresi, plan için bir çıkış dosyası belirtmenize olanak tanır. parametresinin-out
kullanılması, gözden geçirdiğiniz planın tam olarak uygulanan plan olmasını sağlar.
- komutu
Yürütme planını uygulamak için terraform apply komutunu çalıştırın.
terraform apply main.destroy.tfplan
Paketleyici görüntüsünü ve kaynak grubunu silme
Paketleyici görüntüsünü içeren kaynak grubunu silmek için az group delete komutunu çalıştırın. Paketleyici 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