Condividi tramite


Guida introduttiva: Eseguire il backup di una macchina virtuale in Azure con Terraform

In questa guida introduttiva si creerà una macchina virtuale Windows di Azure e le risorse associate usando Terraform. Una macchina virtuale Windows di Azure è una risorsa di calcolo scalabile fornita da Azure. Si tratta di un server Windows su richiesta virtualizzato nel cloud di Azure. È possibile usarlo per distribuire, testare ed eseguire applicazioni, tra le altre cose. Oltre alla macchina virtuale, questo codice crea anche una rete virtuale, una subnet, un indirizzo IP pubblico, un gruppo di sicurezza di rete, un'interfaccia di rete, un account di archiviazione, un insieme di credenziali dei servizi di ripristino di Backup di Azure e criteri di backup.

Terraform abilita la definizione, l'anteprima e la distribuzione dell'infrastruttura cloud. Con Terraform si creano file di configurazione usando la sintassi HCL. La sintassi HCL consente di specificare il provider di servizi cloud, ad esempio Azure, e gli elementi che costituiscono l'infrastruttura cloud. Dopo aver creato i file di configurazione, si crea un piano di esecuzione che consente di visualizzare in anteprima le modifiche dell'infrastruttura prima della distribuzione. Dopo aver verificato le modifiche, è possibile applicare il piano di esecuzione per distribuire l'infrastruttura.

In questo articolo vengono illustrate le operazioni seguenti:

  • Creare un gruppo di risorse di Azure con un nome univoco.
  • Creare una rete virtuale con un nome univoco e uno spazio indirizzi specificato.
  • Creare una subnet all'interno della rete virtuale con un nome univoco e un prefisso di indirizzo specificato.
  • Creare un indirizzo IP pubblico con un nome univoco.
  • Creare un gruppo di sicurezza di rete con due regole di sicurezza per il protocollo desk remoto e il traffico Web.
  • Creare un'interfaccia di rete con un nome univoco e collegarla alla subnet e all'indirizzo IP pubblico.
  • Associare il gruppo di sicurezza di rete all'interfaccia di rete.
  • Generare un ID casuale per un nome dell'account di archiviazione univoco e inserire un account di archiviazione per la diagnostica di avvio.
  • Creare una macchina virtuale Windows con un nome univoco e generare una password casuale per la macchina virtuale.
  • Creare un insieme di credenziali di Servizi di ripristino di backup con un nome univoco.
  • Creare un criterio di backup per la macchina virtuale con frequenza giornaliera e un periodo di conservazione di sette giorni.
  • Proteggi la macchina virtuale con i criteri di backup che sono stati creati.

Prerequisiti

Implementare il codice Terraform

Il codice di esempio per questo articolo si trova nel repository GitHub di Azure Terraform . È possibile visualizzare il file di log contenente i risultati del test delle versioni correnti e precedenti di Terraform. Vedere altri articoli e codice di esempio che illustrano come usare Terraform per gestire le risorse di Azure.

  1. Creare una directory in cui testare ed eseguire il codice Terraform di esempio e impostarla come directory corrente.

  2. Creare un file denominato main.tfe inserire il codice seguente:

    resource "random_pet" "rg_name" {
      prefix = var.resource_group_name_prefix
    }
    
    resource "azurerm_resource_group" "rg" {
      location = var.resource_group_location
      name     = random_pet.rg_name.id
    }
    
    resource "random_string" "name" {
      length  = 12
      lower   = true
      upper   = false
      numeric = false
      special = false
    }
    
    # Create virtual network
    resource "azurerm_virtual_network" "my_terraform_network" {
      name                = "${random_string.name.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_string.name.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_string.name.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_string.name.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_string.name.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                              = "${random_string.name.id}-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"
      vm_agent_platform_updates_enabled = true
    
      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
      }
    }
    
    # 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 "azurerm_recovery_services_vault" "example" {
      name                = "${random_string.name.id}-vault"
      resource_group_name = azurerm_resource_group.rg.name
      location            = azurerm_resource_group.rg.location
      sku                 = "Standard"
      soft_delete_enabled = var.soft_delete_enabled
    }
    
    resource "azurerm_backup_policy_vm" "example" {
      name                = "${random_string.name.id}-policy"
      resource_group_name = azurerm_resource_group.rg.name
      recovery_vault_name = azurerm_recovery_services_vault.example.name
    
      backup {
        frequency = "Daily"
        time      = "23:00"
      }
    
      retention_daily {
        count = 7
      }
    }
    
    resource "azurerm_backup_protected_vm" "example" {
      resource_group_name = azurerm_resource_group.rg.name
      recovery_vault_name = azurerm_recovery_services_vault.example.name
      source_vm_id        = azurerm_windows_virtual_machine.main.id
      backup_policy_id    = azurerm_backup_policy_vm.example.id
    }
    
  3. Creare un file denominato outputs.tfe inserire il codice seguente:

    output "resource_group_name" {
      value = azurerm_resource_group.rg.name
    }
    
    output "azurerm_recovery_services_vault_name" {
      value = azurerm_recovery_services_vault.example.name
    }
    
    output "azurerm_backup_policy_vm_name" {
      value = azurerm_backup_policy_vm.example.name
    }
    
    output "azurerm_windows_virtual_machine_name" {
      value = azurerm_windows_virtual_machine.main.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
    }
    
  4. Creare un file denominato providers.tfe inserire il codice seguente:

    terraform {
      required_version = ">=1.0"
    
      required_providers {
        azurerm = {
          source  = "hashicorp/azurerm"
          version = "~>3.0"
        }
        random = {
          source  = "hashicorp/random"
          version = "~>3.0"
        }
      }
    }
    
    provider "azurerm" {
      features {
        recovery_service {
          vm_backup_stop_protection_and_retain_data_on_destroy = true
          purge_protected_items_from_vault_on_destroy          = true
        }
      }
    }
    
  5. Creare un file denominato variables.tfe inserire il codice seguente:

    variable "resource_group_location" {
      type        = string
      default     = "eastus"
      description = "Location of the resource group."
    }
    
    variable "resource_group_name_prefix" {
      type        = string
      default     = "rg"
      description = "Prefix of the resource group name that's combined with a random ID so name is unique in your Azure subscription."
    }
    
    variable "soft_delete_enabled" {
      type        = bool
      default     = false
      nullable    = false
      description = "Is soft delete enable for the recovery services vault?"
    }
    

Importante

Se si usa il provider azurerm 4.x, è necessario specificare in modo esplicito l'ID sottoscrizione di Azure per l'autenticazione in Azure prima di eseguire i comandi terraform.

Un modo per specificare l'ID sottoscrizione di Azure senza inserirlo nel providers blocco consiste nel specificare l'ID sottoscrizione in una variabile di ambiente denominata ARM_SUBSCRIPTION_ID.

Per altre informazioni, vedere la documentazione di riferimento del provider di Azure.

Inizializzare Terraform

Eseguire terraform init per inizializzare la distribuzione di Terraform. Questo comando scarica il provider di Azure necessario per gestire le risorse di Azure.

terraform init -upgrade

Punti chiave:

  • Il parametro -upgrade aggiorna i plug-in del provider necessari alla versione più recente conforme ai vincoli di versione della configurazione.

Creare un piano di esecuzione Terraform

Eseguire terraform plan per creare un piano di esecuzione.

terraform plan -out main.tfplan

Punti chiave:

  • Il comando terraform plan crea un piano di esecuzione, ma non lo esegue. Determina invece le azioni necessarie per creare la configurazione specificata nei file di configurazione. Questo modello consente di verificare se il piano di esecuzione corrisponde alle aspettative prima di apportare modifiche alle risorse effettive.
  • Il parametro facoltativo -out consente di specificare un file di output per il piano. L'uso del parametro -out garantisce che il piano esaminato sia esattamente quello applicato.

Applicare un piano di esecuzione Terraform

Eseguire terraform apply per applicare il piano di esecuzione all'infrastruttura cloud.

terraform apply main.tfplan

Punti chiave:

  • Il comando terraform apply di esempio presuppone che in precedenza sia stato eseguito terraform plan -out main.tfplan.
  • Se è stato specificato un nome file diverso per il parametro -out, usare lo stesso nome file nella chiamata a terraform apply.
  • Se non è stato usato il parametro -out, chiamare terraform apply senza parametri.

Verificare i risultati

  1. Ottenere il nome del gruppo di risorse di Azure.

    resource_group_name = $(terraform outout -raw azurerm_resource_group_name)
    
  2. Ottenere il nome dell'insieme di credenziali di Servizi di ripristino di backup.

    recovery_services_vault_name = $(terraform output -raw azurerm_recovery_services_vault_name)
    
  3. Ottenere il nome della macchina virtuale Windows.

    windows_virtual_machine_name = $(terraform output -raw azurerm_windows_virtual_machine_name)
    
  4. Eseguire az backup protection backup-now per avviare un processo di backup.

    az backup protection backup-now --resource-group $resource_group_name \
                                    --vault-name $recovery_services_vault_name \
                                    --container-name $windows_virtual_machine_name \
                                    --item-name $windows_virtual_machine_name \
                                    --backup-management-type AzureIaaSVM
    
  5. Eseguire az backup job list per monitorare il processo di backup. Quando lo stato del processo di backup segnala Completato, la macchina virtuale è protetta con i servizi di ripristino di backup e ha un punto di recupero completo archiviato.

    az backup job list --resource-group $resource_group_name \
                       --vault-name $recovery_services_vault_name \
                       --output table
    

Pulire le risorse

Quando le risorse create tramite Terraform non sono più necessarie, seguire questa procedura:

  1. Eseguire terraform plan e specificare il destroy flag.

    terraform plan -destroy -out main.destroy.tfplan
    

    Punti chiave:

    • Il comando terraform plan crea un piano di esecuzione, ma non lo esegue. Determina invece le azioni necessarie per creare la configurazione specificata nei file di configurazione. Questo modello consente di verificare se il piano di esecuzione corrisponde alle aspettative prima di apportare modifiche alle risorse effettive.
    • Il parametro facoltativo -out consente di specificare un file di output per il piano. L'uso del parametro -out garantisce che il piano esaminato sia esattamente quello applicato.
  2. Eseguire terraform apply per applicare il piano di esecuzione.

    terraform apply main.destroy.tfplan
    

Risolvere i problemi di Terraform in Azure

Risolvere i problemi comuni relativi all'uso di Terraform in Azure.

Passaggi successivi