Comment utiliser Packer pour créer des images de machines virtuelles Windows dans AzureHow to use Packer to create Windows virtual machine images in Azure

Chaque machine virtuelle dans Azure est créée à partir d’une image qui définit la distribution Windows et la version du système d’exploitation.Each virtual machine (VM) in Azure is created from an image that defines the Windows distribution and OS version. Les images peuvent inclure des configurations et des applications pré-installées.Images can include pre-installed applications and configurations. La Place de marché Microsoft Azure fournit de nombreuses images internes et de tiers pour les systèmes d’exploitation et environnements d’application les plus courants. Vous pouvez également créer vos propres images personnalisées selon vos besoins.The Azure Marketplace provides many first and third-party images for most common OS' and application environments, or you can create your own custom images tailored to your needs. Cet article explique comment utiliser l’outil open source Packer pour définir et générer des images personnalisées dans Azure.This article details how to use the open-source tool Packer to define and build custom images in Azure.

Cet article a été testé pour la dernière fois le 21/02/2019 à l’aide du module Az PowerShell version 1.3.0 et de Packer version 1.3.4.This article was last tested on 2/21/2019 using the Az PowerShell module version 1.3.0 and Packer version 1.3.4.

Notes

Azure propose désormais un service, le générateur d’images Azure (préversion), pour définir et créer vos propres images personnalisées.Azure now has a service, Azure Image Builder (preview), for defining and creating your own custom images. Le générateur d’images Azure repose sur Packer. Vous pouvez donc même utiliser vos scripts d’approvisionnement de shell Packer existants.Azure Image Builder is built on Packer, so you can even use your existing Packer shell provisioner scripts with it. Pour vous familiariser avec le générateur d’images Azure, voir Créer une machine virtuelle Windows avec le générateur d’images Azure.To get started with Azure Image Builder, see Create a Windows VM with Azure Image Builder.

Créer un groupe de ressources AzureCreate Azure resource group

Pendant le processus de génération, Packer crée des ressources Azure temporaires lorsqu’il génère la machine virtuelle source.During the build process, Packer creates temporary Azure resources as it builds the source VM. Pour capturer cette machine virtuelle source afin de l’utiliser en tant qu’image, vous devez définir un groupe de ressources.To capture that source VM for use as an image, you must define a resource group. La sortie du processus de génération Packer est stockée dans ce groupe de ressources.The output from the Packer build process is stored in this resource group.

Créez un groupe de ressources avec New-AzResourceGroup.Create a resource group with New-AzResourceGroup. L’exemple suivant crée un groupe de ressources nommé myResourceGroup à l’emplacement eastus :The following example creates a resource group named myResourceGroup in the eastus location:

$rgName = "myResourceGroup"
$location = "East US"
New-AzResourceGroup -Name $rgName -Location $location

Créer des informations d’identification AzureCreate Azure credentials

Packer s’authentifie auprès d’Azure à l’aide d’un principal de service.Packer authenticates with Azure using a service principal. Un principal de service Azure est une identité de sécurité que vous pouvez utiliser avec des applications, des services et des outils d’automatisation comme Packer.An Azure service principal is a security identity that you can use with apps, services, and automation tools like Packer. Vous contrôlez et vous définissez les opérations que le principal du service est autorisé à effectuer dans Azure.You control and define the permissions as to what operations the service principal can perform in Azure.

Créez un principal de service avec la commande New-AzADServicePrincipal et assignez au principal de service les autorisations requises pour créer et gérer des ressources avec la commande New-AzRoleAssignment.Create a service principal with New-AzADServicePrincipal and assign permissions for the service principal to create and manage resources with New-AzRoleAssignment. La valeur de -DisplayName doit être unique ; remplacez-la par votre propre valeur, si nécessaire.The value for -DisplayName needs to be unique; replace with your own value as needed.

$sp = New-AzADServicePrincipal -DisplayName "PackerServicePrincipal"
$BSTR = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($sp.Secret)
$plainPassword = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($BSTR)
New-AzRoleAssignment -RoleDefinitionName Contributor -ServicePrincipalName $sp.ApplicationId

Générez ensuite le mot de passe et l’ID d’application.Then output the password and application ID.

$plainPassword
$sp.ApplicationId

Pour vous authentifier auprès d’Azure, vous devez également obtenir vos ID client et d’abonnement Azure à l’aide de la commande Get-AzSubscription :To authenticate to Azure, you also need to obtain your Azure tenant and subscription IDs with Get-AzSubscription:

Get-AzSubscription

Définition du modèle PackerDefine Packer template

Pour générer les images, vous devez créer un modèle en tant que fichier JSON.To build images, you create a template as a JSON file. Dans le modèle, vous définissez des générateurs et des fournisseurs pour mener à bien le processus de génération réel.In the template, you define builders and provisioners that carry out the actual build process. Packer intègre un générateur pour Azure qui vous permet de définir des ressources Azure, telles que les informations d’identification du principal de service créées à l’étape précédente.Packer has a builder for Azure that allows you to define Azure resources, such as the service principal credentials created in the preceding step.

Créez un fichier nommé windows.json et collez le contenu suivant :Create a file named windows.json and paste the following content. Saisissez vos propres valeurs comme suit :Enter your own values for the following:

ParamètreParameter EmplacementWhere to obtain
client_idclient_id Affichage de l’ID du principal de service avec $sp.applicationIdView service principal ID with $sp.applicationId
client_secretclient_secret Affichage du mot de passe généré automatiquement avec $plainPasswordView the auto-generated password with $plainPassword
tenant_idtenant_id Sortie de la commande $sub.TenantIdOutput from $sub.TenantId command
subscription_idsubscription_id Sortie de la commande $sub.SubscriptionIdOutput from $sub.SubscriptionId command
managed_image_resource_group_namemanaged_image_resource_group_name Nom du groupe de ressources créé lors de la première étapeName of resource group you created in the first step
managed_image_namemanaged_image_name Nom de l’image de disque géré crééeName for the managed disk image that is created
{
  "builders": [{
    "type": "azure-arm",

    "client_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx",
    "client_secret": "ppppppp-pppp-pppp-pppp-ppppppppppp",
    "tenant_id": "zzzzzzz-zzzz-zzzz-zzzz-zzzzzzzzzzzz",
    "subscription_id": "yyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyy",

    "managed_image_resource_group_name": "myResourceGroup",
    "managed_image_name": "myPackerImage",

    "os_type": "Windows",
    "image_publisher": "MicrosoftWindowsServer",
    "image_offer": "WindowsServer",
    "image_sku": "2016-Datacenter",

    "communicator": "winrm",
    "winrm_use_ssl": true,
    "winrm_insecure": true,
    "winrm_timeout": "5m",
    "winrm_username": "packer",

    "azure_tags": {
        "dept": "Engineering",
        "task": "Image deployment"
    },

    "location": "East US",
    "vm_size": "Standard_DS2_v2"
  }],
  "provisioners": [{
    "type": "powershell",
    "inline": [
      "Add-WindowsFeature Web-Server",
      "& $env:SystemRoot\\System32\\Sysprep\\Sysprep.exe /oobe /generalize /quiet /quit",
      "while($true) { $imageState = Get-ItemProperty HKLM:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Setup\\State | Select ImageState; if($imageState.ImageState -ne 'IMAGE_STATE_GENERALIZE_RESEAL_TO_OOBE') { Write-Output $imageState.ImageState; Start-Sleep -s 10  } else { break } }"
    ]
  }]
}

Ce modèle génère une machine virtuelle Windows Server 2016, installe IIS, puis généralise la machine virtuelle avec Sysprep.This template builds a Windows Server 2016 VM, installs IIS, then generalizes the VM with Sysprep. L’installation d’IIS montre comment utiliser le fournisseur PowerShell pour exécuter des commandes supplémentaires.The IIS install shows how you can use the PowerShell provisioner to run additional commands. L’image finale de Packer inclut l’installation et la configuration du logiciel requis.The final Packer image then includes the required software install and configuration.

Génération de l’image PackerBuild Packer image

Si Packer n’est pas encore installé sur votre ordinateur local, suivez les instructions d’installation de Packer.If you don't already have Packer installed on your local machine, follow the Packer installation instructions.

Générez l’image en ouvrant une invite de commandes et en spécifiant votre fichier de modèle Packer de la manière suivante :Build the image by opening a cmd prompt and specifying your Packer template file as follows:

./packer build windows.json

Voici un exemple de la sortie des commandes précédentes :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-pq0mthtbtt’
==> azure-arm:  -> Location          : ‘East US’
==> azure-arm:  -> Tags              :
==> azure-arm:  ->> task : Image deployment
==> azure-arm:  ->> dept : Engineering
==> azure-arm: Validating deployment template ...
==> azure-arm:  -> ResourceGroupName : ‘packer-Resource-Group-pq0mthtbtt’
==> azure-arm:  -> DeploymentName    : ‘pkrdppq0mthtbtt’
==> azure-arm: Deploying deployment template ...
==> azure-arm:  -> ResourceGroupName : ‘packer-Resource-Group-pq0mthtbtt’
==> azure-arm:  -> DeploymentName    : ‘pkrdppq0mthtbtt’
==> azure-arm: Getting the certificate’s URL ...
==> azure-arm:  -> Key Vault Name        : ‘pkrkvpq0mthtbtt’
==> azure-arm:  -> Key Vault Secret Name : ‘packerKeyVaultSecret’
==> azure-arm:  -> Certificate URL       : ‘https://pkrkvpq0mthtbtt.vault.azure.net/secrets/packerKeyVaultSecret/8c7bd823e4fa44e1abb747636128adbb'
==> azure-arm: Setting the certificate’s URL ...
==> azure-arm: Validating deployment template ...
==> azure-arm:  -> ResourceGroupName : ‘packer-Resource-Group-pq0mthtbtt’
==> azure-arm:  -> DeploymentName    : ‘pkrdppq0mthtbtt’
==> azure-arm: Deploying deployment template ...
==> azure-arm:  -> ResourceGroupName : ‘packer-Resource-Group-pq0mthtbtt’
==> azure-arm:  -> DeploymentName    : ‘pkrdppq0mthtbtt’
==> azure-arm: Getting the VM’s IP address ...
==> azure-arm:  -> ResourceGroupName   : ‘packer-Resource-Group-pq0mthtbtt’
==> azure-arm:  -> PublicIPAddressName : ‘packerPublicIP’
==> azure-arm:  -> NicName             : ‘packerNic’
==> azure-arm:  -> Network Connection  : ‘PublicEndpoint’
==> azure-arm:  -> IP Address          : ‘40.76.55.35’
==> azure-arm: Waiting for WinRM to become available...
==> azure-arm: Connected to WinRM!
==> azure-arm: Provisioning with Powershell...
==> azure-arm: Provisioning with shell script: /var/folders/h1/ymh5bdx15wgdn5hvgj1wc0zh0000gn/T/packer-powershell-provisioner902510110
    azure-arm: #< CLIXML
    azure-arm:
    azure-arm: Success Restart Needed Exit Code      Feature Result
    azure-arm: ------- -------------- ---------      --------------
    azure-arm: True    No             Success        {Common HTTP Features, Default Document, D...
    azure-arm: <Objs Version=“1.1.0.1” xmlns=“http://schemas.microsoft.com/powershell/2004/04"><Obj S=“progress” RefId=“0"><TN RefId=“0”><T>System.Management.Automation.PSCustomObject</T><T>System.Object</T></TN><MS><I64 N=“SourceId”>1</I64><PR N=“Record”><AV>Preparing modules for first use.</AV><AI>0</AI><Nil /><PI>-1</PI><PC>-1</PC><T>Completed</T><SR>-1</SR><SD> </SD></PR></MS></Obj></Objs>
==> azure-arm: Querying the machine’s properties ...
==> azure-arm:  -> ResourceGroupName : ‘packer-Resource-Group-pq0mthtbtt’
==> azure-arm:  -> ComputeName       : ‘pkrvmpq0mthtbtt’
==> azure-arm:  -> Managed OS Disk   : ‘/subscriptions/guid/resourceGroups/packer-Resource-Group-pq0mthtbtt/providers/Microsoft.Compute/disks/osdisk’
==> azure-arm: Powering off machine ...
==> azure-arm:  -> ResourceGroupName : ‘packer-Resource-Group-pq0mthtbtt’
==> azure-arm:  -> ComputeName       : ‘pkrvmpq0mthtbtt’
==> azure-arm: Capturing image ...
==> azure-arm:  -> Compute ResourceGroupName : ‘packer-Resource-Group-pq0mthtbtt’
==> azure-arm:  -> Compute Name              : ‘pkrvmpq0mthtbtt’
==> 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-pq0mthtbtt’
==> 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

La génération de la machine virtuelle, l’exécution des fournisseurs et le nettoyage du déploiement par Packer ne prennent que quelques minutes.It takes a few minutes for Packer to build the VM, run the provisioners, and clean up the deployment.

Créer une machine virtuelle à partir de l’image de PackerCreate a VM from the Packer image

Vous pouvez à présent créer une machine virtuelle à partir de votre image à l’aide de la commande New-AzVM.You can now create a VM from your Image with New-AzVM. Si elles n’existent pas déjà, les ressources réseau requises sont créées.The supporting network resources are created if they do not already exist. À l’invite, entrez un nom d’utilisateur d’administration et un mot de passe à créer sur la machine virtuelle.When prompted, enter an administrative username and password to be created on the VM. L’exemple suivant permet de créer une machine virtuelle nommée myVM à partir de myPackerImage :The following example creates a VM named myVM from myPackerImage:

New-AzVm `
    -ResourceGroupName $rgName `
    -Name "myVM" `
    -Location $location `
    -VirtualNetworkName "myVnet" `
    -SubnetName "mySubnet" `
    -SecurityGroupName "myNetworkSecurityGroup" `
    -PublicIpAddressName "myPublicIpAddress" `
    -OpenPorts 80 `
    -Image "myPackerImage"

Si vous souhaitez créer des machines virtuelles dans un autre groupe de ressources ou dans une autre région que votre image Packer, spécifiez l’ID de l’image plutôt que son nom.If you wish to create VMs in a different resource group or region than your Packer image, specify the image ID rather than image name. Pour obtenir l’ID d’image, exécutez la commande Get-AzImage.You can obtain the image ID with Get-AzImage.

La création de la machine virtuelle à partir de votre image Packer ne nécessite que quelques minutes.It takes a few minutes to create the VM from your Packer image.

Tester la machine virtuelle et le serveur webTest VM and webserver

Obtenez l’adresse IP publique de votre machine virtuelle avec Get-AzPublicIPAddress.Obtain the public IP address of your VM with Get-AzPublicIPAddress. L’exemple suivant obtient l’adresse IP pour myPublicIP créée précédemment :The following example obtains the IP address for myPublicIP created earlier:

Get-AzPublicIPAddress `
    -ResourceGroupName $rgName `
    -Name "myPublicIPAddress" | select "IpAddress"

Pour voir votre machine virtuelle, qui inclut l’installation d’IIS à partir du fournisseur Packer, entrez l’adresse IP publique dans un navigateur web.To see your VM, that includes the IIS install from the Packer provisioner, in action, enter the public IP address in to a web browser.

Site IIS par défaut

Étapes suivantesNext steps

Vous pouvez également utiliser les scripts d’approvisionnement Packer existants avec le générateur d’images Azure.You can also use existing Packer provisioner scripts with Azure Image Builder.