Como utilizar o Packer para criar imagens de máquinas virtuais do Linux no Azure
Aplica-se a: ✔️ Conjuntos de dimensionamento flexíveis de VMs ✔️ do Linux
Cada máquina virtual (VM) no Azure é criada a partir de uma imagem que define a distribuição do Linux e a versão do SO. As imagens podem incluir aplicações e configurações pré-instaladas. O Azure Marketplace fornece muitas imagens originais e de terceiros para distribuições e ambientes de aplicações mais comuns ou pode criar as suas próprias imagens personalizadas adaptadas às suas necessidades. Este artigo detalha como utilizar a ferramenta de open source Packer para definir e criar imagens personalizadas no Azure.
Nota
O Azure tem agora um serviço, o Azure Image Builder, para definir e criar as suas próprias imagens personalizadas. O Azure Image Builder baseia-se no Packer, pelo que pode até utilizar os scripts do aprovisionador de shell do Packer existentes com o mesmo. Para começar a utilizar o Azure Image Builder, veja Criar uma VM do Linux com o Azure Image Builder.
Criar um grupo de recursos do Azure
Durante o processo de compilação, o Packer cria recursos temporários do Azure à medida que cria a VM de origem. Para capturar essa VM de origem para utilização como imagem, tem de definir um grupo de recursos. O resultado do processo de compilação do Packer é armazenado neste grupo de recursos.
Crie um grupo de recursos com az group create. O exemplo seguinte cria um grupo de recursos com o nome myResourceGroup na localização eastus :
az group create -n myResourceGroup -l eastus
Criar credenciais do Azure
O Packer autentica-se com o Azure através de um principal de serviço. Um principal de serviço do Azure é uma identidade de segurança que pode utilizar com aplicações, serviços e ferramentas de automatização, como o Packer. Pode controlar e definir as permissões relativamente às operações que o principal de serviço pode realizar no Azure.
Crie um principal de serviço com az ad sp create-for-rbac e produza as credenciais de que o Packer precisa:
az ad sp create-for-rbac --role Contributor --scopes /subscriptions/<subscription_id> --query "{ client_id: appId, client_secret: password, tenant_id: tenant }"
Um exemplo do resultado dos comandos anteriores é o seguinte:
{
"client_id": "f5b6a5cf-fbdf-4a9f-b3b8-3c2cd00225a4",
"client_secret": "0e760437-bf34-4aad-9f8d-870be799c55d",
"tenant_id": "72f988bf-86f1-41af-91ab-2d7cd011db47"
}
Para autenticar no Azure, também tem de obter o ID da subscrição do Azure com az account show:
az account show --query "{ subscription_id: id }"
Vai utilizar o resultado destes dois comandos no próximo passo.
Definir modelo Packer
Para criar imagens, crie um modelo como um ficheiro JSON. No modelo, define construtores e aprovisionadores que executam o processo de compilação real. O Packer tem um aprovisionador para o Azure que lhe permite definir recursos do Azure, como as credenciais do principal de serviço criadas no passo anterior.
Crie um ficheiro com o nome ubuntu.json e cole o seguinte conteúdo. Introduza os seus próprios valores para os seguintes parâmetros:
Parâmetro | Onde obter |
---|---|
client_id | Primeira linha de saída do az ad sp comando create - appId |
client_secret | Segunda linha de saída do az ad sp comando create - password |
tenant_id | Terceira linha de saída do az ad sp comando create - inquilino |
subscription_id | Saída do az account show comando |
managed_image_resource_group_name | Nome do grupo de recursos que criou no primeiro passo |
managed_image_name | Nome da imagem do disco gerido que é criada |
{
"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": "0001-com-ubuntu-server-jammy",
"image_sku": "22_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"
}]
}
Nota
Substitua os image_publisher
valores , image_offer
, image_sku
e inline
os comandos em conformidade.
Também pode criar um ficheiro com o nome ubuntu.pkr.hcl e colar o seguinte conteúdo com os seus próprios valores, conforme utilizado para a tabela de parâmetros acima.
source "azure-arm" "autogenerated_1" {
azure_tags = {
dept = "Engineering"
task = "Image deployment"
}
client_id = "f5b6a5cf-fbdf-4a9f-b3b8-3c2cd00225a4"
client_secret = "0e760437-bf34-4aad-9f8d-870be799c55d"
image_offer = "0001-com-ubuntu-server-jammy"
image_publisher = "canonical"
image_sku = "22_04-lts"
location = "East US"
managed_image_name = "myPackerImage"
managed_image_resource_group_name = "myResourceGroup"
os_type = "Linux"
subscription_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx"
tenant_id = "72f988bf-86f1-41af-91ab-2d7cd011db47"
vm_size = "Standard_DS2_v2"
}
build {
sources = ["source.azure-arm.autogenerated_1"]
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"]
inline_shebang = "/bin/sh -x"
}
}
Este modelo cria uma imagem do Ubuntu 22.04 LTS, instala o NGINX e, em seguida, desaprovisiona a VM.
Nota
Se expandir este modelo para aprovisionar credenciais de utilizador, ajuste o comando do aprovisionador que desaprovisiona o agente do Azure para ler -deprovision
em vez de deprovision+user
.
O +user
sinalizador remove todas as contas de utilizador da VM de origem.
Imagem do Packer de compilação
Se ainda não tiver o Packer instalado no seu computador local, siga as instruções de instalação do Packer.
Crie a imagem ao especificar o ficheiro de modelo do Packer da seguinte forma:
sudo ./packer build ubuntu.json
Também pode criar a imagem ao especificar o ficheiro ubuntu.pkr.hcl da seguinte forma:
sudo packer build ubuntu.pkr.hcl
Um exemplo do resultado dos comandos anteriores é o seguinte:
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
O Packer demora alguns minutos a criar a VM, a executar os aprovisionadores e a limpar a implementação.
Criar VM a partir da Imagem do Azure
Agora pode criar uma VM a partir da sua Imagem com az vm create. Especifique a Imagem que criou com o --image
parâmetro . O exemplo seguinte cria uma VM com o nome myVM a partir de myPackerImage e gera chaves SSH se ainda não existirem:
az vm create \
--resource-group myResourceGroup \
--name myVM \
--image myPackerImage \
--admin-username azureuser \
--generate-ssh-keys
Se quiser criar VMs num grupo de recursos ou região diferente da imagem do Packer, especifique o ID da imagem em vez do nome da imagem. Pode obter o ID da imagem com az image show.
A criação da VM demora alguns minutos. Assim que a VM tiver sido criada, tome nota da publicIpAddress
apresentada pela CLI do Azure. Este endereço é utilizado para aceder ao site NGINX através de um browser.
Para permitir que o tráfego da Web aceda à VM, abra a porta 80 a partir da Internet com az vm open-port:
az vm open-port \
--resource-group myResourceGroup \
--name myVM \
--port 80
Testar VM e NGINX
Agora, pode abrir um browser e introduzir http://publicIpAddress
na barra de endereço. Forneça o seu próprio endereço IP público a partir do processo de criação da VM. A página NGINX predefinida é apresentada como no exemplo seguinte:
Passos seguintes
Também pode utilizar scripts do aprovisionador Packer existentes com o Azure Image Builder.