التشغيل السريع: استخدام Terraform لإنشاء جهاز ظاهري يعمل بنظام Windows

ينطبق على: ✔️ أجهزة Windows الظاهرية

توضح لك هذه المقالة كيفية إنشاء بيئة Windows كاملة ودعم الموارد باستخدام Terraform. تتضمن هذه الموارد شبكة ظاهرية وشبكة فرعية وعنوان IP عام والمزيد.

يتيح Terraform تعريف البنية الأساسية السحابية ومعاينتها ونشرها. باستخدام Terraform، يمكنك إنشاء ملفات التكوين باستخدام بناء جملة HCL. يسمح لك بناء الجملة بلغة HCL بتحديد موفر الخدمة السحابية، مثل خدمة Azure، وتحديد العناصر التي تشكل البنية الأساسية للخدمة السحابية. بعد إنشاء ملفات التكوين الخاصة بك، يمكنك إنشاء خطة تنفيذ تسمح لك بمعاينة تغييرات البنية الأساسية قبل نشرها. بمجرد التحقق من التغييرات، يمكنك تطبيق خطة التنفيذ لنشر البنية الأساسية.

في هذه المقالة، ستتعرف على كيفية:

المتطلبات الأساسية

  • اشتراك Azure: إذا لم يكن لديك اشتراك Azure، فأنشئ حسابمجاني قبل أن تبدأ.

تنفيذ كود Terraform

إشعار

يوجد نموذج التعليمات البرمجية لهذه المقالة في مستودع Azure Terraform GitHub. يمكنك عرض ملف السجل الذي يحتوي على نتائج الاختبار من الإصدارات الحالية والسابقة من Terraform.

راجع المزيد من المقالات ونماذج التعليمات البرمجية التي توضح كيفية استخدام Terraform لإدارة موارد Azure

  1. قم بإنشاء دليل لاختبار نموذج التعليمة البرمجية لـ Terraform وجعله الدليل الحالي.

  2. قم بإنشاء ملف باسم providers.tf وأدخل التعليمة البرمجية التالية:

    terraform {
      required_version = ">=1.0"
    
      required_providers {
        azurerm = {
          source  = "hashicorp/azurerm"
          version = "~>3.0"
        }
        random = {
          source  = "hashicorp/random"
          version = "~>3.0"
        }
      }
    }
    
    provider "azurerm" {
      features {}
    }
    
  3. قم بإنشاء ملف باسم main.tf وأدخل التعليمة البرمجية التالية:

    resource "azurerm_resource_group" "rg" {
      location = var.resource_group_location
      name     = "${random_pet.prefix.id}-rg"
    }
    
    # Create virtual network
    resource "azurerm_virtual_network" "my_terraform_network" {
      name                = "${random_pet.prefix.id}-vnet"
      address_space       = ["10.0.0.0/16"]
      location            = azurerm_resource_group.rg.location
      resource_group_name = azurerm_resource_group.rg.name
    }
    
    # Create subnet
    resource "azurerm_subnet" "my_terraform_subnet" {
      name                 = "${random_pet.prefix.id}-subnet"
      resource_group_name  = azurerm_resource_group.rg.name
      virtual_network_name = azurerm_virtual_network.my_terraform_network.name
      address_prefixes     = ["10.0.1.0/24"]
    }
    
    # Create public IPs
    resource "azurerm_public_ip" "my_terraform_public_ip" {
      name                = "${random_pet.prefix.id}-public-ip"
      location            = azurerm_resource_group.rg.location
      resource_group_name = azurerm_resource_group.rg.name
      allocation_method   = "Dynamic"
    }
    
    # Create Network Security Group and rules
    resource "azurerm_network_security_group" "my_terraform_nsg" {
      name                = "${random_pet.prefix.id}-nsg"
      location            = azurerm_resource_group.rg.location
      resource_group_name = azurerm_resource_group.rg.name
    
      security_rule {
        name                       = "RDP"
        priority                   = 1000
        direction                  = "Inbound"
        access                     = "Allow"
        protocol                   = "*"
        source_port_range          = "*"
        destination_port_range     = "3389"
        source_address_prefix      = "*"
        destination_address_prefix = "*"
      }
      security_rule {
        name                       = "web"
        priority                   = 1001
        direction                  = "Inbound"
        access                     = "Allow"
        protocol                   = "Tcp"
        source_port_range          = "*"
        destination_port_range     = "80"
        source_address_prefix      = "*"
        destination_address_prefix = "*"
      }
    }
    
    # Create network interface
    resource "azurerm_network_interface" "my_terraform_nic" {
      name                = "${random_pet.prefix.id}-nic"
      location            = azurerm_resource_group.rg.location
      resource_group_name = azurerm_resource_group.rg.name
    
      ip_configuration {
        name                          = "my_nic_configuration"
        subnet_id                     = azurerm_subnet.my_terraform_subnet.id
        private_ip_address_allocation = "Dynamic"
        public_ip_address_id          = azurerm_public_ip.my_terraform_public_ip.id
      }
    }
    
    # Connect the security group to the network interface
    resource "azurerm_network_interface_security_group_association" "example" {
      network_interface_id      = azurerm_network_interface.my_terraform_nic.id
      network_security_group_id = azurerm_network_security_group.my_terraform_nsg.id
    }
    
    # Create storage account for boot diagnostics
    resource "azurerm_storage_account" "my_storage_account" {
      name                     = "diag${random_id.random_id.hex}"
      location                 = azurerm_resource_group.rg.location
      resource_group_name      = azurerm_resource_group.rg.name
      account_tier             = "Standard"
      account_replication_type = "LRS"
    }
    
    
    # Create virtual machine
    resource "azurerm_windows_virtual_machine" "main" {
      name                  = "${var.prefix}-vm"
      admin_username        = "azureuser"
      admin_password        = random_password.password.result
      location              = azurerm_resource_group.rg.location
      resource_group_name   = azurerm_resource_group.rg.name
      network_interface_ids = [azurerm_network_interface.my_terraform_nic.id]
      size                  = "Standard_DS1_v2"
    
      os_disk {
        name                 = "myOsDisk"
        caching              = "ReadWrite"
        storage_account_type = "Premium_LRS"
      }
    
      source_image_reference {
        publisher = "MicrosoftWindowsServer"
        offer     = "WindowsServer"
        sku       = "2022-datacenter-azure-edition"
        version   = "latest"
      }
    
    
      boot_diagnostics {
        storage_account_uri = azurerm_storage_account.my_storage_account.primary_blob_endpoint
      }
    }
    
    # Install IIS web server to the virtual machine
    resource "azurerm_virtual_machine_extension" "web_server_install" {
      name                       = "${random_pet.prefix.id}-wsi"
      virtual_machine_id         = azurerm_windows_virtual_machine.main.id
      publisher                  = "Microsoft.Compute"
      type                       = "CustomScriptExtension"
      type_handler_version       = "1.8"
      auto_upgrade_minor_version = true
    
      settings = <<SETTINGS
        {
          "commandToExecute": "powershell -ExecutionPolicy Unrestricted Install-WindowsFeature -Name Web-Server -IncludeAllSubFeature -IncludeManagementTools"
        }
      SETTINGS
    }
    
    # Generate random text for a unique storage account name
    resource "random_id" "random_id" {
      keepers = {
        # Generate a new ID only when a new resource group is defined
        resource_group = azurerm_resource_group.rg.name
      }
    
      byte_length = 8
    }
    
    resource "random_password" "password" {
      length      = 20
      min_lower   = 1
      min_upper   = 1
      min_numeric = 1
      min_special = 1
      special     = true
    }
    
    resource "random_pet" "prefix" {
      prefix = var.prefix
      length = 1
    }
    
  4. قم بإنشاء ملف باسم variables.tf وأدخل التعليمة البرمجية التالية:

    variable "resource_group_location" {
      default     = "eastus"
      description = "Location of the resource group."
    }
    
    variable "prefix" {
      type        = string
      default     = "win-vm-iis"
      description = "Prefix of the resource name"
    }
    
  5. قم بإنشاء ملف باسم outputs.tf وأدخل التعليمة البرمجية التالية:

    output "resource_group_name" {
      value = azurerm_resource_group.rg.name
    }
    
    output "public_ip_address" {
      value = azurerm_windows_virtual_machine.main.public_ip_address
    }
    
    output "admin_password" {
      sensitive = true
      value     = azurerm_windows_virtual_machine.main.admin_password
    }
    

تهيئة Terraform

قم بتشغيل terraform init لتهيئة توزيع Terraform. يقوم هذا الأمر بتنزيل موفر Azure المطلوب لإدارة موارد Azure.

terraform init -upgrade

النقاط الرئيسية:

  • تقوم -upgrade المعلمة بترقية مكونات الموفر الإضافية الضرورية إلى أحدث إصدار يتوافق مع قيود إصدار التكوين.

إنشاء خطة تنفيذ Terraform

قم بتشغيل خطة terraform لإنشاء خطة تنفيذ.

terraform plan -out main.tfplan

النقاط الرئيسية:

  • ينشئ الأمر terraform plan خطة تنفيذ، لكنه لا ينفذها. بدلًا من ذلك، يحدد الإجراءات الضرورية لإنشاء التكوين المحدد في ملفات التكوين الخاصة بك. يسمح لك هذا النمط بالتحقق مما إذا كانت خطة التنفيذ تتطابق مع توقعاتك قبل إجراء أي تغييرات على الموارد الفعلية.
  • تسمح المعلمة -out الاختيارية بتحديد ملف الإخراج للخطة. يضمن استخدام -out المعلمة أن الخطة التي راجعتها هي بالضبط ما يتم تطبيقها.
  • لقراءة المزيد حول خطط التنفيذ والأمان المستمرين، راجع قسم تحذيرات الأمان.

تطبيق خطة تنفيذ Terraform

قم بتشغيل تطبيق terraform لتطبيق خطة التنفيذ على البنية الأساسية السحابية الخاصة بك.

terraform apply main.tfplan

النقاط الرئيسية:

  • يفترض الأمر المثال terraform apply أنك قمت بتشغيل terraform plan -out main.tfplanمسبقا .
  • إذا قمت بتحديد اسم ملف مختلف للمعلمة -out، فاستخدم نفس اسم الملف في الاستدعاء terraform apply.
  • إذا لم تستخدم المعلمة -out، استدع terraform apply دون أي معلمات.

لا يتم تقديم معلومات التكلفة أثناء عملية إنشاء الجهاز الظاهري ل Terraform كما هي لمدخل Azure. إذا كنت ترغب في معرفة المزيد حول كيفية عمل التكلفة للأجهزة الظاهرية ، راجع صفحة نظرة عامة على تحسين التكلفة.

تحقق من النتائج

  1. قم بتشغيل الأمر التالي للحصول على عنوان IP العام للجهاز الظاهري وتدوينه:

    echo $(terraform output -raw public_ip_address)
    
  2. مع IIS المثبتة والمنفذ 80 الآن افتح على الجهاز الظاهري من الإنترنت، استخدم مستعرض ويب من اختيارك لعرض صفحة الترحيب IIS الظاهري. استخدم عنوان IP العام للجهاز الظاهري الذي تم الحصول عليه من الأمر السابق. يوضح المثال التالي موقع IIS الظاهري على الويب:

    Screenshot showing the IIS default site.

تنظيف الموارد

عندما لم تعد بحاجة إلى الموارد التي تم إنشاؤها عبر Terraform، قم بالخطوات التالية:

  1. قم بتشغيل خطة terraform وحدد العلامة destroy.

    terraform plan -destroy -out main.destroy.tfplan
    

    النقاط الرئيسية:

    • ينشئ الأمر terraform plan خطة تنفيذ، لكنه لا ينفذها. بدلًا من ذلك، يحدد الإجراءات الضرورية لإنشاء التكوين المحدد في ملفات التكوين الخاصة بك. يسمح لك هذا النمط بالتحقق مما إذا كانت خطة التنفيذ تتطابق مع توقعاتك قبل إجراء أي تغييرات على الموارد الفعلية.
    • تسمح المعلمة -out الاختيارية بتحديد ملف الإخراج للخطة. يضمن استخدام -out المعلمة أن الخطة التي راجعتها هي بالضبط ما يتم تطبيقها.
    • لقراءة المزيد حول خطط التنفيذ والأمان المستمرين، راجع قسم تحذيرات الأمان.
  2. قم بتشغيل تطبيق terraform لتطبيق خطة التنفيذ.

    terraform apply main.destroy.tfplan
    

استكشاف أخطاء Terraform على Azure وإصلاحها

استكشاف المشاكل الشائعة وإصلاحها عند استخدام Terraform على Azure

الخطوات التالية

في هذا التشغيل السريع، قمت بتوزيع جهاز ظاهري بسيط باستخدام ملف Terraform. لمعرفة المزيد عن الأجهزة الظاهرية Azure، تابع البرنامج التعليمي لنظام إدارة البرامج لينكس.