Come usare Packer per creare immagini di macchine virtuali di Linux in AzureHow to use Packer to create Linux virtual machine images in Azure

Ogni macchina virtuale (VM, Virtual Machine) in Azure viene creata a partire da un'immagine che ne definisce la distribuzione di Linux e la versione del sistema operativo.Each virtual machine (VM) in Azure is created from an image that defines the Linux distribution and OS version. Le immagini possono includere applicazioni e configurazioni preinstallate.Images can include pre-installed applications and configurations. In Microsoft Azure Marketplace sono disponibili molte prime immagini e immagini di terze parti per gli ambienti applicativi e di distribuzione più diffusi. In alternativa, è possibile creare immagini personalizzate su misura per le proprie esigenze.The Azure Marketplace provides many first and third-party images for most common distributions and application environments, or you can create your own custom images tailored to your needs. Questo articolo illustra in dettaglio come definire e compilare immagini personalizzate in Azure tramite lo strumento open source Packer.This article details how to use the open source tool Packer to define and build custom images in Azure.

Creare un gruppo di risorse di AzureCreate Azure resource group

Durante il processo di compilazione della macchina virtuale di origine Packer crea risorse di Azure temporanee.During the build process, Packer creates temporary Azure resources as it builds the source VM. Per acquisire la macchina virtuale di origine per usarla come immagine, è necessario definire un gruppo di risorse,To capture that source VM for use as an image, you must define a resource group. nel quale verrà archiviato l'output del processo di compilazione di Packer.The output from the Packer build process is stored in this resource group.

Come prima cosa creare un gruppo di risorse con az group create.Create a resource group with az group create. L'esempio seguente crea un gruppo di risorse denominato myResourceGroup nella posizione eastus:The following example creates a resource group named myResourceGroup in the eastus location:

az group create -n myResourceGroup -l eastus

Creare credenziali di AzureCreate Azure credentials

Per eseguire l'autenticazione con Azure, Packer usa un'entità servizio.Packer authenticates with Azure using a service principal. Un'entità servizio di Azure è un'identità di sicurezza che è possibile usare con le app, con i servizi e con strumenti di automazione come Packer.An Azure service principal is a security identity that you can use with apps, services, and automation tools like Packer. Le autorizzazioni per le operazioni che l'entità servizio può eseguire in Azure vengono controllate e definite dall'utente.You control and define the permissions as to what operations the service principal can perform in Azure.

Creare un'entità servizio con az ad sp create-for-rbac e generare l'output delle credenziali necessarie per Packer:Create a service principal with az ad sp create-for-rbac and output the credentials that Packer needs:

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

Ecco un esempio di output dei comandi precedenti:An example of the output from the preceding commands is as follows:

{
    "client_id": "f5b6a5cf-fbdf-4a9f-b3b8-3c2cd00225a4",
    "client_secret": "0e760437-bf34-4aad-9f8d-870be799c55d",
    "tenant_id": "72f988bf-86f1-41af-91ab-2d7cd011db47"
}

Per eseguire l'autenticazione in Azure, è anche necessario ottenere l'ID della sottoscrizione di Azure con az account show:To authenticate to Azure, you also need to obtain your Azure subscription ID with az account show:

az account show --query "{ subscription_id: id }"

L'output di questi due comandi verrà usato nel passaggio successivo.You use the output from these two commands in the next step.

Definire un modello di PackerDefine Packer template

Per compilare immagini, è necessario creare un modello come file JSON.To build images, you create a template as a JSON file. Nel modello si definiscono i compilatori e gli strumenti di provisioning che eseguono il processo di compilazione effettivo.In the template, you define builders and provisioners that carry out the actual build process. Packer è dotato di uno strumento di provisioning per Azure che consente di definire risorse di Azure, ad esempio le credenziali delle entità servizio create nel passaggio precedente.Packer has a provisioner for Azure that allows you to define Azure resources, such as the service principal credentials created in the preceding step.

Creare un file con nome ubuntu.json e incollare al suo interno il contenuto seguente.Create a file named ubuntu.json and paste the following content. Immettere valori personalizzati per i parametri seguenti:Enter your own values for the following:

ParametroParameter OrigineWhere to obtain
client_idclient_id Prima riga di output da az ad sp create command - appIdFirst line of output from az ad sp create command - appId
client_secretclient_secret Seconda riga di output da az ad sp create command - passwordSecond line of output from az ad sp create command - password
tenant_idtenant_id Terza riga di output da az ad sp create command - tenantThird line of output from az ad sp create command - tenant
subscription_idsubscription_id Output del comando az account showOutput from az account show command
managed_image_resource_group_namemanaged_image_resource_group_name Nome del gruppo di risorse creato nel primo passaggioName of resource group you created in the first step
managed_image_namemanaged_image_name Nome per l'immagine del disco gestito che viene creataName for the managed disk image that is created
{
  "builders": [{
    "type": "azure-arm",

    "client_id": "f5b6a5cf-fbdf-4a9f-b3b8-3c2cd00225a4",
    "client_secret": "0e760437-bf34-4aad-9f8d-870be799c55d",
    "tenant_id": "72f988bf-86f1-41af-91ab-2d7cd011db47",
    "subscription_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx",

    "managed_image_resource_group_name": "myResourceGroup",
    "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"
  }]
}

Questo modello compila un'immagine di Ubuntu 16.04 LTS, installa NGINX, quindi effettua il deprovisioning della macchina virtuale.This template builds an Ubuntu 16.04 LTS image, installs NGINX, then deprovisions the VM.

Nota

Se si espande questo modello per eseguire il provisioning delle credenziali utente, modificare il comando dello strumento di provisioning che effettua il deprovisioning dell'agente di Azure per leggere -deprovision anziché deprovision+user.If you expand on this template to provision user credentials, adjust the provisioner command that deprovisions the Azure agent to read -deprovision rather than deprovision+user. Il flag +user rimuove tutti gli account utente dalla macchina virtuale di origine.The +user flag removes all user accounts from the source VM.

Compilare l'immagine in PackerBuild Packer image

Se Packer non è installato nel computer locale, seguire le istruzioni di installazione di Packer.If you don't already have Packer installed on your local machine, follow the Packer installation instructions.

Compilare l'immagine specificando il file del modello di Packer come segue:Build the image by specifying your Packer template file as follows:

./packer build ubuntu.json

Ecco un esempio di output dei comandi precedenti:An example of the output from the preceding commands is as follows:

azure-arm output will be in this color.

==> azure-arm: Running builder ...
    azure-arm: Creating Azure Resource Manager (ARM) client ...
==> azure-arm: Creating resource group ...
==> azure-arm:  -> ResourceGroupName : ‘packer-Resource-Group-swtxmqm7ly’
==> azure-arm:  -> Location          : ‘East US’
==> azure-arm:  -> Tags              :
==> azure-arm:  ->> dept : Engineering
==> azure-arm:  ->> task : Image deployment
==> azure-arm: Validating deployment template ...
==> azure-arm:  -> ResourceGroupName : ‘packer-Resource-Group-swtxmqm7ly’
==> azure-arm:  -> DeploymentName    : ‘pkrdpswtxmqm7ly’
==> azure-arm: Deploying deployment template ...
==> azure-arm:  -> ResourceGroupName : ‘packer-Resource-Group-swtxmqm7ly’
==> azure-arm:  -> DeploymentName    : ‘pkrdpswtxmqm7ly’
==> azure-arm: Getting the VM’s IP address ...
==> azure-arm:  -> ResourceGroupName   : ‘packer-Resource-Group-swtxmqm7ly’
==> azure-arm:  -> PublicIPAddressName : ‘packerPublicIP’
==> azure-arm:  -> NicName             : ‘packerNic’
==> azure-arm:  -> Network Connection  : ‘PublicEndpoint’
==> azure-arm:  -> IP Address          : ‘40.76.218.147’
==> azure-arm: Waiting for SSH to become available...
==> azure-arm: Connected to SSH!
==> azure-arm: Provisioning with shell script: /var/folders/h1/ymh5bdx15wgdn5hvgj1wc0zh0000gn/T/packer-shell868574263
    azure-arm: WARNING! The waagent service will be stopped.
    azure-arm: WARNING! Cached DHCP leases will be deleted.
    azure-arm: WARNING! root password will be disabled. You will not be able to login as root.
    azure-arm: WARNING! /etc/resolvconf/resolv.conf.d/tail and /etc/resolvconf/resolv.conf.d/original will be deleted.
    azure-arm: WARNING! packer account and entire home directory will be deleted.
==> azure-arm: Querying the machine’s properties ...
==> azure-arm:  -> ResourceGroupName : ‘packer-Resource-Group-swtxmqm7ly’
==> azure-arm:  -> ComputeName       : ‘pkrvmswtxmqm7ly’
==> azure-arm:  -> Managed OS Disk   : ‘/subscriptions/guid/resourceGroups/packer-Resource-Group-swtxmqm7ly/providers/Microsoft.Compute/disks/osdisk’
==> azure-arm: Powering off machine ...
==> azure-arm:  -> ResourceGroupName : ‘packer-Resource-Group-swtxmqm7ly’
==> azure-arm:  -> ComputeName       : ‘pkrvmswtxmqm7ly’
==> azure-arm: Capturing image ...
==> azure-arm:  -> Compute ResourceGroupName : ‘packer-Resource-Group-swtxmqm7ly’
==> azure-arm:  -> Compute Name              : ‘pkrvmswtxmqm7ly’
==> azure-arm:  -> Compute Location          : ‘East US’
==> azure-arm:  -> Image ResourceGroupName   : ‘myResourceGroup’
==> azure-arm:  -> Image Name                : ‘myPackerImage’
==> azure-arm:  -> Image Location            : ‘eastus’
==> azure-arm: Deleting resource group ...
==> azure-arm:  -> ResourceGroupName : ‘packer-Resource-Group-swtxmqm7ly’
==> azure-arm: Deleting the temporary OS disk ...
==> azure-arm:  -> OS Disk : skipping, managed disk was used...
Build ‘azure-arm’ finished.

==> Builds finished. The artifacts of successful builds are:
--> azure-arm: Azure.ResourceManagement.VMImage:

ManagedImageResourceGroupName: myResourceGroup
ManagedImageName: myPackerImage
ManagedImageLocation: eastus

Creare una macchina virtuale da un'immagine di AzureCreate VM from Azure Image

È ora possibile creare una macchina virtuale dall'immagine con az vm create.You can now create a VM from your Image with az vm create. Specificare l'immagine creata con il parametro --image.Specify the Image you created with the --image parameter. L'esempio seguente crea una macchina virtuale denominata myVM da myPackerImage e genera chiavi SSH, se non esistono ancora:The following example creates a VM named myVM from myPackerImage and generates SSH keys if they do not already exist:

az vm create \
    --resource-group myResourceGroup \
    --name myVM \
    --image myPackerImage \
    --admin-username azureuser \
    --generate-ssh-keys

La creazione della macchina virtuale richiede alcuni minuti.It takes a few minutes to create the VM. Dopo aver creato la macchina virtuale, prendere nota dell'indirizzo publicIpAddress visualizzato dall'interfaccia della riga di comando di Azure.Once the VM has been created, take note of the publicIpAddress displayed by the Azure CLI. Questo indirizzo viene usato per accedere al sito NGINX tramite un Web browser.This address is used to access the NGINX site via a web browser.

Per consentire al traffico Web di raggiungere la macchina virtuale, aprire la porta 80 da Internet con il comando az vm open_port:To allow web traffic to reach your VM, open port 80 from the Internet with az vm open-port:

az vm open-port \
    --resource-group myResourceGroup \
    --name myVM \
    --port 80

Testare la macchina virtuale e NGINXTest VM and NGINX

È ora possibile aprire un Web browser e immettere http://publicIpAddress bella barra degli indirizzi.Now you can open a web browser and enter http://publicIpAddress in the address bar. Fornire il proprio indirizzo IP pubblico dal processo di creazione della macchina virtuale.Provide your own public IP address from the VM create process. La pagina NGINX predefinita viene visualizzata come illustrato nell'esempio seguente:The default NGINX page is displayed as in the following example:

Sito NGINX predefinito

Passaggi successiviNext steps

In questo esempio Packer è stato usato per creare un'immagine di macchina virtuale con NGINX già installato.In this example, you used Packer to create a VM image with NGINX already installed. È possibile usare questa immagine di macchina virtuale insieme a flussi di lavoro di distribuzione esistenti, ad esempio per distribuire app in macchine virtuali create dall'immagine con Ansible, Chef o Puppet.You can use this VM image alongside existing deployment workflows, such as to deploy your app to VMs created from the Image with Ansible, Chef, or Puppet.

Per altri modelli di Packer di esempio per distribuzioni di Linux di altro tipo, vedere questo repository di GitHub.For additional example Packer templates for other Linux distros, see this GitHub repo.