Creare un'infrastruttura completa per la macchina virtuale Linux in Azure con TerraformCreate a complete Linux virtual machine infrastructure in Azure with Terraform

Terraform consente di definire e creare distribuzioni di infrastrutture complete in Azure.Terraform allows you to define and create complete infrastructure deployments in Azure. I modelli Terrraform, compilati dall'utente in un formato leggibile, creano e configurano le risorse di Azure in modo coerente e riproducibile.You build Terraform templates in a human-readable format that create and configure Azure resources in a consistent, reproducible manner. In questo articolo viene illustrato come creare un ambiente Linux completo e le risorse di supporto con Terraform.This article shows you how to create a complete Linux environment and supporting resources with Terraform. È anche possibile apprendere come installare e configurare Terraform.You can also learn how to Install and configure Terraform.

Creare una connessione ad Azure e il gruppo di risorseCreate Azure connection and resource group

Verranno ora esaminate le singole sezioni di un modello Terraform.Let's go through each section of a Terraform template. È anche disponibile una versione completa del modello Terraform che può essere copiata e incollata.You can also see the full version of the Terraform template that you can copy and paste.

La sezione provider indica a Terraform di usare un provider di Azure.The provider section tells Terraform to use an Azure provider. Per ottenere i valori per subscription_id, client_id, client_secret e tenant_id, vedere Installare e configurare Terraform per eseguire il provisioning di macchine virtuali e altra infrastruttura in Azure.To get values for subscription_id, client_id, client_secret, and tenant_id, see Install and configure Terraform.

Suggerimento

Se si creano variabili di ambiente per i valori o si usa l'esperienza Azure Cloud Shell Bash, non è necessario includere le dichiarazioni di variabili in questa sezione.If you create environment variables for the values or are using the Azure Cloud Shell Bash experience , you don't need to include the variable declarations in this section.

provider "azurerm" {
    subscription_id = "xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
    client_id       = "xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
    client_secret   = "xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
    tenant_id       = "xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
}

Nella sezione seguente viene creato un gruppo di risorse denominato myResourceGroup nella località eastus:The following section creates a resource group named myResourceGroup in the eastus location:

resource "azurerm_resource_group" "myterraformgroup" {
    name     = "myResourceGroup"
    location = "eastus"

    tags = {
        environment = "Terraform Demo"
    }
}

In altre sezioni si fa riferimento al gruppo di risorse con ${azurerm_resource_group.myterraformgroup.name} .In additional sections, you reference the resource group with ${azurerm_resource_group.myterraformgroup.name}.

Creare una rete virtualeCreate virtual network

La sezione seguente crea una rete virtuale denominata myVnet nello spazio di indirizzi 10.0.0.0/16:The following section creates a virtual network named myVnet in the 10.0.0.0/16 address space:

resource "azurerm_virtual_network" "myterraformnetwork" {
    name                = "myVnet"
    address_space       = ["10.0.0.0/16"]
    location            = "eastus"
    resource_group_name = azurerm_resource_group.myterraformgroup.name

    tags = {
        environment = "Terraform Demo"
    }
}

La sezione seguente crea una subnet denominata mySubnet nella rete virtuale myVnet:The following section creates a subnet named mySubnet in the myVnet virtual network:

resource "azurerm_subnet" "myterraformsubnet" {
    name                 = "mySubnet"
    resource_group_name  = azurerm_resource_group.myterraformgroup.name
    virtual_network_name = azurerm_virtual_network.myterraformnetwork.name
    address_prefix       = "10.0.2.0/24"
}

Creare un indirizzo IP pubblicoCreate public IP address

Per accedere alle risorse in Internet, creare e assegnare un indirizzo IP pubblico alla macchina virtuale.To access resources across the Internet, create and assign a public IP address to your VM. La sezione seguente crea un indirizzo IP pubblico denominato myPublicIP:The following section creates a public IP address named myPublicIP:

resource "azurerm_public_ip" "myterraformpublicip" {
    name                         = "myPublicIP"
    location                     = "eastus"
    resource_group_name          = azurerm_resource_group.myterraformgroup.name
    allocation_method            = "Dynamic"

    tags = {
        environment = "Terraform Demo"
    }
}

Creare un gruppo di sicurezza di reteCreate Network Security Group

I gruppi di sicurezza di rete consentono di controllare il flusso del traffico di rete in ingresso e in uscita dalla macchina virtuale.Network Security Groups control the flow of network traffic in and out of your VM. La sezione seguente crea un gruppo di sicurezza di rete denominato myNetworkSecurityGroup e definisce una regola per consentire il traffico SSH sulla porta TCP 22:The following section creates a network security group named myNetworkSecurityGroup and defines a rule to allow SSH traffic on TCP port 22:

resource "azurerm_network_security_group" "myterraformnsg" {
    name                = "myNetworkSecurityGroup"
    location            = "eastus"
    resource_group_name = azurerm_resource_group.myterraformgroup.name
    
    security_rule {
        name                       = "SSH"
        priority                   = 1001
        direction                  = "Inbound"
        access                     = "Allow"
        protocol                   = "Tcp"
        source_port_range          = "*"
        destination_port_range     = "22"
        source_address_prefix      = "*"
        destination_address_prefix = "*"
    }

    tags = {
        environment = "Terraform Demo"
    }
}

Creare la scheda di interfaccia di rete virtualeCreate virtual network interface card

Una scheda di interfaccia di rete virtuale, NIC, connette la macchina virtuale a una rete virtuale specifica, a un indirizzo IP pubblico e a un gruppo di sicurezza di rete.A virtual network interface card (NIC) connects your VM to a given virtual network, public IP address, and network security group. La sezione seguente in un modello Terraform crea una scheda di interfaccia di rete virtuale denominata myNIC connessa alle risorse di rete virtuale create:The following section in a Terraform template creates a virtual NIC named myNIC connected to the virtual networking resources you have created:

resource "azurerm_network_interface" "myterraformnic" {
    name                        = "myNIC"
    location                    = "eastus"
    resource_group_name         = azurerm_resource_group.myterraformgroup.name
    network_security_group_id   = azurerm_network_security_group.myterraformnsg.id

    ip_configuration {
        name                          = "myNicConfiguration"
        subnet_id                     = "${azurerm_subnet.myterraformsubnet.id}"
        private_ip_address_allocation = "Dynamic"
        public_ip_address_id          = "${azurerm_public_ip.myterraformpublicip.id}"
    }

    tags = {
        environment = "Terraform Demo"
    }
}

Creare un account di archiviazione per la diagnosticaCreate storage account for diagnostics

Per archiviare la diagnostica di avvio per una macchina virtuale, è necessario un account di archiviazione.To store boot diagnostics for a VM, you need a storage account. La diagnostica di avvio può aiutare a risolvere i problemi e a monitorare lo stato della macchina virtuale.These boot diagnostics can help you troubleshoot problems and monitor the status of your VM. L'account di archiviazione creato viene usato solo per archiviare i dati della diagnostica di avvio.The storage account you create is only to store the boot diagnostics data. Poiché ogni account di archiviazione deve avere un nome univoco, la sezione seguente genera un testo casuale:As each storage account must have a unique name, the following section generates some random text:

resource "random_id" "randomId" {
    keepers = {
        # Generate a new ID only when a new resource group is defined
        resource_group = azurerm_resource_group.myterraformgroup.name
    }
    
    byte_length = 8
}

A questo punto è possibile creare un account di archiviazione.Now you can create a storage account. La sezione seguente crea un account di archiviazione con il nome basato sul testo casuale generato nel passaggio precedente:The following section creates a storage account, with the name based on the random text generated in the preceding step:

resource "azurerm_storage_account" "mystorageaccount" {
    name                        = "diag${random_id.randomId.hex}"
    resource_group_name         = azurerm_resource_group.myterraformgroup.name
    location                    = "eastus"
    account_replication_type    = "LRS"
    account_tier                = "Standard"

    tags = {
        environment = "Terraform Demo"
    }
}

Creare una macchina virtualeCreate virtual machine

Il passaggio finale consiste nel creare una macchina virtuale e usare tutte le risorse create.The final step is to create a VM and use all the resources created. La sezione seguente crea una macchina virtuale denominata myVM e associa la scheda di rete virtuale denominata myNIC.The following section creates a VM named myVM and attaches the virtual NIC named myNIC. Viene usata l'immagine più recente di Ubuntu 16.04-LTS e viene creato un nome utente azureuser con autenticazione della password disabilitata.The latest Ubuntu 16.04-LTS image is used, and a user named azureuser is created with password authentication disabled.

I dati della chiave SSH vengono indicati nella sezione ssh_keys.SSH key data is provided in the ssh_keys section. Fornire una chiave SSH pubblica valida nel campo key_data.Provide a valid public SSH key in the key_data field.

resource "azurerm_virtual_machine" "myterraformvm" {
    name                  = "myVM"
    location              = "eastus"
    resource_group_name   = azurerm_resource_group.myterraformgroup.name
    network_interface_ids = [azurerm_network_interface.myterraformnic.id]
    vm_size               = "Standard_DS1_v2"

    storage_os_disk {
        name              = "myOsDisk"
        caching           = "ReadWrite"
        create_option     = "FromImage"
        managed_disk_type = "Premium_LRS"
    }

    storage_image_reference {
        publisher = "Canonical"
        offer     = "UbuntuServer"
        sku       = "16.04.0-LTS"
        version   = "latest"
    }

    os_profile {
        computer_name  = "myvm"
        admin_username = "azureuser"
    }

    os_profile_linux_config {
        disable_password_authentication = true
        ssh_keys {
            path     = "/home/azureuser/.ssh/authorized_keys"
            key_data = "ssh-rsa AAAAB3Nz{snip}hwhqT9h"
        }
    }

    boot_diagnostics {
        enabled     = "true"
        storage_uri = azurerm_storage_account.mystorageaccount.primary_blob_endpoint
    }

    tags = {
        environment = "Terraform Demo"
    }
}

Completare lo script TerraformComplete Terraform script

Per riunire tutte queste sezioni e vedere Terraform in azione, creare un file denominato terraform_azure.tf e incollarvi il contenuto seguente:To bring all these sections together and see Terraform in action, create a file called terraform_azure.tf and paste the following content:

# Configure the Microsoft Azure Provider
provider "azurerm" {
    subscription_id = "xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
    client_id       = "xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
    client_secret   = "xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
    tenant_id       = "xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
}

# Create a resource group if it doesn’t exist
resource "azurerm_resource_group" "myterraformgroup" {
    name     = "myResourceGroup"
    location = "eastus"

    tags = {
        environment = "Terraform Demo"
    }
}

# Create virtual network
resource "azurerm_virtual_network" "myterraformnetwork" {
    name                = "myVnet"
    address_space       = ["10.0.0.0/16"]
    location            = "eastus"
    resource_group_name = azurerm_resource_group.myterraformgroup.name

    tags = {
        environment = "Terraform Demo"
    }
}

# Create subnet
resource "azurerm_subnet" "myterraformsubnet" {
    name                 = "mySubnet"
    resource_group_name  = azurerm_resource_group.myterraformgroup.name
    virtual_network_name = azurerm_virtual_network.myterraformnetwork.name
    address_prefix       = "10.0.1.0/24"
}

# Create public IPs
resource "azurerm_public_ip" "myterraformpublicip" {
    name                         = "myPublicIP"
    location                     = "eastus"
    resource_group_name          = azurerm_resource_group.myterraformgroup.name
    allocation_method            = "Dynamic"

    tags = {
        environment = "Terraform Demo"
    }
}

# Create Network Security Group and rule
resource "azurerm_network_security_group" "myterraformnsg" {
    name                = "myNetworkSecurityGroup"
    location            = "eastus"
    resource_group_name = azurerm_resource_group.myterraformgroup.name
    
    security_rule {
        name                       = "SSH"
        priority                   = 1001
        direction                  = "Inbound"
        access                     = "Allow"
        protocol                   = "Tcp"
        source_port_range          = "*"
        destination_port_range     = "22"
        source_address_prefix      = "*"
        destination_address_prefix = "*"
    }

    tags = {
        environment = "Terraform Demo"
    }
}

# Create network interface
resource "azurerm_network_interface" "myterraformnic" {
    name                      = "myNIC"
    location                  = "eastus"
    resource_group_name       = azurerm_resource_group.myterraformgroup.name
    network_security_group_id = azurerm_network_security_group.myterraformnsg.id

    ip_configuration {
        name                          = "myNicConfiguration"
        subnet_id                     = azurerm_subnet.myterraformsubnet.id
        private_ip_address_allocation = "Dynamic"
        public_ip_address_id          = azurerm_public_ip.myterraformpublicip.id
    }

    tags = {
        environment = "Terraform Demo"
    }
}

# Generate random text for a unique storage account name
resource "random_id" "randomId" {
    keepers = {
        # Generate a new ID only when a new resource group is defined
        resource_group = azurerm_resource_group.myterraformgroup.name
    }
    
    byte_length = 8
}

# Create storage account for boot diagnostics
resource "azurerm_storage_account" "mystorageaccount" {
    name                        = "diag${random_id.randomId.hex}"
    resource_group_name         = azurerm_resource_group.myterraformgroup.name
    location                    = "eastus"
    account_tier                = "Standard"
    account_replication_type    = "LRS"

    tags = {
        environment = "Terraform Demo"
    }
}

# Create virtual machine
resource "azurerm_virtual_machine" "myterraformvm" {
    name                  = "myVM"
    location              = "eastus"
    resource_group_name   = azurerm_resource_group.myterraformgroup.name
    network_interface_ids = [azurerm_network_interface.myterraformnic.id]
    vm_size               = "Standard_DS1_v2"

    storage_os_disk {
        name              = "myOsDisk"
        caching           = "ReadWrite"
        create_option     = "FromImage"
        managed_disk_type = "Premium_LRS"
    }

    storage_image_reference {
        publisher = "Canonical"
        offer     = "UbuntuServer"
        sku       = "16.04.0-LTS"
        version   = "latest"
    }

    os_profile {
        computer_name  = "myvm"
        admin_username = "azureuser"
    }

    os_profile_linux_config {
        disable_password_authentication = true
        ssh_keys {
            path     = "/home/azureuser/.ssh/authorized_keys"
            key_data = "ssh-rsa AAAAB3Nz{snip}hwhqT9h"
        }
    }

    boot_diagnostics {
        enabled = "true"
        storage_uri = azurerm_storage_account.mystorageaccount.primary_blob_endpoint
    }

    tags = {
        environment = "Terraform Demo"
    }
}

Compilare e distribuire l'infrastrutturaBuild and deploy the infrastructure

Con il modello Terraform creato, il primo passaggio consiste nell'inizializzare Terraform.With your Terraform template created, the first step is to initialize Terraform. Questo passaggio assicura che Terraform disponga di tutti i prerequisiti necessari per compilare il modello in Azure.This step ensures that Terraform has all the prerequisites to build your template in Azure.

terraform init

Il passaggio successivo riguarda la revisione di Terraform e la convalida del modello.The next step is to have Terraform review and validate the template. Questo passaggio confronta le risorse richieste con le informazioni sullo stato salvate da Terraform e quindi restituisce l'esecuzione pianificata.This step compares the requested resources to the state information saved by Terraform and then outputs the planned execution. Non vengono create risorse in Azure.Resources are not created in Azure.

terraform plan

Dopo l'esecuzione del comando viene visualizzata una schermata simile alla seguente:After you execute the previous command, you should see something like the following screen:

Refreshing Terraform state in-memory prior to plan...
The refreshed state will be used to calculate this plan, but will not be
persisted to local or remote state storage.


...

Note: You didn’t specify an “-out” parameter to save this plan, so when
“apply” is called, Terraform can’t guarantee this is what will execute.
  + azurerm_resource_group.myterraform
      <snip>
  + azurerm_virtual_network.myterraformnetwork
      <snip>
  + azurerm_network_interface.myterraformnic
      <snip>
  + azurerm_network_security_group.myterraformnsg
      <snip>
  + azurerm_public_ip.myterraformpublicip
      <snip>
  + azurerm_subnet.myterraformsubnet
      <snip>
  + azurerm_virtual_machine.myterraformvm
      <snip>
Plan: 7 to add, 0 to change, 0 to destroy.

Se tutti i dati sono corretti e si è pronti a compilare l'infrastruttura in Azure, applicare il modello in Terraform:If everything looks correct and you are ready to build the infrastructure in Azure, apply the template in Terraform:

terraform apply

Al termine, l'infrastruttura per la macchina virtuale è pronta.Once Terraform completes, your VM infrastructure is ready. Ottenere l'indirizzo IP pubblico della VM con az vm show:Obtain the public IP address of your VM with az vm show:

az vm show --resource-group myResourceGroup --name myVM -d --query [publicIps] --o tsv

È quindi possibile stabilire una connessione SSH alla VM:You can then SSH to your VM:

ssh azureuser@<publicIps>

Passaggi successiviNext steps

È stata creata un'infrastruttura di base in Azure usando Terraform.You have created basic infrastructure in Azure by using Terraform. Per scenari più complessi, inclusi esempi d'uso di servizi di bilanciamento del carico e set di scalabilità delle macchine virtuali, vedere i numerosi esempi di Terraform per Azure.For more complex scenarios, including examples that use load balancers and virtual machine scale sets, see numerous Terraform examples for Azure. La documentazione di Terraform include un elenco completo e aggiornato dei provider di Azure supportati.For an up-to-date list of supported Azure providers, see the Terraform documentation.